diff --git a/.cppcheck.rule b/.cppcheck.rule deleted file mode 100644 index d8f67a83a..000000000 --- a/.cppcheck.rule +++ /dev/null @@ -1,18 +0,0 @@ - - - wcwidth \( - - wcwidthForbidden - warning - Always use fish_wcwidth rather than wcwidth. - - - - - wcswidth \( - - wcswidthForbidden - warning - Always use fish_wcswidth rather than wcswidth. - - diff --git a/.cppcheck.rules b/.cppcheck.rules new file mode 100644 index 000000000..8c0d28c62 --- /dev/null +++ b/.cppcheck.rules @@ -0,0 +1,35 @@ + + + + wcwidth \( + + wcwidthForbidden + warning + Always use fish_wcwidth rather than wcwidth. + + + + + wcswidth \( + + wcswidthForbidden + warning + Always use fish_wcswidth rather than wcswidth. + + +<--!> +]]> + + + flock \( + + flockSemanticsWarning + warning + flock has a fallback implemented in terms of fcntl; ensure that the fcntl semantics will apply (see http://0pointer.de/blog/projects/locking.html) + + diff --git a/.cppcheck.suppressions b/.cppcheck.suppressions new file mode 100644 index 000000000..abe53fc0f --- /dev/null +++ b/.cppcheck.suppressions @@ -0,0 +1,14 @@ +// suppress all instances of varFuncNullUB: "Passing NULL after the last typed +// argument to a variadic function leads to undefined behaviour." That's +// because all the places we do this are valid and won't cause problems even +// on a ILP64 platform because we're careful about using NULL rather than 0. +varFuncNullUB +// Suppress the warning about unmatched suppressions. At the moment these +// warnings are emitted even when removing the suppression comment results in +// the warning being suppressed. In other words this unmatchedSuppression +// warnings are false positives. +unmatchedSuppression + +memleak:src/env_universal_common.cpp +flockSemanticsWarning:src/env_universal_common.cpp +flockSemanticsWarning:src/history.cpp diff --git a/.gitattributes b/.gitattributes index 90c1bb112..c7c7e113a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -34,8 +34,8 @@ fish.spec.in export-ignore /.github/* export-ignore # for linguist; let github identify our project as C++ instead of C due to pcre2 -/pcre2-10.21/ linguist-vendored -/pcre2-10.21/* linguist-vendored +/pcre2-10.22/ linguist-vendored +/pcre2-10.22/* linguist-vendored angular.js linguist-vendored /doc_src/* linguist-documentation *.fish linguist-language=fish diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index f0aba404e..250c53bad 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,12 +1,12 @@ -- [ ] Have you checked if problem occurs with [fish 2.3.1](/fish-shell/fish-shell/releases/tag/2.3.1)? +- [ ] Have you checked if problem occurs with [fish 2.4.0](/fish-shell/fish-shell/releases/tag/2.4.0)? - [ ] Tried fish without third-party customizations *(check `sh -c 'env HOME=$(mktemp -d) fish'`)*? **fish version installed** *(`fish --version`)*: -**OS/terminal used**: +**OS/terminal used**: -Talk about the the issue here. +Talk about the the issue here. ## Reproduction steps 1. step one diff --git a/.gitignore b/.gitignore index 385c95d3d..8c6a1ef55 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,7 @@ Desktop.ini # These file names can appear anywhere in the hierarchy. They tend to be OS # or build system artifacts. autom4te.cache +aclocal.m4 Makefile config.h config.cache @@ -87,7 +88,7 @@ messages.pot /tests/*.tmp.* /share/pkgconfig -# xcode +# xcode ## Build generated build/ DerivedData/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e56b963c..4abae7af2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,103 @@ -# next-2.x +# fish 2.5b1 (released ???) + +## Platform Changes + +Starting with version 2.5, fish requires a more up-to-date version of C++, specifically C++11 (from 2011). This affects some older platforms: + +### Linux + +For users building from source, GCC's g++ 4.8 or later, or LLVM's clang 3.3 or later, are known to work. Older platforms may require a newer compiler installed. + +Unfortunately, because of the complexity of the toolchain, binary packages are no longer published by the fish-shell developers for the following platforms: + + - Red Hat Enterprise Linux and CentOS 5 & 6 for 64-bit builds + - Ubuntu 12.04 (EoLTS April 2017) + - Debian 7 (EoLTS May 2018) + +Installing newer version of fish on these systems will require building from source. + +### OS X SnowLeopard + +Starting with version 2.5, fish requires a C++11 standard library on OS X 10.6 ("SnowLeopard"). If this library is not installed, you will see this error: `dyld: Library not loaded: /usr/lib/libc++.1.dylib` + +MacPorts is the easiest way to obtain this library. After installing the SnowLeopard MacPorts release from the install page, run: + +``` +sudo port -v install libcxx +``` + +Now fish should launch successfully. (Please open an issue if it does not.) + +This is only necessary on 10.6. OS X 10.7 and later include the required library by default. + +## Other significant changes + +- Attempting to exit with running processes in the background produces a warning, then signals them to terminate if a second attempt to exit is made. This brings the behaviour for running background processes into line with stopped processes. (#3497) +- `random` can now have start, stop and step values specified, or the new `choice` subcommand can be used to pick an argument from a list (#3619). +- A new key bindings preset, `fish_hybrid_key_bindings`, including all the Emacs-style and Vi-style bindings, which behaves like `fish_vi_key_bindings` in fish 2.3.0 (#3556). +- `function` now returns an error when called with invalid options, rather than defining the function anyway (#3574). This was a regression present in fish 2.3 and 2.4.0. +- fish no longer prints a warning when it identifies a running instance of an old version (2.1.0 and earlier). Changes to universal variables may not propagate between these old versions and 2.5b1. +- Improved compatiblity with Android (#3585), MSYS/mingw (#2360), Solaris (#3456, #3340) +- Like other shells, the `test` builting now returns an error for numeric operations on invalid integers (#3346, #3581). +- `complete` no longer recognises `--authoritative` and `--unauthoritative` options, and they are marked as obsolete. +- `status` accepts subcommands, and should be used like `status is-interactive`. The old options continue to be supported for the foreseeable future (#3526), although only one subcommand or option can be specified at a time. +- Selection mode (used with "begin-selection") no longer selects a character the cursor does not move over (#3684). +- List indexes are handled better, and a bit more liberally in some cases (`echo $PATH[1 .. 3]` is now valid) (#3579). +- The `fish_mode_prompt` function is now simply a stub around `fish_default_mode_prompt`, which allows the mode prompt to be included more easily in customised prompt functions (#3641). + +## Notable fixes and improvements +- `alias`, run without options or arguments, lists all defined aliases, and aliases now include a description in the function signature that identifies them. +- `complete` accepts empty strings as descriptions (#3557). +- `command` accepts `-q`/`--quiet` in combination with `--search` (#3591), providing a simple way of checking whether a command exists in scripts. +- Abbreviations can now be renamed with `abbr --rename OLD_KEY NEW_KEY` (#3610). +- The command synopses printed by `--help` options work better with copying and pasting (#2673). +- `help` launches the browser specified by the `$fish_help_browser variable` if it is set (#3131). +- History merging could lose items under certain circumstances and is now fixed (#3496). +- The `$status` variable is now set to 123 when a syntactically invalid command is entered (#3616). +- Exiting fish now signals all background processes to terminate, not just stopped jobs (#3497). +- A new `prompt_hostname` function which prints a hostname suitable for use in prompts (#3482). +- The `__fish_man_page` function (bound to Alt-h by default) now tries to recognize subcommands (e.g. `git add` will now open the "git-add" man page) (#3678). +- A new function `edit_command_buffer` (bound to Alt-e & Alt-v by default) to edit the command buffer in an external editor (#1215, #3627). +- `set_color` now supports italics (`--italics`), dim (`--dim`) and reverse (`--reverse`) modes (#3650). +- Filesystems with very slow locking (eg incorrectly-configured NFS) will no longer slow fish down (#685). +- Improved completions for `apt` (#3695), `fusermount` (#3642), `make` (#3628), `netctl-auto` (#3378), `nmcli` (#3648), `pygmentize` (#3378), and `tar` (#3719). +- Added completions for: + - `VBoxHeadless` (#3378) + - `VBoxSDL` (#3378) + - `base64` (#3378) + - `caffeinate` (#3524) + - `dconf` (#3638) + - `dig` (#3495) + - `dpkg-reconfigure` (#3521 & #3522) + - `feh` (#3378) + - `launchctl` (#3682) + - `lxc` (#3554 & #3564), + - `mddiagnose` (#3524) + - `mdfind` (#3524) + - `mdimport` (#3524) + - `mdls` (#3524) + - `mdutil` (#3524) + - `mkvextract` (#3492) + - `nvram` (#3524) + - `objdump` (#3378) + - `sysbench` (#3491) + - `tmutil` (#3524) + +--- + +# fish 2.4.0 (released November 8, 2016) + +There are no major changes between 2.4b1 and 2.4.0. + +## Notable fixes and improvements +- The documentation is now generated properly and with the correct version identifier. +- Automatic cursor changes are now only enabled on the subset of XTerm versions known to support them, resolving a problem where older versions printed garbage to the terminal before and after every prompt (#3499). +- Improved the title set in Apple Terminal.app. +- Added completions for `defaults` and improved completions for `diskutil` (#3478). + +--- + +# fish 2.4b1 (released October 18, 2016) ## Significant changes - The clipboard integration has been revamped with explicit bindings. The killring commands no longer copy from, or paste to, the X11 clipboard - use the new copy (`C-x`) and paste (`C-v`) bindings instead. The clipboard is now available on OS X as well as systems using X11 (e.g. Linux). (#3061) @@ -37,7 +136,7 @@ - `p4`, the Perforce client (#3314) - `pygmentize` (#3378) - `ranger` (#3378) -- Improved completions for `aura` (#3297), `abbr` (#3267), `brew` (#3309), `chown` (#3380, #3383),`cygport` (#3392), `git` (#3274, #3226, #3225, #3094, #3087, #3035, #3021, #2982, #3230), `kill & `pkill` (#3200) `screen` (#3271), and `xz` (#3378). +- Improved completions for `aura` (#3297), `abbr` (#3267), `brew` (#3309), `chown` (#3380, #3383),`cygport` (#3392), `git` (#3274, #3226, #3225, #3094, #3087, #3035, #3021, #2982, #3230), `kill` & `pkill` (#3200), `screen` (#3271), `wget` (#3470), and `xz` (#3378). - Distributors, packagers and developers will notice that the build process produces more succinct output by default; use `make V=1` to get verbose output (#3248). - Improved compatibility with minor platforms including musl (#2988), Cygwin (#2993), Android (#3441, #3442), Haiku (#3322) and Solaris . @@ -407,7 +506,7 @@ Bug Fixes * **fish_indent is fixed.** In particular, the `funced` and `funcsave` functions work again. * A SIGTERM now ends the whole execution stack again (resolving #13). * Bumped the __fish_config_interactive version number so the default fish_color_autosuggestion kicks in. -* fish_config better handles combined term256 and classic colors like "555 yellow". +* fish_config better handles combined term256 and classic colors like "555 yellow". New Features ------------ @@ -465,4 +564,4 @@ The large number of forks relative to bash are due to fish's insanely expensive The large reduction in lstat() numbers is due to fish no longer needing to call ttyname() on OS X. -We've got some work to do to be as lean as bash, but we're on the right track. +We've got some work to do to be as lean as bash, but we're on the right track. diff --git a/COPYING b/COPYING index cc3da7efd..a8a80460d 100644 --- a/COPYING +++ b/COPYING @@ -9,7 +9,7 @@ you can redistribute it and/or modify it under the terms of the GNU GPL as published by the Free Software Foundation. fish also includes software licensed under the GNU Lesser General Public -License version 2, the OpenBSD license and the ISC license. +License version 2, the OpenBSD license, the ISC license, and the NetBSD license. Full licensing information is contained in doc_src/license.hdr. diff --git a/Doxyfile b/Doxyfile index 21bd8db69..056ccc0a4 100644 --- a/Doxyfile +++ b/Doxyfile @@ -837,7 +837,7 @@ RECURSIVE = NO # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = +EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded diff --git a/Makefile.in b/Makefile.in index 747be9d9e..8bb1b997e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -70,7 +70,7 @@ extra_confdir = @extra_confdir@ # pcre2 # PCRE2_WIDTH = @WCHAR_T_BITS@ -PCRE2_DIR = pcre2-10.21 +PCRE2_DIR = pcre2-10.22 PCRE2_LIBDIR = $(PCRE2_DIR)/.libs PCRE2_LIB = $(PCRE2_LIBDIR)/libpcre2-$(PCRE2_WIDTH).a PCRE2_H = $(PCRE2_DIR)/src/pcre2.h @@ -181,6 +181,17 @@ PROGRAMS := fish fish_indent fish_key_reader # Manual pages to install # MANUALS := $(addsuffix .1, $(addprefix share/man/man1/, $(PROGRAMS))) +HELP_MANPAGES := $(wildcard share/man/man1/*.1) + +# Determine which man pages we don't want to install +# On OS X, don't install a man page for open, since we defeat fish's open +# function on OS X. +# This is also done in build_tools/build_documentation.sh, but because the +# tarball includes this page, we need to skip it in the Makefile too (see +# https://github.com/fish-shell/fish-shell/issues/2561). +ifeq ($(shell uname), Darwin) + HELP_MANPAGES := $(filter-out share/man/man1/open.1, $(HELP_MANPAGES)) +endif # # All translation message catalogs @@ -238,7 +249,7 @@ show-%: # all: show-CXX show-CXXFLAGS $(PROGRAMS) $(user_doc) $(share_man) $(TRANSLATIONS) fish.pc share/__fish_build_paths.fish ifneq (,$(findstring install,$(MAKECMDGOALS))) -# Fish has been built, but if the goal was 'install', we aren't done yet and this output isnt't desirable +# Fish has been built, but if the goal was 'install', we aren't done yet and this output isnt't desirable @echo "$(green)fish has now been built.$(sgr0)" @echo "Run $(yellow)$(notdir $(MAKE)) install$(sgr0) to install fish.$(sgr0)" endif @@ -286,7 +297,7 @@ prof: all # directory once Doxygen is done. # doc: $(HDR_FILES_SRC) Doxyfile.user $(HTML_SRC) $(HELP_SRC) doc.h $(HDR_FILES) lexicon_filter - @echo " SED doxygen $(em)user_doc$(sgr0)" + @echo " doxygen $(em)user_doc$(sgr0)" $v (cat Doxyfile.user; echo INPUT_FILTER=./lexicon_filter; echo PROJECT_NUMBER=$(FISH_BUILD_VERSION) | $(SED) "s/-.*//") | doxygen - && touch user_doc $v rm -f $(wildcard $(addprefix ./user_doc/html/,arrow*.png bc_s.png bdwn.png closed.png doc.png folder*.png ftv2*.png nav*.png open.png splitbar.png sync_*.png tab*.* doxygen.* dynsections.js jquery.js pages.html)) @@ -367,7 +378,7 @@ test_interactive: $(call filter_up_to,test_interactive,$(active_test_goals)) # builtins # doc_src/commands.hdr:$(HELP_SRC) doc_src/commands.hdr.in | - @echo " CAT AWK $(em)$@$(sgr0)" + @echo " CAT AWK $(em)$@$(sgr0)" $v rm -f command_list.tmp command_list_toc.tmp $@ $v for i in $(sort $(HELP_SRC)); do \ echo "
" >>command_list.tmp; \ @@ -383,7 +394,7 @@ doc_src/commands.hdr:$(HELP_SRC) doc_src/commands.hdr.in | $v cat $@.in | $(AWK) '{if ($$0 ~ /@command_list_toc@/) { system("cat command_list_toc.txt"); } else if ($$0 ~ /@command_list@/){ system("cat command_list.txt");} else{ print $$0;}}' >$@ toc.txt: $(HDR_FILES:index.hdr=index.hdr.in) | show-SED - @echo " SED $(em)$@$(sgr0)" + @echo " SED $(em)$@$(sgr0)" $v rm -f toc.tmp $@ # Ugly hack to set the toc initial title for the main page $v echo '- fish shell documentation - $(FISH_BUILD_VERSION)' > toc.tmp @@ -400,7 +411,7 @@ toc.txt: $(HDR_FILES:index.hdr=index.hdr.in) | show-SED $v mv toc.tmp $@ doc_src/index.hdr: toc.txt doc_src/index.hdr.in | show-AWK - @echo " AWK CAT $(em)$@$(sgr0)" + @echo " AWK CAT $(em)$@$(sgr0)" $v cat $@.in | $(AWK) '{if ($$0 ~ /@toc@/){ system("cat toc.txt");} else{ print $$0;}}' >$@ # @@ -415,7 +426,7 @@ doc_src/index.hdr: toc.txt doc_src/index.hdr.in | show-AWK lexicon.txt: doc_src/commands.hdr $(FUNCTIONS_DIR_FILES) $(COMPLETIONS_DIR_FILES) share/functions/__fish_config_interactive.fish | show-SED show-FGREP $v rm -f lexicon.tmp lexicon_catalog.tmp lexicon_catalog.txt $@ # Scan sources for commands/functions/binaries/colours. If GNU sed was portable, this could be much smarter. - @echo " SEDFGREP $(em)$@$(sgr0)" + @echo " SEDFGREP $(em)$@$(sgr0)" $v $(SED) >lexicon.tmp -n \ -e "s|^.*>\([a-z][a-z_]*\)|'\1'|w lexicon_catalog.tmp" \ -e "s|'\(.*\)'|bltn \1|p"; mv lexicon_catalog.tmp lexicon_catalog.txt @@ -454,7 +465,7 @@ lexicon_filter: lexicon.txt lexicon_filter.in | show-SED else \ WORDBL='\\<'; WORDBR='\\>'; \ fi; $(SED) >$@.tmp -n -e "s|^\([a-z][a-z][a-z][a-z]\) \([a-z_-]*\)$$|s,$$WORDBL\2$$WORDBR,@\1{\2},g|p" -e '$$G;s/.*\n/b tidy/p'; - $v mv $@.tmp $@; test -x $@ || chmod a+x $@; + $v mv $@.tmp $@; test -x $@ || chmod a+x $@; # @@ -474,7 +485,7 @@ doc.h: $(HDR_FILES) # the internal help function text. # %.doxygen:%.txt - @echo " cat * $(em)$@$(sgr0)" + @echo " cat * $(em)$@$(sgr0)" $v echo "/** \page " `basename $*` >$@; $v cat $*.txt >>$@; $v echo "*/" >>$@ @@ -520,7 +531,7 @@ doc.h: $(HDR_FILES) # Create a template translation object # messages.pot: $(wildcard src/*.cpp src/*.h share/completions/*.fish share/functions/*.fish) - @echo " xgettext $(em)$@$(sgr0)" + @echo " xgettext $(em)$@$(sgr0)" xgettext -k_ -kN_ $(wildcard src/*.cpp src/*.h) -o messages.pot $v xgettext -j -k_ -kN_ -k--description -LShell --from-code=UTF-8 $(wildcard share/completions/*.fish share/functions/*.fish) share/fish.config -o messages.pot @@ -597,7 +608,7 @@ check-legacy-binaries: .PHONY: check-legacy-binaries install: all install-force | check-legacy-binaries - @echo + @echo @echo "$(bo)fish is now installed on your system.$(sgr0)" @echo "To run fish, type $(bo)$(green)fish$(sgr0) in your terminal." @echo "$(T_YELLOW)Even if you are already in fish, you should now start a new fish session.$(sgr0)" @@ -666,42 +677,19 @@ install-force: all install-translations | show-datadir show-sysconfdir show-extr @echo "Installing pkgconfig file" $v $(INSTALL) -m 644 fish.pc $(DESTDIR)$(datadir)/pkgconfig @echo "Installing the $(bo)fish completion library$(sgr0)..."; - $v for i in $(COMPLETIONS_DIR_FILES:%='%'); do \ - $(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/fish/completions/; \ - done; + $v $(INSTALL) -m 644 $(COMPLETIONS_DIR_FILES:%='%') $(DESTDIR)$(datadir)/fish/completions/ @echo "Installing $(bo)fish functions$(sgr0)"; - $v for i in $(FUNCTIONS_DIR_FILES:%='%'); do \ - $(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/fish/functions/; \ - done; + $v $(INSTALL) -m 644 $(FUNCTIONS_DIR_FILES:%='%') $(DESTDIR)$(datadir)/fish/functions/ @echo "Installing $(bo)man pages$(sgr0)"; $v $(INSTALL) -m 644 share/groff/* $(DESTDIR)$(datadir)/fish/groff/ - $v for i in $(wildcard share/man/man1/*.1); do \ - $(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/fish/man/man1/; \ - done; + $v test -z "$(HELP_MANPAGES)" || $(INSTALL) -m 644 $(HELP_MANPAGES) $(DESTDIR)$(datadir)/fish/man/man1/ @echo "Installing helper tools"; - $v for i in $(wildcard share/tools/*.py); do\ - $(INSTALL) -m 755 $$i $(DESTDIR)$(datadir)/fish/tools/; \ - done; - $v for i in share/tools/web_config/*.*; do\ - $(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/fish/tools/web_config/; \ - true; \ - done; - $v for i in share/tools/web_config/js/*.*; do\ - $(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/fish/tools/web_config/js/; \ - true; \ - done; - $v for i in share/tools/web_config/partials/*; do\ - $(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/fish/tools/web_config/partials/; \ - true; \ - done; - $v for i in share/tools/web_config/sample_prompts/*.fish; do\ - $(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/fish/tools/web_config/sample_prompts/; \ - true; \ - done; - $v for i in share/tools/web_config/*.py; do\ - $(INSTALL) -m 755 $$i $(DESTDIR)$(datadir)/fish/tools/web_config/; \ - true; \ - done; + $v $(INSTALL) -m 755 share/tools/*.py $(DESTDIR)$(datadir)/fish/tools/ + $v $(INSTALL) -m 644 share/tools/web_config/*.* $(DESTDIR)$(datadir)/fish/tools/web_config/ + $v $(INSTALL) -m 644 share/tools/web_config/js/*.* $(DESTDIR)$(datadir)/fish/tools/web_config/js/ + $v $(INSTALL) -m 644 share/tools/web_config/partials/* $(DESTDIR)$(datadir)/fish/tools/web_config/partials/ + $v $(INSTALL) -m 644 share/tools/web_config/sample_prompts/*.fish $(DESTDIR)$(datadir)/fish/tools/web_config/sample_prompts/ + $v $(INSTALL) -m 755 share/tools/web_config/*.py $(DESTDIR)$(datadir)/fish/tools/web_config/ @echo "Installing online user documentation"; $v $(INSTALL) -m 755 -d $(DESTDIR)$(docdir) $v for i in user_doc/html/* CHANGELOG.md; do \ @@ -733,7 +721,7 @@ uninstall: uninstall-translations | show-prefix show-bindir show-sysconfdir show @echo @echo "In 5 seconds, $(red)all data$(sgr0) (includes functions, completions, tools) in" @echo $$"\t$(bo)$(DESTDIR)$(datadir)/fish$(sgr0) will be deleted!" - @echo + @echo @echo $$"If you put things there, $(red)stop now!$(sgr0) $(bo)\\c" @echo $$"$(bo)5$(sgr0) \\c" @sleep 1 @@ -766,7 +754,7 @@ uninstall: uninstall-translations | show-prefix show-bindir show-sysconfdir show @echo "[ $(bo)"$(basename $(MANUALS))$(sgr0) $$"] in \\c" @echo "$(em)$(mandir)/man1$(sgr0)" -$v for i in $(MANUALS); do \ - rm -rf "$(DESTDIR)$(mandir)/man1/"$$$(basename $i)$$$(wildcard .*); + rm -rf "$(DESTDIR)$(mandir)/man1/"$$$(basename $i)$$$(wildcard .*); done; @echo @echo "$(green)Fish (likely) unintalled$(sgr0)" @@ -795,7 +783,7 @@ uninstall-translations: show-DESTDIR show-localedir # # How basic files get compiled # -obj/%.o: src/%.cpp | show-CXX show-CXXFLAGS show-CPPFLAGS obj +obj/%.o: src/%.cpp | show-CXX show-CXXFLAGS show-CPPFLAGS obj @echo " CXX $(em)$@$(sgr0)" $v $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@ @@ -818,7 +806,7 @@ $(PCRE2_LIB): $(PCRE2_H) $v $(MAKE) V=$(V) -C $(PCRE2_DIR) libpcre2-$(PCRE2_WIDTH).la $(PCRE2_H): - @echo " autoconf $(em)$@$(sgr0)" + @echo " autoconf $(em)$@$(sgr0)" $v (cd $(PCRE2_DIR) && ./config.status) # @@ -836,7 +824,7 @@ fish_indent: $(FISH_INDENT_OBJS) $(EXTRA_PCRE2) $v $(CXX) $(CXXFLAGS) $(LDFLAGS) $(FISH_INDENT_OBJS) $(LIBS) -o $@ # -# Build the fish_key_reader program to show input from the terminal. +# Build the fish_key_reader program to show input from the terminal. # fish_key_reader: $(FISH_KEYREAD_OBJS) $(EXTRA_PCRE2) @echo " CXX LD $(em)$@$(sgr0)" @@ -853,7 +841,7 @@ fish_key_reader: $(FISH_KEYREAD_OBJS) $(EXTRA_PCRE2) # exactly the files that result in objects, leaving the #include'd files # behind. # -depend: | show-MKDIR_P +depend: | show-MKDIR_P @echo " CXX LD $(em)$@$(sgr0)" $v $(MKDIR_P) /tmp/fish_make_depend/src # This is ran only once in a blue moon - full verbosity so we are reminded what it does. @@ -870,9 +858,9 @@ depend: | show-MKDIR_P # TODO - why not have the Makefile run lint.fish on actual files itself (generate a report target?) # lint: - $v build_tools/lint.fish $(CXX) $(CXXFLAGS) $(CPPFLAGS) + $v build_tools/lint.fish "$(CXX)" $(CXXFLAGS) $(CPPFLAGS) lint-all: - $v build_tools/lint.fish $(CXX) --all $(CXXFLAGS) $(CPPFLAGS) + $v build_tools/lint.fish "$(CXX)" --all $(CXXFLAGS) $(CPPFLAGS) .PHONY: lint lint-all # @@ -889,8 +877,9 @@ style-all: # Restore the source tree to the state right after extracting a tarball. # distclean: clean - $v $(MAKE) V=$(V) -C $(PCRE2_DIR) distclean ||: - $v rm -f config.status config.log config.h Makefile + $v test ! -f $(PCRE2_DIR)/Makefile || \ + $(MAKE) V=$(V) -C $(PCRE2_DIR) distclean ||: + $v rm -rf config.status config.log config.h Makefile autom4te.cache aclocal.m4 .PHONY: distclean # @@ -906,9 +895,12 @@ clean: # PCRE's make clean has a few slightly annoying exceptions to the V= rule. If V=0 # send all output to /dev/null - unless there's an error, in which case run it again not silenced. ifeq ($(V), 0 ) - $(MAKE) -C $(PCRE2_DIR) clean ||: + @test ! -f $(PCRE2_DIR)/Makefile || \ + $(MAKE) -C $(PCRE2_DIR) clean ||: else - @$(MAKE) -s -C $(PCRE2_DIR) clean > /dev/null || $(MAKE) -s -C $(PCRE2_DIR) clean ||: + @test ! -f $(PCRE2_DIR)/Makefile || \ + $(MAKE) -s -C $(PCRE2_DIR) clean > /dev/null || \ + $(MAKE) -s -C $(PCRE2_DIR) clean ||: endif $v rm -f obj/*.o *.o doc.h doc.tmp $v rm -f doc_src/*.doxygen doc_src/*.cpp doc_src/*.o doc_src/commands.hdr @@ -1020,14 +1012,13 @@ obj/expand.o: src/complete.h src/env.h src/exec.h src/expand.h obj/expand.o: src/parse_constants.h src/iothread.h src/parse_util.h obj/expand.o: src/tokenizer.h src/path.h src/proc.h src/io.h src/parse_tree.h obj/expand.o: src/util.h src/wildcard.h src/wutil.h -obj/fallback.o: config.h src/signal.h src/fallback.h src/util.h +obj/fallback.o: config.h src/signal.h src/common.h src/fallback.h src/util.h obj/fish.o: config.h src/builtin.h src/common.h src/fallback.h src/signal.h obj/fish.o: src/env.h src/event.h src/expand.h src/parse_constants.h obj/fish.o: src/fish_version.h src/function.h src/history.h src/wutil.h -obj/fish.o: src/input.h src/input_common.h src/io.h src/parser.h -obj/fish.o: src/parse_tree.h src/tokenizer.h src/proc.h src/path.h -obj/fish.o: src/reader.h src/complete.h src/highlight.h src/color.h -obj/fish.o: src/wildcard.h +obj/fish.o: src/input.h src/io.h src/parser.h src/parse_tree.h +obj/fish.o: src/tokenizer.h src/proc.h src/path.h src/reader.h src/complete.h +obj/fish.o: src/highlight.h src/color.h obj/fish_indent.o: config.h src/color.h src/common.h src/fallback.h obj/fish_indent.o: src/signal.h src/env.h src/fish_version.h src/highlight.h obj/fish_indent.o: src/input.h src/output.h src/parse_constants.h @@ -1136,8 +1127,8 @@ obj/sanity.o: src/wutil.h src/kill.h src/proc.h src/io.h src/parse_tree.h obj/sanity.o: src/parse_constants.h src/tokenizer.h src/reader.h obj/sanity.o: src/complete.h src/highlight.h src/color.h src/env.h obj/sanity.o: src/sanity.h -obj/screen.o: config.h src/common.h src/fallback.h src/signal.h src/env.h -obj/screen.o: src/highlight.h src/color.h src/output.h src/pager.h +obj/screen.o: config.h src/common.h src/fallback.h src/signal.h +obj/screen.o: src/highlight.h src/color.h src/env.h src/output.h src/pager.h obj/screen.o: src/complete.h src/reader.h src/parse_constants.h src/screen.h obj/screen.o: src/util.h obj/signal.o: config.h src/signal.h src/common.h src/fallback.h src/event.h @@ -1146,7 +1137,7 @@ obj/signal.o: src/tokenizer.h src/reader.h src/complete.h src/highlight.h obj/signal.o: src/color.h src/env.h src/wutil.h obj/tokenizer.o: config.h src/common.h src/fallback.h src/signal.h obj/tokenizer.o: src/tokenizer.h src/wutil.h -obj/utf8.o: config.h src/utf8.h +obj/utf8.o: config.h src/common.h src/fallback.h src/signal.h src/utf8.h obj/util.o: config.h src/common.h src/fallback.h src/signal.h src/util.h obj/util.o: src/wutil.h obj/wcstringutil.o: config.h src/common.h src/fallback.h src/signal.h diff --git a/README.md b/README.md index 23b362459..90a8cad65 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,9 @@ Detailed user documentation is available by running `help` within fish, and also ## Building -Fish can be built using a C++11 environment but only requires C++03. It builds successfully with g++ 4.2 or later, and with clang. This allows fish to run on older systems such as OS X Snow Leopard (released in 2009). +fish requires a C++11 compiler. It builds successfully with g++ 4.8 or later, or with clang 3.3 or later. -Fish can be built using autotools or Xcode. autoconf 2.60 or later is required to build from git versions, but is not required for releases. +fish can be built using autotools or Xcode. autoconf 2.60 or later, as well as automake 1.13 or later, are required to build from git versions. These are not required to build from released tarballs. fish depends on a curses implementation, such as ncurses. The headers and libraries are required for building. @@ -27,7 +27,7 @@ Building the documentation requires Doxygen 1.8.7 or newer. ### Autotools Build - autoconf [if building from Git] + autoreconf --no-recursive [if building from Git] ./configure make [gmake on BSD] sudo make install diff --git a/build_tools/build_documentation.sh b/build_tools/build_documentation.sh index fe366ae8f..ebd3ed6ba 100755 --- a/build_tools/build_documentation.sh +++ b/build_tools/build_documentation.sh @@ -21,6 +21,7 @@ fi # Determine which man pages we don't want to generate. # on OS X, don't make a man page for open, since we defeat fish's open function on OS X. +# This is also done in the Makefile, but the Xcode build doesn't use that CONDEMNED_PAGES= if test `uname` = 'Darwin'; then CONDEMNED_PAGES="$CONDEMNED_PAGES open.1" diff --git a/build_tools/lint.fish b/build_tools/lint.fish index 7fb72e790..ae6e5c1f6 100755 --- a/build_tools/lint.fish +++ b/build_tools/lint.fish @@ -35,10 +35,14 @@ for arg in $argv set cppcheck_args $cppcheck_args $arg else if string match -q -- '-I*' $arg set cppcheck_args $cppcheck_args $arg - else if string match -q -- '-iquote*' $arg - set cppcheck_args $cppcheck_args $arg end end + +# Not sure when this became necessary but without these flags cppcheck no longer works on macOS. +# It complains that "Cppcheck cannot find all the include files." It appears that cppcheck used +# to, but no longer, recognizes the -iquote flag. So switch to hardcoding the appropriate -I flags. +set cppcheck_args $cppcheck_args -I . -I ./src + if test "$machine_type" = "x86_64" set cppcheck_args -D__x86_64__ -D__LP64__ $cppcheck_args end @@ -49,7 +53,8 @@ else # We haven't been asked to lint all the source. If there are uncommitted # changes lint those, else lint the files in the most recent commit. # Select (cached files) (modified but not cached, and untracked files) - set files (git diff-index --cached HEAD --name-only) (git ls-files --exclude-standard --others --modified) + set files (git diff-index --cached HEAD --name-only) + set files $files (git ls-files --exclude-standard --others --modified) if not set -q files[1] # No pending changes so lint the files in the most recent commit. set files (git diff-tree --no-commit-id --name-only -r HEAD) @@ -75,9 +80,12 @@ if set -q c_files[1] for c_file in $c_files switch $kernel_name case Darwin - include-what-you-use -Xiwyu --no_default_mappings -Xiwyu --mapping_file=build_tools/iwyu.osx.imp $cppcheck_args --std=c++11 $c_file 2>&1 + include-what-you-use -Xiwyu --no_default_mappings -Xiwyu \ + --mapping_file=build_tools/iwyu.osx.imp --std=c++11 \ + $cppcheck_args $c_file 2>&1 case Linux - include-what-you-use -Xiwyu --mapping_file=build_tools/iwyu.linux.imp $cppcheck_args $c_file 2>&1 + include-what-you-use -Xiwyu --mapping_file=build_tools/iwyu.linux.imp \ + $cppcheck_args $c_file 2>&1 case '*' # hope for the best include-what-you-use $cppcheck_args $c_file 2>&1 end @@ -92,7 +100,25 @@ if set -q c_files[1] # The stderr to stdout redirection is because cppcheck, incorrectly IMHO, writes its # diagnostic messages to stderr. Anyone running this who wants to capture its output will # expect those messages to be written to stdout. - cppcheck -q --verbose --std=posix --language=c++ --template \[(set_color --bold)(set_color --underline)"{file}"(set_color normal)(set_color --bold)":{line}"(set_color normal)"] "(set_color brmagenta)"{severity}"(set_color magenta)" ({id}):"\n(set_color normal)" {message}" --suppress=missingIncludeSystem --inline-suppr --enable=$cppchecks --rule-file=.cppcheck.rule $cppcheck_args $c_files 2>&1 + set -l cn (set_color normal) + set -l cb (set_color --bold) + set -l cu (set_color --underline) + set -l cm (set_color magenta) + set -l cbrm (set_color brmagenta) + set -l template "[$cb$cu{file}$cn$cb:{line}$cn] $cbrm{severity}$cm ({id}):$cn\n {message}" + set cppcheck_args -q --verbose --std=c++11 --std=posix --language=c++ --template $template \ + --suppress=missingIncludeSystem --inline-suppr --enable=$cppchecks \ + --rule-file=.cppcheck.rules --suppressions-list=.cppcheck.suppressions $cppcheck_args + + cppcheck $cppcheck_args $c_files 2>&1 + + echo + echo ======================================== + echo 'Running `cppcheck --check-config` to identify missing includes similar problems.' + echo 'Ignore unmatchedSuppression warnings as they are probably false positives we' + echo 'cannot suppress.' + echo ======================================== + cppcheck $cppcheck_args --check-config $c_files 2>&1 end if type -q oclint @@ -109,14 +135,14 @@ if set -q c_files[1] oclint-xcodebuild xcodebuild.log >/dev/null end if test $all = yes - oclint-json-compilation-database -e '/pcre2-10.21/' -- -enable-global-analysis 2>&1 + oclint-json-compilation-database -e '/pcre2-10.22/' -- -enable-global-analysis 2>&1 else set i_files for f in $c_files set i_files $i_files -i $f end - echo oclint-json-compilation-database -e '/pcre2-10.21/' $i_files - oclint-json-compilation-database -e '/pcre2-10.21/' $i_files 2>&1 + echo oclint-json-compilation-database -e '/pcre2-10.22/' $i_files + oclint-json-compilation-database -e '/pcre2-10.22/' $i_files 2>&1 end else # Presumably we're on Linux or other platform not requiring special diff --git a/build_tools/make_darcs_completions.fish b/build_tools/make_darcs_completions.fish index ccf5f08a8..e7978df10 100755 --- a/build_tools/make_darcs_completions.fish +++ b/build_tools/make_darcs_completions.fish @@ -1,7 +1,7 @@ #!/usr/bin/env fish # -# This file produces command specific completions for darcs. Meant to be -# executed from the root directory (so the completions get put in the right +# This file produces command specific completions for darcs. Meant to be +# executed from the root directory (so the completions get put in the right # place). . build_tools/make_vcs_completions_generic.fish diff --git a/build_tools/make_tarball.sh b/build_tools/make_tarball.sh index c1c840e84..c0fc7a751 100755 --- a/build_tools/make_tarball.sh +++ b/build_tools/make_tarball.sh @@ -49,9 +49,7 @@ rm -f "$path" "$path".gz git archive --format=tar --prefix="$prefix"/ HEAD > "$path" # tarball out the documentation, generate a configure script and version file -# Don't use autoreconf since it invokes commands that may not be installed, like aclocal -# Don't run autoheader since configure.ac runs it. autoconf is enough. -autoconf +autoreconf --no-recursive ./configure --with-doxygen make doc share/man echo $VERSION > version diff --git a/build_tools/make_vcs_completions_generic.fish b/build_tools/make_vcs_completions_generic.fish index efa16dc2b..dda025e37 100755 --- a/build_tools/make_vcs_completions_generic.fish +++ b/build_tools/make_vcs_completions_generic.fish @@ -1,7 +1,7 @@ #!/usr/bin/env fish # -# This file provides generic functions for generating specific completions for -# hg, darcs and a few other vcs systems. It uses the fact that all these +# This file provides generic functions for generating specific completions for +# hg, darcs and a few other vcs systems. It uses the fact that all these # systems have a somewhat uniform command line help mechanism. # diff --git a/build_tools/osx_package_resources/welcome.rtf b/build_tools/osx_package_resources/welcome.rtf index 3411a5337..3be3d8914 100644 --- a/build_tools/osx_package_resources/welcome.rtf +++ b/build_tools/osx_package_resources/welcome.rtf @@ -8,13 +8,13 @@ \f0\fs30 \cf0 Fish is a smart and user friendly command line shell. For more information, visit {\field{\*\fldinst{HYPERLINK "https://fishshell.com"}}{\fldrslt https://fishshell.com}}\ \ -fish will be installed into +fish will be installed into \f1\fs26 /usr/local/ -\f0\fs30 , and fish will be added to +\f0\fs30 , and fish will be added to \f1\fs26 /etc/shells \f0\fs30 if necessary.\ \ -Your default shell will +Your default shell will \i not \i0 be changed. To make fish your default, run:\ \ diff --git a/build_tools/style.fish b/build_tools/style.fish index 9ac4bb7f0..fc60228a1 100755 --- a/build_tools/style.fish +++ b/build_tools/style.fish @@ -30,12 +30,10 @@ if test $all = yes exit 1 end set c_files src/*.h src/*.cpp - # For now we don't restyle all the fish scripts. That's because `fish_indent` still has some - # problems with its output that require manual intervention. Not to mention that very few of the - # fish scripts even conform to `fish_indent` output at this time. When `fish_indent` output is - # deemed acceptable as a default and all the fish scripts have been restyled this comment should - # be removed and the following statement uncommented. - # set f_files share/***.fish + # For now we don't restyle all fish scripts other than completion scripts. That's because people + # really like to vertically align the elements of the `complete` command and fish_indent + # currently does not honor that whitespace. + set f_files (printf '%s\n' share/***.fish | grep -v /completions/) else # We haven't been asked to reformat all the source. If there are uncommitted changes reformat # those using `git clang-format`. Else reformat the files in the most recent commit. diff --git a/configure.ac b/configure.ac index f6558112e..0d4514bbc 100644 --- a/configure.ac +++ b/configure.ac @@ -15,6 +15,7 @@ AC_INIT(fish, m4_esyscmd([cut -f 3 -d ' ' FISH-BUILD-VERSION-FILE | tr -d '\n']), fish-users@lists.sourceforge.net) ac_clean_files=a.out.dSYM + # # List of output variables produced by this configure script # @@ -33,23 +34,23 @@ AC_SUBST(EXTRA_PCRE2) # running autoconf to handle an updates configure.ac. # -AC_MSG_CHECKING([if autoconf needs to be run]) +AC_MSG_CHECKING([if autoreconf needs to be run]) if test configure -ot configure.ac; then AC_MSG_RESULT([yes]) - if which autoconf >/dev/null; then - # No need to provide any error messages if autoconf fails, the + if which autoreconf >/dev/null; then + # No need to provide any error messages if autoreconf fails, the # shell and autconf should take care of that themselves - AC_MSG_NOTICE([running autoconf]) - if autoconf; then + AC_MSG_NOTICE([running autoreconf --no-recursive]) + if autoreconf --no-recursive; then ./configure "$@" exit fi exit 1 else AC_MSG_ERROR( - [cannot find the autoconf program in your path. + [cannot find the autoreconf program in your path. This program needs to be run whenever the configure.ac file is modified. -Please install autoconf and try again.] +Please install autoreconf and try again.] ) fi else @@ -81,6 +82,12 @@ else AC_MSG_RESULT([no]) fi +# +# Include the autoconf macros directory +# + +AC_CONFIG_MACRO_DIRS([m4]) + # # Set up various programs needed for install # Note AC_PROG_CXX sets CXXFLAGS if not set, which we want @@ -97,12 +104,13 @@ AC_PROG_AWK AC_PROG_FGREP AC_PROG_SED AC_USE_SYSTEM_EXTENSIONS +AX_CXX_COMPILE_STDCXX_11(noext,mandatory) # # Tell autoconf to create config.h header # AC_CONFIG_HEADERS(config.h) -AC_CANONICAL_TARGET +AC_CANONICAL_HOST # @@ -209,11 +217,12 @@ CXXFLAGS="$CXXFLAGS -fno-exceptions" # -# -Wall is there to keep me on my toes -# But signed comparison warnings are way too aggressive +# Set some warning flags +# Don't warn about missing field initializers, it has too many +# false positives for code like `struct termios tmodes = {};` # -CXXFLAGS="$CXXFLAGS -Wextra" +CXXFLAGS="$CXXFLAGS -Wextra -Wno-missing-field-initializers" # # This is needed in order to get the really cool backtraces on Linux @@ -242,6 +251,18 @@ AC_CHECK_FILES([/proc/self/stat]) AC_DEFINE([NCURSES_NOMACROS], [1], [Define to 1 to disable ncurses macros that conflict with the STL]) AC_DEFINE([NOMACROS], [1], [Define to 1 to disable curses macros that conflict with the STL]) +# Threading is excitingly broken on Solaris without adding -pthread to CXXFLAGS +# Only support GCC for now +dnl Ideally we would use the AX_PTHREAD macro here, but it's GPL3-licensed +dnl ACX_PTHREAD is way too old and seems to break the OS X build +dnl Both only check with AC_LANG(C) in any case +case $host_os in + solaris*) + CXXFLAGS="$CXXFLAGS -pthread" + CFLAGS="$CFLAGS -pthread" + ;; +esac + # # Check presense of various libraries. This is done on a per-binary # level, since including various extra libraries in all binaries only @@ -250,9 +271,8 @@ AC_DEFINE([NOMACROS], [1], [Define to 1 to disable curses macros that conflict w # # Check for os dependant libraries for all binaries. -AC_SEARCH_LIBS( connect, socket, , [AC_MSG_ERROR([Cannot find the socket library, needed to build this package.] )] ) AC_SEARCH_LIBS( nanosleep, rt, , [AC_MSG_ERROR([Cannot find the rt library, needed to build this package.] )] ) -AC_SEARCH_LIBS( shm_open, rt, , [AC_MSG_ERROR([Cannot find the rt library, needed to build this package.] )] ) +AC_SEARCH_LIBS( shm_open, rt, [AC_DEFINE([HAVE_SHM_OPEN], [1], [Define to 1 if the shm_open() function exists])] ) AC_SEARCH_LIBS( pthread_create, pthread, , [AC_MSG_ERROR([Cannot find the pthread library, needed to build this package.] )] ) AC_SEARCH_LIBS( setupterm, [ncurses tinfo curses], , [AC_MSG_ERROR([Could not find a curses implementation, needed to build fish. If this is Linux, try running 'sudo apt-get install libncurses5-dev' or 'sudo yum install ncurses-devel'])] ) AC_SEARCH_LIBS( [dladdr], [dl] ) @@ -302,10 +322,67 @@ AC_CHECK_FUNCS( futimes ) AC_CHECK_FUNCS( wcslcpy lrand48_r killpg ) AC_CHECK_FUNCS( backtrace_symbols getifaddrs ) AC_CHECK_FUNCS( futimens clock_gettime ) -AC_CHECK_FUNCS( getpwent ) +AC_CHECK_FUNCS( getpwent flock ) +AC_CHECK_FUNCS( dirfd ) AC_CHECK_DECL( [mkostemp], [ AC_CHECK_FUNCS([mkostemp]) ] ) +dnl AC_CHECK_FUNCS uses C linkage, but sometimes (Solaris!) the behaviour is +dnl different with C++. +AC_MSG_CHECKING([for wcsdup]) +AC_TRY_LINK( [ #include ], + [ wchar_t* foo = wcsdup(L""); ], + [ AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_WCSDUP, 1, Define to 1 if you have the `wcsdup' function.) + ], + [AC_MSG_RESULT(no)], + ) + +AC_MSG_CHECKING([for std::wcsdup]) +AC_TRY_LINK( [ #include ], + [ wchar_t* foo = std::wcsdup(L""); ], + [ AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_STD__WCSDUP, 1, Define to 1 if you have the `std::wcsdup' function.) + ], + [AC_MSG_RESULT(no)], + ) + +AC_MSG_CHECKING([for wcscasecmp]) +AC_TRY_LINK( [ #include ], + [ int foo = wcscasecmp(L"", L""); ], + [ AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_WCSCASECMP, 1, Define to 1 if you have the `wcscasecmp' function.) + ], + [AC_MSG_RESULT(no)], + ) + +AC_MSG_CHECKING([for std::wcscasecmp]) +AC_TRY_LINK( [ #include ], + [ int foo = std::wcscasecmp(L"", L""); ], + [ AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_STD__WCSCASECMP, 1, Define to 1 if you have the `std::wcscasecmp' function.) + ], + [AC_MSG_RESULT(no)], + ) + +AC_MSG_CHECKING([for wcsncasecmp]) +AC_TRY_LINK( [ #include ], + [ int foo = wcsncasecmp(L"", L"", 0); ], + [ AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_WCSNCASECMP, 1, Define to 1 if you have the `wcsncasecmp' function.) + ], + [AC_MSG_RESULT(no)], + ) + +AC_MSG_CHECKING([for std::wcsncasecmp]) +AC_TRY_LINK( [ #include ], + [ int foo = std::wcsncasecmp(L"", L"", 0); ], + [ AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_STD__WCSNCASECMP, 1, Define to 1 if you have the `std::wcsncasecmp' function.) + ], + [AC_MSG_RESULT(no)], + ) + if test x$local_gettext != xno; then AC_CHECK_FUNCS( gettext ) @@ -472,6 +549,34 @@ else AC_MSG_RESULT(no) fi +# Check that threads actually work on Solaris +AC_MSG_CHECKING([for threadsafe errno]) +AC_RUN_IFELSE( + [AC_LANG_PROGRAM([ + #include + #include + #include + + void *thread1_func(void *p_arg) + { + errno = 1; + return 0; + } + ],[ + errno = 0; + pthread_t t1; + pthread_create(&t1, NULL, thread1_func, NULL); + pthread_join(t1, NULL); + return errno; + ])], + [AC_MSG_RESULT(yes)], + [ + AC_MSG_RESULT(no) + AC_MSG_FAILURE([errno is not threadsafe - check your compiler settings]) + ], + [AC_MSG_RESULT(crosscompiling, skipped)] +) + pcre2_min_version=10.21 EXTRA_PCRE2= AC_ARG_WITH( @@ -555,7 +660,7 @@ if test "x$included_pcre2" = "xyes"; then AC_MSG_NOTICE([using included PCRE2 library]) # unfortunately these get added to the global configuration ac_configure_args="$ac_configure_args --disable-pcre2-8 --enable-pcre2-$WCHAR_T_BITS --disable-shared" - AC_CONFIG_SUBDIRS([pcre2-10.21]) + AC_CONFIG_SUBDIRS([pcre2-10.22]) PCRE2_CXXFLAGS='-I$(PCRE2_DIR)/src' PCRE2_LIBS='-L$(PCRE2_LIBDIR) -lpcre2-$(PCRE2_WIDTH)' diff --git a/debian/compat b/debian/compat index 45a4fb75d..ec635144f 100644 --- a/debian/compat +++ b/debian/compat @@ -1 +1 @@ -8 +9 diff --git a/debian/control b/debian/control index 6d1535644..5ff06de53 100644 --- a/debian/control +++ b/debian/control @@ -3,7 +3,7 @@ Section: shells Priority: extra Maintainer: ridiculous_fish Uploaders: David Adam -Build-Depends: debhelper (>= 8.0.0), libncurses5-dev, autoconf, autotools-dev, dh-autoreconf, gettext +Build-Depends: debhelper (>= 9.0.0), libncurses5-dev, autoconf, autotools-dev, dh-autoreconf, gettext # When libpcre2-dev is available on all supported Debian versions, add a dependency on that. Standards-Version: 3.9.4 Homepage: http://fishshell.com/ @@ -13,7 +13,7 @@ Vcs-Browser: https://github.com/fish-shell/fish-shell Package: fish Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, fish-common (= ${source:Version}), passwd (>= 4.0.3-10), bc, gettext-base, man-db -Recommends: xsel (>=1.2.0), xdg-utils +Recommends: xsel (>=1.2.0) Description: friendly interactive shell Fish is a command-line shell for modern systems, focusing on user-friendliness, sensibility and discoverability in interactive use. The syntax is simple, but @@ -22,7 +22,8 @@ Description: friendly interactive shell Package: fish-common Architecture: all Depends: ${misc:Depends} -Recommends: fish, python (>=2.6), xdg-utils +Recommends: fish, python (>=2.6) +Suggests: xdg-utils Replaces: fish (<= 2.1.1.dfsg-2) Description: friendly interactive shell (architecture-independent files) Fish is a command-line shell for modern systems, focusing on user-friendliness, diff --git a/debian/rules b/debian/rules index 904f9cdd4..e48ceb825 100755 --- a/debian/rules +++ b/debian/rules @@ -4,17 +4,14 @@ # Uncomment this to turn on verbose mode. export DH_VERBOSE=1 -# dpkg-dev 1.16.1 doesn't export buildflags -# can be removed once on dh compat level 9 -DPKG_EXPORT_BUILDFLAGS = 1 --include /usr/share/dpkg/buildflags.mk - %: dh $@ --with autotools-dev,autoreconf override_dh_installdocs: dh_installdocs --link-doc=fish +# Still needed until all platforms have debhelper 9.20151219 +# Consider transitioning https://wiki.debian.org/DebugPackage override_dh_strip: dh_strip --dbg-package=fish-dbg diff --git a/doc_src/FORMATTING.md b/doc_src/FORMATTING.md index e9f462375..904637139 100644 --- a/doc_src/FORMATTING.md +++ b/doc_src/FORMATTING.md @@ -8,7 +8,7 @@ While the documentation is pretty robust to variations in the documentation sour ## Line breaks and wrapping -Contrary to the rest of the fish source code, the documentation greatly benefits from the use of long lines and soft wrapping. It allows paragraphs to be treated as complete blocks by Doxygen, means that the semantic filter can see complete lines when deciding on how to apply syntax highlighting, and means that man pages will consistently wrap to the width of the users console in advanced pagers, such as 'most'. +Contrary to the rest of the fish source code, the documentation greatly benefits from the use of long lines and soft wrapping. It allows paragraphs to be treated as complete blocks by Doxygen, means that the semantic filter can see complete lines when deciding on how to apply syntax highlighting, and means that man pages will consistently wrap to the width of the users console in advanced pagers, such as 'most'. ## Doxygen special commands and aliases @@ -16,7 +16,7 @@ While Markdown syntax forms the basis of the documentation content, there are so ### Structure: \\page, \\section and \\subsection -Use of Doxygen sections markers are important, as these determine what will be eventually output as a web page, man page or included in the developer docs. +Use of Doxygen sections markers are important, as these determine what will be eventually output as a web page, man page or included in the developer docs. Currently the make process for the documentation is quite convoluted, but basically the HTML docs are produced from a single, compiled file, doc.h. This contains a number of \\page markers that produce the various pages used in the documentation. The format of a \\page mark is: @@ -175,7 +175,7 @@ ___ (3 underscores): Display a cursor. Graphical keyboard shortcuts can be defined using the following special commands. These allow for the different text requirements across the html and man pages. The HTML uses CSS to create a keyboard style, whereas the man page would display the key as text. - `@key{lable}` - Displays a key with a purely textual lable, such as: 'Tab', 'Page Up', 'Page Down', 'Home', 'End', 'F1', 'F19' and so on. + Displays a key with a purely textual lable, such as: 'Tab', 'Page Up', 'Page Down', 'Home', 'End', 'F1', 'F19' and so on. - `@key{modifier,lable}` Displays a keystroke requiring the use of a 'modifier' key, such as 'Control-A', 'Shift-X', 'Alt-Tab' etc. @@ -204,7 +204,7 @@ Some useful Unicode/HTML5 entities: Tested on: - Ubuntu 14.04 with Doxygen 1.8.8, built from [GitHub source](https://github.com/doxygen/doxygen.git). - CentOS 6.5 with Doxygen 1.8.8, built from [GitHub source](https://github.com/doxygen/doxygen.git). -- Mac OS X 10.9 with Homebrew install Doxygen 1.8.7 and 1.8.8. +- Mac OS X 10.9 with Homebrew install Doxygen 1.8.7 and 1.8.8. Graphviz was also installed in all the above testing. diff --git a/doc_src/abbr.txt b/doc_src/abbr.txt index d34f55e1f..c1fd717ee 100644 --- a/doc_src/abbr.txt +++ b/doc_src/abbr.txt @@ -3,6 +3,7 @@ \subsection abbr-synopsis Synopsis \fish{synopsis} abbr --add word phrase... +abbr --rename word new_word abbr --show abbr --list abbr --erase word @@ -33,6 +34,8 @@ The following parameters are available: - `-a WORD PHRASE` or `--add WORD PHRASE` Adds a new abbreviation, causing WORD to be expanded to PHRASE. +- `-r WORD NEW_WORD` or `--rename WORD NEW_WORD` Renames an abbreviation, from WORD to NEW_WORD. + - `-s` or `--show` Show all abbreviated words and their expanded phrases in a manner suitable for export and import. - `-l` or `--list` Lists all abbreviated words. @@ -48,6 +51,11 @@ abbr -a gco git checkout \endfish Add a new abbreviation where `gco` will be replaced with `git checkout`. +\fish +abbr -r gco gch +\endfish +Renames an existing abbreviation from `gco` to `gch`. + \fish abbr -e gco \endfish diff --git a/doc_src/bind.txt b/doc_src/bind.txt index a9148a1b5..7d452a511 100644 --- a/doc_src/bind.txt +++ b/doc_src/bind.txt @@ -71,6 +71,8 @@ The following special input functions are available: - `backward-word`, move one word to the left +- `beginning-of-buffer`, moves to the beginning of the buffer, i.e. the start of the first line + - `beginning-of-history`, move to the beginning of the history - `beginning-of-line`, move to the beginning of the line @@ -81,12 +83,14 @@ The following special input functions are available: - `complete`, guess the remainder of the current token -- `complete-and-search`, invoke the searchable pager on completion options +- `complete-and-search`, invoke the searchable pager on completion options (for convenience, this also moves backwards in the completion pager) - `delete-char`, delete one character to the right of the cursor - `downcase-word`, make the current word lowercase +- `end-of-buffer`, moves to the end of the buffer, i.e. the end of the first line + - `end-of-history`, move to the end of the history - `end-of-line`, move to the end of the line diff --git a/doc_src/command.txt b/doc_src/command.txt index 4f9087d67..b05c77e9c 100644 --- a/doc_src/command.txt +++ b/doc_src/command.txt @@ -13,7 +13,7 @@ The following options are available: - `-s` or `--search` returns the name of the disk file that would be executed, or nothing if no file with the specified name could be found in the `$PATH`. -With the `-s` option, `command` treats every argument as a separate command to look up and sets the exit status to 0 if any of the specified commands were found, or 1 if no commands could be found. +With the `-s` option, `command` treats every argument as a separate command to look up and sets the exit status to 0 if any of the specified commands were found, or 1 if no commands could be found. Additionally passing a `-q` or `--quiet` option prevents any paths from being printed, like the `type -q`, for testing only the exit status. For basic compatibility with POSIX `command`, the `-v` flag is recognized as an alias for `-s`. diff --git a/doc_src/complete.txt b/doc_src/complete.txt index 0e6ee5d03..5a1a86fa7 100644 --- a/doc_src/complete.txt +++ b/doc_src/complete.txt @@ -61,6 +61,10 @@ the fish manual. - `-C` or `--do-complete` with no argument makes complete try to find all possible completions for the current command line buffer. If the shell is not in interactive mode, an error is returned. +- `-A` and `--authoritative` no longer do anything and are silently ignored. + +- `-u` and `--unauthoritative` no longer do anything and are silently ignored. + Command specific tab-completions in `fish` are based on the notion of options and arguments. An option is a parameter which begins with a hyphen, such as '`-h`', '`-help`' or '`--help`'. Arguments are parameters that do not begin with a hyphen. Fish recognizes three styles of options, the same styles as the GNU version of the getopt library. These styles are: - Short options, like '`-a`'. Short options are a single character long, are preceded by a single hyphen and may be grouped together (like '`-la`', which is equivalent to '`-l -a`'). Option arguments may be specified in the following parameter ('`-w 32`') or by appending the option with the value ('`-w32`'). diff --git a/doc_src/function.txt b/doc_src/function.txt index e58d6513a..fb0e0fca8 100644 --- a/doc_src/function.txt +++ b/doc_src/function.txt @@ -31,7 +31,7 @@ The following options are available: - `-S` or `--no-scope-shadowing` allows the function to access the variables of calling functions. Normally, any variables inside the function that have the same name as variables from the calling function are "shadowed", and their contents is independent of the calling function. -- `-V` or `--inherit-variable NAME` snapshots the value of the variable `NAME` and defines a local variable with that same name and value when the function is executed. +- `-V` or `--inherit-variable NAME` snapshots the value of the variable `NAME` and defines a local variable with that same name and value when the function is defined. This is similar to a closure in other languages like Python but a bit different. Note the word "snapshot" in the first sentence. If you change the value of the variable after defining the function, even if you do so in the same scope (typically another function) the new value will not be used by the function you just created using this option. See the `function notify` example below for how this might be used. If the user enters any additional arguments after the function, they are inserted into the environment variable array `$argv`. If the `--argument-names` option is provided, the arguments are also assigned to names specified in that option. diff --git a/doc_src/functions.txt b/doc_src/functions.txt index 1a5b1c078..05c8b6028 100644 --- a/doc_src/functions.txt +++ b/doc_src/functions.txt @@ -3,6 +3,7 @@ \subsection functions-synopsis Synopsis \fish{synopsis} functions [ -a | --all ] [ -n | --names ] +functions [ -m | --metadata ] [ -v ] FUNCTION functions -c OLDNAME NEWNAME functions -d DESCRIPTION FUNCTION functions [ -e | -q ] FUNCTIONS... @@ -14,7 +15,7 @@ functions [ -e | -q ] FUNCTIONS... The following options are available: -- `-a` or `--all` lists all functions, even those whose name start with an underscore. +- `-a` or `--all` lists all functions, even those whose name starts with an underscore. - `-c OLDNAME NEWNAME` or `--copy OLDNAME NEWNAME` creates a new function named NEWNAME, using the definition of the OLDNAME function. @@ -22,10 +23,21 @@ The following options are available: - `-e` or `--erase` causes the specified functions to be erased. +- `-m` or `--metadata` reports the path name where each function is defined or could be autoloaded, `stdin` if the function was defined interactively or on the command line or by reading stdin, and `n/a` if the function isn't available. If the `--verbose` option is also specified then four lines are written: + + -# the pathname as already described, + -# `autoloaded`, `not-autoloaded` or `n/a`, + -# the line number within the file or zero if not applicable, + -# `scope-shadowing` if the function shadows the vars in the calling function (the normal case) else `no-scope-shadowing`, or `n/a` if the function isn't defined. + +You should not assume that only four lines will be written since we may add additional information to the output in the future. + - `-n` or `--names` lists the names of all defined functions. - `-q` or `--query` tests if the specified functions exist. +- `-v` or `--verbose` will make some output more verbose. + The default behavior of `functions`, when called with no arguments, is to print the names of all defined functions. Unless the `-a` option is given, no functions starting with underscores are not included in the output. If any non-option parameters are given, the definition of the specified functions are printed. diff --git a/doc_src/help.txt b/doc_src/help.txt index e279e62b0..9665dba27 100644 --- a/doc_src/help.txt +++ b/doc_src/help.txt @@ -13,6 +13,8 @@ If a `SECTION` is specified, the help for that command is shown. If the BROWSER environment variable is set, it will be used to display the documentation. Otherwise, fish will search for a suitable browser. +If you prefer to use a different browser (other than as described above) for fish help, you can set the fish_help_browser variable. This variable may be set as an array, where the first element is the browser command and the rest are browser options. + Note that most builtin commands display their help in the terminal when given the `--help` option. diff --git a/doc_src/index.hdr.in b/doc_src/index.hdr.in index 27a7ed9a6..3b537179c 100644 --- a/doc_src/index.hdr.in +++ b/doc_src/index.hdr.in @@ -240,6 +240,8 @@ There are a few important things that need to be noted about aliases: - If the alias has the same name as the aliased command, it is necessary to prefix the call to the program with `command` in order to tell fish that the function should not call itself, but rather a command with the same name. Failing to do so will cause infinite recursion bugs. +- Autoloading isn't applicable to aliases. Since, by definition, the function is created at the time the alias command is executed. You cannot autoload aliases. + To easily create a function of this form, you can use the alias command. @@ -263,6 +265,8 @@ It is very important that function definition files only contain the definition Autoloading also won't work for event handlers, since fish cannot know that a function is supposed to be executed when an event occurs when it hasn't yet loaded the function. See the event handlers section for more information. +Autoloading is not applicable to functions created by the `alias` command. For functions simple enough that you prefer to use the `alias` command to define them you'll need to put those commands in your `~/.config/fish/config.fish` script or some other script run when the shell starts. + If you are developing another program, you may wish to install functions which are available for all users of the fish shell on a system. They can be installed to the "vendor" functions directory. As this path may vary from system to system, the `pkgconfig` framework should be used to discover this path with the output of `pkg-config --variable functionsdir fish`. @@ -845,12 +849,10 @@ The user can change the settings of `fish` by changing the values of certain var - `FISH_VERSION`, the version of the currently running fish -- `COLUMNS`, the current width of the terminal - -- `LINES`, the current height of the terminal - - `SHLVL`, the level of nesting of shells +- `COLUMNS` and `LINES`, the current size of the terminal in height and width. These values are only used by fish if the operating system does not report the size of the terminal. Both variables must be set in that case otherwise a default of 80x24 will be used. They are updated when the window size changes. + The names of these variables are mostly derived from the csh family of shells and differ from the ones used by Bourne style shells such as bash. Variables whose name are in uppercase are exported to the commands started by fish, while those in lowercase are not exported. This rule is not enforced by fish, but it is good coding practice to use casing to distinguish between exported and unexported variables. `fish` also uses several variables internally. Such variables are prefixed with the string `__FISH` or `__fish.` These should never be used by the user. Changing their value may break fish. @@ -865,6 +867,8 @@ If `fish` encounters a problem while executing a command, the status variable ma - 1 is the generally the exit status from fish builtin commands if they were supplied with invalid arguments +- 123 means that the command was not executed because the command name contained invalid characters + - 124 means that the command was not executed because none of the wildcards in the command produced any matches - 125 means that while an executable with the specified name was located, the operating system could not actually execute the command @@ -977,7 +981,7 @@ Some bindings are shared between emacs- and vi-mode because they aren't text edi - @key{Alt,↑,Up} and @key{Alt,↓,Down} search the command history for the previous/next token containing the token under the cursor before the search was started. If the commandline was not on a token when the search started, all tokens match. See the history section for more information on history searching. -- @key{Control,C} deletes the entire line. +- @key{Control,C} cancels the entire line. - @key{Control,D} delete one character to the right of the cursor. If the command line is empty, @key{Control,D} will exit fish. @@ -987,15 +991,21 @@ Some bindings are shared between emacs- and vi-mode because they aren't text edi - @key{Control,W} moves the previous path component (everything up to the previous "/") to the killring. -- @key{Alt,D} moves the next word to the killring. +- @key{Control,X} copies the current buffer to the system's clipboard, @key{Control,V} inserts the clipboard contents. -- @key{Alt,H} (or @key{F1}) shows the manual page for the current command, if one exists. +- @key{Alt,d} moves the next word to the killring. -- @key{Alt,L} lists the contents of the current directory, unless the cursor is over a directory argument, in which case the contents of that directory will be listed. +- @key{Alt,h} (or @key{F1}) shows the manual page for the current command, if one exists. -- @key{Alt,P} adds the string '`| less;`' to the end of the job under the cursor. The result is that the output of the command will be paged. +- @key{Alt,l} lists the contents of the current directory, unless the cursor is over a directory argument, in which case the contents of that directory will be listed. -- @key{Alt,W} prints a short description of the command under the cursor. +- @key{Alt,p} adds the string '`| less;`' to the end of the job under the cursor. The result is that the output of the command will be paged. + +- @key{Alt,w} prints a short description of the command under the cursor. + +- @key{Alt,e} edit the current command line in an external editor. The editor is chosen from the first available of the `$VISUAL` or `$EDITOR` variables. + +- @key{Alt,v} Same as @key{Alt,e}. \subsection emacs-mode Emacs mode commands @@ -1009,11 +1019,11 @@ Some bindings are shared between emacs- and vi-mode because they aren't text edi - @key{Control,K} moves contents from the cursor to the end of line to the killring. -- @key{Alt,C} capitalizes the current word. +- @key{Alt,c} capitalizes the current word. -- @key{Alt,U} makes the current word uppercase. +- @key{Alt,u} makes the current word uppercase. -- @key{Control, t} transposes the last two characters +- @key{Control,t} transposes the last two characters - @key{Alt,t} transposes the last two words @@ -1038,7 +1048,7 @@ function fish_user_key_bindings end \endfish -When in vi-mode, the `fish_mode_prompt` function will display a mode indicator to the left of the prompt. The `fish_vi_cursor` function will be used to change the cursor's shape depending on the mode in supported terminals. To disable this feature, override it with an empty function. +When in vi-mode, the `fish_mode_prompt` function will display a mode indicator to the left of the prompt. The `fish_vi_cursor` function will be used to change the cursor's shape depending on the mode in supported terminals. To disable this feature, override it with an empty function. To display the mode elsewhere (like in your right prompt), use the output of the `fish_default_mode_prompt` function. \subsubsection vi-mode-command Command mode @@ -1068,16 +1078,11 @@ Command mode is also known as normal mode. - @key{[} and @key{]} search the command history for the previous/next token containing the token under the cursor before the search was started. See the history section for more information on history searching. -- @key{Control, X} copies the current buffer to the system's clipboard, @key{Control, V} inserts the clipboard contents. -- @key{Control,C} deletes the entire line. - - @key{Backspace} moves the cursor left. \subsubsection vi-mode-insert Insert mode -- @key{Escape} or @key{Control,C} enters command mode. - -- @key{Control,x} moves the cursor to the end of the line. If an autosuggestion is available, it will be accepted completely. +- @key{Escape} enters command mode. - @key{Backspace} removes one character to the left. diff --git a/doc_src/license.hdr b/doc_src/license.hdr index e372104f1..7a57e61b0 100644 --- a/doc_src/license.hdr +++ b/doc_src/license.hdr @@ -7,7 +7,7 @@ \endhtmlonly -`fish` Copyright © 2005-2009 Axel Liljencrantz. `fish` is released under the GNU General Public License, version 2. +`fish` Copyright © 2005-2009 Axel Liljencrantz. `fish` is released under the GNU General Public License, version 2. `fish` includes other code licensed under the GNU General Public License, version 2, including GNU `printf`: @@ -320,6 +320,38 @@ Permission to use, copy, modify, and/or distribute this software for any purpose THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +---- + + +## License for flock + +`fish` also contains small amounts of code from NetBSD, namely the `flock` fallback function. This code is copyright 2001 The NetBSD Foundation, Inc., and derived from software contributed to The NetBSD Foundation by Todd Vierling. + +The NetBSD license follows. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + \htmlonly[block] diff --git a/doc_src/random.txt b/doc_src/random.txt index 5d8a8bab3..28f140152 100644 --- a/doc_src/random.txt +++ b/doc_src/random.txt @@ -2,31 +2,43 @@ \subsection random-synopsis Synopsis \fish{synopsis} -random [SEED] +random +random SEED +random START END +random START STEP END +random choice [ITEMS...] \endfish \subsection random-description Description -`random` outputs a psuedo-random number from 0 to 32767, inclusive. -Even ignoring the very narrow range of values you should not assume -this produces truly random values within that range. Do not use the -value for any cryptographic purposes, and take care to handle collisions: -the same random number appearing more than once in a given fish instance. +`RANDOM` generates a pseudo-random integer from a uniform distribution. The +range (inclusive) is dependent on the arguments passed. +No arguments indicate a range of [0; 32767]. +If one argument is specified, the internal engine will be seeded with the +argument for future invocations of `RANDOM` and no output will be produced. +Two arguments indicate a range of [START; END]. +Three arguments indicate a range of [START; END] with a spacing of STEP +between possible outputs. +`RANDOM choice` will select one random item from the succeeding arguments. -If a `SEED` value is provided, it is used to seed the random number -generator, and no output will be produced. This can be useful for debugging -purposes, where it can be desirable to get the same random number sequence -multiple times. If the random number generator is called without first -seeding it, the current time will be used as the seed. +Note that seeding the engine will NOT give the same result across different +systems. +You should not consider `RANDOM` cryptographically secure, or even +statistically accurate. \subsection random-example Example -The following code will count down from a random number to 1: +The following code will count down from a random even number between 10 and 20 to 1: \fish -for i in (seq (random) -1 1) +for i in (seq (random 10 2 20) -1 1) echo $i - sleep end \endfish + +And this will open a random picture from any of the subdirectories: + +\fish +open (random choice **jpg) +\endfish diff --git a/doc_src/read.txt b/doc_src/read.txt index 33829070c..5514bc848 100644 --- a/doc_src/read.txt +++ b/doc_src/read.txt @@ -43,6 +43,7 @@ If `-a` or `--array` is provided, only one variable name is allowed and the toke See the documentation for `set` for more details on the scoping rules for variables. +When read reaches the end-of-file (EOF) instead of the separator, it returns 1. If not, it returns 0. \subsection read-example Example @@ -50,4 +51,9 @@ The following code stores the value 'hello' in the shell variable `$foo`. \fish echo hello|read foo + +# This is a neat way to handle command output by-line: +printf '%s\n' line1 line2 line3 line4 | while read -l foo + echo "This is another line: $foo" + end \endfish diff --git a/doc_src/set_color.txt b/doc_src/set_color.txt index 112a51f44..8af576458 100644 --- a/doc_src/set_color.txt +++ b/doc_src/set_color.txt @@ -21,15 +21,18 @@ The following options are available: - `-b`, `--background` *COLOR* sets the background color. - `-c`, `--print-colors` prints a list of the 16 named colors. - `-o`, `--bold` sets bold mode. +- `-d`, `--dim` sets dim mode. +- `-i`, `--italics` sets italics mode. +- `-r`, `--reverse` sets reverse mode. - `-u`, `--underline` sets underlined mode. -Using the *normal* keyword will reset foreground, background, and all formatting back to default. +Using the *normal* keyword will reset foreground, background, and all formatting back to default. \subsection set_color-notes Notes 1. Using the *normal* keyword will reset both background and foreground colors to whatever is the default for the terminal. 2. Setting the background color only affects subsequently written characters. Fish provides no way to set the background color for the entire terminal window. Configuring the window background color (and other attributes such as its opacity) has to be done using whatever mechanisms the terminal provides. -3. Some terminals use the `--bold` escape sequence to switch to a brighter color set rather than increasing the weight of text. +3. Some terminals use the `--bold` escape sequence to switch to a brighter color set rather than increasing the weight of text. 4. `set_color` works by printing sequences of characters to *stdout*. If used in command substitution or a pipe, these characters will also be captured. This may or may not be desirable. Checking the exit code of `isatty stdout` before using `set_color` can be useful to decide not to colorize output in a script. \subsection set_color-example Examples @@ -50,3 +53,5 @@ If terminfo reports 256 color support for a terminal, support will always be ena Many terminals support 24-bit (i.e., true-color) color escape sequences. This includes modern xterm, Gnome Terminal, Konsole, and iTerm2. Fish attempts to detect such terminals through various means in `config.fish` You can explicitly force that support via `set fish_term24bit 1`. The `set_color` command uses the terminfo database to look up how to change terminal colors on whatever terminal is in use. Some systems have old and incomplete terminfo databases, and may lack color information for terminals that support it. Fish will assume that all terminals can use the [ANSI X3.64](https://en.wikipedia.org/wiki/ANSI_escape_code) escape sequences if the terminfo definition indicates a color below 16 is not supported. + +Support for italics, dim, reverse, and other modes is not guaranteed in all terminal emulators. Fish attempts to determine if the terminal supports these modes even if the terminfo database may not be up-to-date. diff --git a/fish.spec.in b/fish.spec.in index 89ce0314b..b4e1e69f9 100644 --- a/fish.spec.in +++ b/fish.spec.in @@ -11,6 +11,10 @@ URL: http://fishshell.com/ Source0: %{name}_@VERSION@.orig.tar.gz BuildRequires: ncurses-devel gettext gcc-c++ autoconf +%if 0%{?opensuse_bs} && 0%{?rhel} && 0%{?rhel} < 7 +BuildRequires: gcc48 gcc48-c++ +%endif + BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Requires: bc @@ -34,7 +38,19 @@ is simple but incompatible with other shell languages. %setup -q -n %{name}-@VERSION@ %build +%if 0%{?opensuse_bs} && 0%{?rhel} && 0%{?rhel} < 7 +export CC=gcc48 +export CXX=g++48 +%if 0%{?rhel} < 6 +# i686 required for atomic instructions; default is i386 +export CXXFLAGS="$CXXFLAGS -march=i686" +%endif +%endif +%if 0%{?opensuse_bs} +%configure || cat config.log +%else %configure +%endif make %{?_smp_mflags} %install diff --git a/fish.xcodeproj/project.pbxproj b/fish.xcodeproj/project.pbxproj index f31cdf263..4431ab2d2 100644 --- a/fish.xcodeproj/project.pbxproj +++ b/fish.xcodeproj/project.pbxproj @@ -817,7 +817,7 @@ D04F7FF71BA4E82C00B0F227 /* pcre2_chartables.c.dist */, ); name = pcre; - path = "pcre2-10.21/src"; + path = "pcre2-10.22/src"; sourceTree = SOURCE_ROOT; }; D08A328E17B4455100F3A533 /* fish_tests */ = { @@ -1138,7 +1138,7 @@ D0A084F213B3AC130099B651 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0800; + LastUpgradeCheck = 0820; TargetAttributes = { D008D0C41BC58F8800841177 = { CreatedOnToolsVersion = 7.0.1; @@ -1751,18 +1751,6 @@ }; name = Release; }; - 9C7A55711DCD71330049C25D /* Release_C++11 */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - LLVM_LTO = YES_THIN; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = "Release_C++11"; - }; D007693F1990137800CA4627 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1789,139 +1777,6 @@ }; name = Release; }; - D00769411990137800CA4627 /* Release_C++11 */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - LLVM_LTO = YES_THIN; - PRODUCT_NAME = fish_tests; - }; - name = "Release_C++11"; - }; - D007FDDA17136EAA00A52BE6 /* Release_C++11 */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - DEAD_CODE_STRIPPING = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_ENABLE_CPP_EXCEPTIONS = NO; - GCC_ENABLE_CPP_RTTI = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - "LOCALEDIR=\\\"/usr/local/share/locale\\\"", - "PREFIX=L\\\"/usr/local\\\"", - "DATADIR=L\\\"/usr/local/share\\\"", - "SYSCONFDIR=L\\\"/usr/local/etc\\\"", - "BINDIR=L\\\"/usr/local/bin\\\"", - "DOCDIR=L\\\"/usr/local/share/doc\\\"", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_MISSING_NEWLINE = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_LABEL = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.7; - SDKROOT = macosx; - USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/osx $(SRCROOT)/osx/shared_headers $(SHARED_DERIVED_FILE_DIR)"; - WARNING_CFLAGS = ( - "-Wall", - "-Wunused-macros", - ); - }; - name = "Release_C++11"; - }; - D007FDDB17136EAA00A52BE6 /* Release_C++11 */ = { - isa = XCBuildConfiguration; - buildSettings = { - COMBINE_HIDPI_IMAGES = YES; - INSTALL_PATH = /usr/local; - PRODUCT_NAME = "base copy"; - SKIP_INSTALL = NO; - }; - name = "Release_C++11"; - }; - D007FDDC17136EAA00A52BE6 /* Release_C++11 */ = { - isa = XCBuildConfiguration; - buildSettings = { - COMBINE_HIDPI_IMAGES = YES; - INSTALL_PATH = /usr/local; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = NO; - }; - name = "Release_C++11"; - }; - D007FDDD17136EAA00A52BE6 /* Release_C++11 */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - EXECUTABLE_NAME = fish_launcher; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - INFOPLIST_FILE = osx/Info.plist; - LLVM_LTO = YES_THIN; - PRODUCT_BUNDLE_IDENTIFIER = "com.ridiculousfish.fish-shell"; - PRODUCT_NAME = fish; - WRAPPER_EXTENSION = app; - }; - name = "Release_C++11"; - }; - D007FDDE17136EAA00A52BE6 /* Release_C++11 */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - LLVM_LTO = YES_THIN; - PRODUCT_NAME = fish; - }; - name = "Release_C++11"; - }; - D007FDE017136EAA00A52BE6 /* Release_C++11 */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - LLVM_LTO = YES_THIN; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = "Release_C++11"; - }; - D007FDE217136EAA00A52BE6 /* Release_C++11 */ = { - isa = XCBuildConfiguration; - buildSettings = { - COMBINE_HIDPI_IMAGES = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = "Release_C++11"; - }; D008D0C51BC58F8800841177 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1936,13 +1791,6 @@ }; name = Release; }; - D008D0C71BC58F8800841177 /* Release_C++11 */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = "Release_C++11"; - }; D04F7FD21BA4E29300B0F227 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1965,7 +1813,7 @@ SKIP_INSTALL = YES; USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/osx/pcre2 $(SRCROOT)/osx/shared_headers/"; USE_HEADERMAP = NO; - WARNING_CFLAGS = ""; + WARNING_CFLAGS = "-Wno-unreachable-code"; }; name = Debug; }; @@ -1991,36 +1839,10 @@ SKIP_INSTALL = YES; USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/osx/pcre2 $(SRCROOT)/osx/shared_headers/"; USE_HEADERMAP = NO; - WARNING_CFLAGS = ""; + WARNING_CFLAGS = "-Wno-unreachable-code"; }; name = Release; }; - D04F7FD41BA4E29300B0F227 /* Release_C++11 */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - GCC_INPUT_FILETYPE = sourcecode.c.c; - GCC_PREPROCESSOR_DEFINITIONS = ( - "LOCALEDIR=\\\"/usr/local/share/locale\\\"", - "PREFIX=L\\\"/usr/local\\\"", - "DATADIR=L\\\"/usr/local/share\\\"", - "SYSCONFDIR=L\\\"/usr/local/etc\\\"", - "BINDIR=L\\\"/usr/local/bin\\\"", - "DOCDIR=L\\\"/usr/local/share/doc\\\"", - "PCRE2_CODE_UNIT_WIDTH=32", - "HAVE_CONFIG_H=1", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = NO; - GCC_WARN_UNUSED_VARIABLE = NO; - LLVM_LTO = YES_THIN; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/osx/pcre2 $(SRCROOT)/osx/shared_headers/"; - USE_HEADERMAP = NO; - WARNING_CFLAGS = ""; - }; - name = "Release_C++11"; - }; D07D267015E33B86009E43F6 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2045,6 +1867,8 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; + CLANG_CXX_LIBRARY = "libc++"; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; @@ -2080,7 +1904,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_LABEL = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.6; + MACOSX_DEPLOYMENT_TARGET = 10.7; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/osx $(SRCROOT)/osx/shared_headers $(SHARED_DERIVED_FILE_DIR)"; @@ -2095,6 +1919,8 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; + CLANG_CXX_LIBRARY = "libc++"; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; @@ -2128,7 +1954,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_LABEL = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.6; + MACOSX_DEPLOYMENT_TARGET = 10.7; SDKROOT = macosx; USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/osx $(SRCROOT)/osx/shared_headers $(SHARED_DERIVED_FILE_DIR)"; WARNING_CFLAGS = ( @@ -2276,7 +2102,6 @@ buildConfigurations = ( 9C7A556F1DCD71330049C25D /* Debug */, 9C7A55701DCD71330049C25D /* Release */, - 9C7A55711DCD71330049C25D /* Release_C++11 */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -2286,7 +2111,6 @@ buildConfigurations = ( D007693F1990137800CA4627 /* Debug */, D00769401990137800CA4627 /* Release */, - D00769411990137800CA4627 /* Release_C++11 */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -2296,7 +2120,6 @@ buildConfigurations = ( D008D0C51BC58F8800841177 /* Debug */, D008D0C61BC58F8800841177 /* Release */, - D008D0C71BC58F8800841177 /* Release_C++11 */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -2306,7 +2129,6 @@ buildConfigurations = ( D04F7FD21BA4E29300B0F227 /* Debug */, D04F7FD31BA4E29300B0F227 /* Release */, - D04F7FD41BA4E29300B0F227 /* Release_C++11 */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -2316,7 +2138,6 @@ buildConfigurations = ( D07D267015E33B86009E43F6 /* Debug */, D07D267115E33B86009E43F6 /* Release */, - D007FDDB17136EAA00A52BE6 /* Release_C++11 */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -2326,7 +2147,6 @@ buildConfigurations = ( D0A084F813B3AC130099B651 /* Debug */, D0A084F913B3AC130099B651 /* Release */, - D007FDDA17136EAA00A52BE6 /* Release_C++11 */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -2336,7 +2156,6 @@ buildConfigurations = ( D0A564E7168CFDD800AF6161 /* Debug */, D0A564E8168CFDD800AF6161 /* Release */, - D007FDE217136EAA00A52BE6 /* Release_C++11 */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -2346,7 +2165,6 @@ buildConfigurations = ( D0D02AA515985A75008E62BD /* Debug */, D0D02AA615985A75008E62BD /* Release */, - D007FDDD17136EAA00A52BE6 /* Release_C++11 */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -2356,7 +2174,6 @@ buildConfigurations = ( D0D02AD41598642A008E62BD /* Debug */, D0D02AD51598642A008E62BD /* Release */, - D007FDE017136EAA00A52BE6 /* Release_C++11 */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -2366,7 +2183,6 @@ buildConfigurations = ( D0D26944159835CA005D9B9C /* Debug */, D0D26945159835CA005D9B9C /* Release */, - D007FDDE17136EAA00A52BE6 /* Release_C++11 */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -2376,7 +2192,6 @@ buildConfigurations = ( D0F019EE15A976F30034B3B1 /* Debug */, D0F019EF15A976F30034B3B1 /* Release */, - D007FDDC17136EAA00A52BE6 /* Release_C++11 */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/fish.xcodeproj/xcshareddata/xcschemes/Makefile.xcscheme b/fish.xcodeproj/xcshareddata/xcschemes/Makefile.xcscheme index c96046ff1..6706aea40 100644 --- a/fish.xcodeproj/xcshareddata/xcschemes/Makefile.xcscheme +++ b/fish.xcodeproj/xcshareddata/xcschemes/Makefile.xcscheme @@ -1,6 +1,6 @@ +# Copyright (c) 2012 Zack Weinberg +# Copyright (c) 2013 Roy Stogner +# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov +# Copyright (c) 2015 Paul Norman +# Copyright (c) 2015 Moritz Klammler +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 4 + +dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro +dnl (serial version number 13). + +AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl + m4_if([$1], [11], [], + [$1], [14], [], + [$1], [17], [m4_fatal([support for C++17 not yet implemented in AX_CXX_COMPILE_STDCXX])], + [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$2], [], [], + [$2], [ext], [], + [$2], [noext], [], + [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], + [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], + [$3], [optional], [ax_cxx_compile_cxx$1_required=false], + [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) + AC_LANG_PUSH([C++])dnl + ac_success=no + AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, + ax_cv_cxx_compile_cxx$1, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [ax_cv_cxx_compile_cxx$1=yes], + [ax_cv_cxx_compile_cxx$1=no])]) + if test x$ax_cv_cxx_compile_cxx$1 = xyes; then + ac_success=yes + fi + + m4_if([$2], [noext], [], [dnl + if test x$ac_success = xno; then + for switch in -std=gnu++$1 -std=gnu++0x; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + fi]) + + m4_if([$2], [ext], [], [dnl + if test x$ac_success = xno; then + dnl HP's aCC needs +std=c++11 according to: + dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf + dnl Cray's crayCC needs "-h std=c++11" + for switch in -std=c++$1 -std=c++0x +std=c++$1 "-h std=c++$1"; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + fi]) + AC_LANG_POP([C++]) + if test x$ax_cxx_compile_cxx$1_required = xtrue; then + if test x$ac_success = xno; then + AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) + fi + fi + if test x$ac_success = xno; then + HAVE_CXX$1=0 + AC_MSG_NOTICE([No compiler with C++$1 support was found]) + else + HAVE_CXX$1=1 + AC_DEFINE(HAVE_CXX$1,1, + [define if the compiler supports basic C++$1 syntax]) + fi + AC_SUBST(HAVE_CXX$1) +]) + + +dnl Test body for checking C++11 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 +) + + +dnl Test body for checking C++14 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 +) + + +dnl Tests for new features in C++11 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual void f() {} + }; + + struct Derived : public Base + { + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + +]]) + + +dnl Tests for new features in C++14 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_seperators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + +]]) diff --git a/m4/ax_cxx_compile_stdcxx_11.m4 b/m4/ax_cxx_compile_stdcxx_11.m4 new file mode 100644 index 000000000..0aadeafe7 --- /dev/null +++ b/m4/ax_cxx_compile_stdcxx_11.m4 @@ -0,0 +1,39 @@ +# ============================================================================ +# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html +# ============================================================================ +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX_11([ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the C++11 +# standard; if necessary, add switches to CXX and CXXCPP to enable +# support. +# +# This macro is a convenience alias for calling the AX_CXX_COMPILE_STDCXX +# macro with the version set to C++11. The two optional arguments are +# forwarded literally as the second and third argument respectively. +# Please see the documentation for the AX_CXX_COMPILE_STDCXX macro for +# more information. If you want to use this macro, you also need to +# download the ax_cxx_compile_stdcxx.m4 file. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik +# Copyright (c) 2012 Zack Weinberg +# Copyright (c) 2013 Roy Stogner +# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov +# Copyright (c) 2015 Paul Norman +# Copyright (c) 2015 Moritz Klammler +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 17 + +AX_REQUIRE_DEFINED([AX_CXX_COMPILE_STDCXX]) +AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [AX_CXX_COMPILE_STDCXX([11], [$1], [$2])]) diff --git a/osx/Info.plist b/osx/Info.plist index dbbcc6398..8d703c2bc 100644 --- a/osx/Info.plist +++ b/osx/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2.3.500 + 2.4.500 CFBundleVersion 0.1 LSApplicationCategoryType diff --git a/osx/config.h b/osx/config.h index f273f679f..4431c9c2a 100644 --- a/osx/config.h +++ b/osx/config.h @@ -10,13 +10,22 @@ /* Define to 1 if you have the header file. */ #define HAVE_CURSES_H 1 +/* define if the compiler supports basic C++11 syntax */ +#define HAVE_CXX11 1 + /* Define to 1 if you have the header file, and it defines `DIR'. */ #define HAVE_DIRENT_H 1 +/* Define to 1 if you have the `dirfd' function. */ +#define HAVE_DIRFD 1 + /* Define to 1 if you have the header file. */ #define HAVE_EXECINFO_H 1 +/* Define to 1 if you have the `flock' function. */ +#define HAVE_FLOCK 1 + /* Define to 1 if you have the `futimens' function. */ /* #undef HAVE_FUTIMENS */ @@ -65,6 +74,9 @@ /* Define to 1 if you have the header file, and it defines `DIR'. */ /* #undef HAVE_NDIR_H */ +/* Define to 1 if the shm_open() function exists */ +#define HAVE_SHM_OPEN 1 + /* Define to 1 if you have the header file. */ /* #undef HAVE_SIGINFO_H */ @@ -77,6 +89,15 @@ /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 +/* Define to 1 if you have the `std::wcscasecmp' function. */ +/* #undef HAVE_STD__WCSCASECMP */ + +/* Define to 1 if you have the `std::wcsdup' function. */ +/* #undef HAVE_STD__WCSDUP */ + +/* Define to 1 if you have the `std::wcsncasecmp' function. */ +/* #undef HAVE_STD__WCSNCASECMP */ + /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 @@ -139,6 +160,9 @@ /* Define to 1 if you have the `wcslcpy' function. */ #define HAVE_WCSLCPY 1 +/* Define to 1 if you have the `wcsncasecmp' function. */ +#define HAVE_WCSNCASECMP 1 + /* Define to 1 if you have the `wcsndup' function. */ /* #undef HAVE_WCSNDUP */ @@ -167,7 +191,7 @@ #define PACKAGE_NAME "fish" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "fish 2.3.1-git" +#define PACKAGE_STRING "fish 2.4.0-git" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "fish" @@ -176,7 +200,7 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "2.3.1-git" +#define PACKAGE_VERSION "2.4.0-git" /* The size of `wchar_t', as computed by sizeof. */ #define SIZEOF_WCHAR_T 4 diff --git a/osx/pcre2/config.h b/osx/pcre2/config.h index e76dd9f7c..c663bd26b 100644 --- a/osx/pcre2/config.h +++ b/osx/pcre2/config.h @@ -112,6 +112,9 @@ sure both macros are undefined; an emulation function will then be used. */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_WAIT_H 1 + /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 @@ -170,6 +173,9 @@ sure both macros are undefined; an emulation function will then be used. */ overflow caused by enormously large patterns. */ #define MAX_NAME_SIZE 32 +/* Defining NEVER_BACKSLASH_C locks out the use of \C in all patterns. */ +/* #undef NEVER_BACKSLASH_C */ + /* The value of NEWLINE_DEFAULT determines the default newline character sequence. PCRE2 client programs can override this by selecting other values at run time. The valid values are 1 (CR), 2 (LF), 3 (CRLF), 4 (ANY), and 5 @@ -186,7 +192,7 @@ sure both macros are undefined; an emulation function will then be used. */ #define PACKAGE_NAME "PCRE2" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "PCRE2 10.20" +#define PACKAGE_STRING "PCRE2 10.22" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "pcre2" @@ -195,7 +201,7 @@ sure both macros are undefined; an emulation function will then be used. */ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "10.20" +#define PACKAGE_VERSION "10.22" /* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested parentheses (of any kind) in a pattern. This limits the amount of system @@ -234,7 +240,7 @@ sure both macros are undefined; an emulation function will then be used. */ #define PCRE2_EXP_DEFN __attribute__ ((visibility ("default"))) /* Define to any value if linking statically (TODO: make nice with Libtool) */ -#define PCRE2_STATIC 1 +/* #undef PCRE2_STATIC */ /* Define to necessary symbol if this constant uses a non-standard name on your system. */ @@ -260,6 +266,9 @@ sure both macros are undefined; an emulation function will then be used. */ is able to handle .gz files. */ /* #undef SUPPORT_LIBZ */ +/* Define to any value to enable callout script support in pcre2grep. */ +#define SUPPORT_PCRE2GREP_CALLOUT /**/ + /* Define to any value to enable JIT support in pcre2grep. */ /* #undef SUPPORT_PCRE2GREP_JIT */ @@ -267,10 +276,10 @@ sure both macros are undefined; an emulation function will then be used. */ /* #undef SUPPORT_PCRE2_16 */ /* Define to any value to enable the 32 bit PCRE2 library. */ -#define SUPPORT_PCRE2_32 /**/ +/* #undef SUPPORT_PCRE2_32 */ /* Define to any value to enable the 8 bit PCRE2 library. */ -/* #undef SUPPORT_PCRE2_8 */ +#define SUPPORT_PCRE2_8 /**/ /* Define to any value to enable support for Unicode and UTF encoding. This will work even in an EBCDIC environment, but it is incompatible with the @@ -282,7 +291,7 @@ sure both macros are undefined; an emulation function will then be used. */ /* #undef SUPPORT_VALGRIND */ /* Version number of package */ -#define VERSION "10.20" +#define VERSION "10.22" /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ diff --git a/osx/shared_headers/pcre2.h b/osx/shared_headers/pcre2.h index 7f9ba4f19..20d221b80 100644 --- a/osx/shared_headers/pcre2.h +++ b/osx/shared_headers/pcre2.h @@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE. /* The current PCRE version information. */ #define PCRE2_MAJOR 10 -#define PCRE2_MINOR 21 +#define PCRE2_MINOR 22 #define PCRE2_PRERELEASE -#define PCRE2_DATE 2016-01-12 +#define PCRE2_DATE 2016-07-29 /* When an application links to a PCRE DLL in Windows, the symbols that are imported have to be identified as such. When building PCRE2, the appropriate @@ -146,7 +146,8 @@ sanity checks). */ #define PCRE2_DFA_RESTART 0x00000040u #define PCRE2_DFA_SHORTEST 0x00000080u -/* These are additional options for pcre2_substitute(). */ +/* These are additional options for pcre2_substitute(), which passes any others +through to pcre2_match(). */ #define PCRE2_SUBSTITUTE_GLOBAL 0x00000100u #define PCRE2_SUBSTITUTE_EXTENDED 0x00000200u @@ -154,6 +155,11 @@ sanity checks). */ #define PCRE2_SUBSTITUTE_UNKNOWN_UNSET 0x00000800u #define PCRE2_SUBSTITUTE_OVERFLOW_LENGTH 0x00001000u +/* A further option for pcre2_match(), not allowed for pcre2_dfa_match(), +ignored for pcre2_jit_match(). */ + +#define PCRE2_NO_JIT 0x00002000u + /* Newline and \R settings, for use in compile contexts. The newline values must be kept in step with values set in config.h and both sets must all be greater than zero. */ @@ -245,6 +251,7 @@ numbers must not be changed. */ #define PCRE2_ERROR_BADSUBSTITUTION (-59) #define PCRE2_ERROR_BADSUBSPATTERN (-60) #define PCRE2_ERROR_TOOMANYREPLACE (-61) +#define PCRE2_ERROR_BADSERIALIZEDDATA (-62) /* Request types for pcre2_pattern_info() */ @@ -436,7 +443,9 @@ PCRE2_EXP_DECL int pcre2_set_recursion_memory_management( \ PCRE2_EXP_DECL \ pcre2_code *pcre2_compile(PCRE2_SPTR, PCRE2_SIZE, uint32_t, \ int *, PCRE2_SIZE *, pcre2_compile_context *); \ -PCRE2_EXP_DECL void pcre2_code_free(pcre2_code *); +PCRE2_EXP_DECL void pcre2_code_free(pcre2_code *); \ +PCRE2_EXP_DECL \ + pcre2_code *pcre2_code_copy(const pcre2_code *); /* Functions that give information about a compiled pattern. */ @@ -585,6 +594,7 @@ pcre2_compile are called by application code. */ /* Functions: the complete list in alphabetical order */ #define pcre2_callout_enumerate PCRE2_SUFFIX(pcre2_callout_enumerate_) +#define pcre2_code_copy PCRE2_SUFFIX(pcre2_code_copy_) #define pcre2_code_free PCRE2_SUFFIX(pcre2_code_free_) #define pcre2_compile PCRE2_SUFFIX(pcre2_compile_) #define pcre2_compile_context_copy PCRE2_SUFFIX(pcre2_compile_context_copy_) diff --git a/pcre2-10.21/.gitignore b/pcre2-10.22/.gitignore similarity index 100% rename from pcre2-10.21/.gitignore rename to pcre2-10.22/.gitignore diff --git a/pcre2-10.21/132html b/pcre2-10.22/132html similarity index 100% rename from pcre2-10.21/132html rename to pcre2-10.22/132html diff --git a/pcre2-10.21/AUTHORS b/pcre2-10.22/AUTHORS similarity index 100% rename from pcre2-10.21/AUTHORS rename to pcre2-10.22/AUTHORS diff --git a/pcre2-10.21/CMakeLists.txt b/pcre2-10.22/CMakeLists.txt similarity index 96% rename from pcre2-10.21/CMakeLists.txt rename to pcre2-10.22/CMakeLists.txt index 2c84b054d..ced3df2ff 100644 --- a/pcre2-10.21/CMakeLists.txt +++ b/pcre2-10.22/CMakeLists.txt @@ -71,6 +71,9 @@ # 2015-07-16 PH updated for new pcre2_find_bracket source module # 2015-08-24 PH correct C_FLAGS setting (patch from Roy Ivy III) # 2015-10=16 PH added support for never-backslash-C +# 2016-03-01 PH applied Chris Wilson's patch for MSVC static +# 2016-06-24 PH applied Chris Wilson's second patch, putting the first under +# a new option instead of being unconditional. PROJECT(PCRE2 C) @@ -157,6 +160,9 @@ SET(PCRE2_SUPPORT_JIT OFF CACHE BOOL SET(PCRE2_SUPPORT_PCRE2GREP_JIT ON CACHE BOOL "Enable use of Just-in-time compiling in pcre2grep.") +SET(PCRE2_SUPPORT_PCRE2GREP_CALLOUT ON CACHE BOOL + "Enable callout string support in pcre2grep.") + SET(PCRE2_SUPPORT_UNICODE ON CACHE BOOL "Enable support for Unicode and UTF-8/UTF-16/UTF-32 encoding.") @@ -184,6 +190,9 @@ IF (MINGW) ENDIF(MINGW) IF(MSVC) + OPTION(PCRE_STATIC_RUNTIME OFF CACHE BOOL + "ON=Compile against the static runtime (/MT)." + OFF) OPTION(INSTALL_MSVC_PDB "ON=Install .pdb files built by MSVC, if generated" OFF) @@ -272,6 +281,10 @@ IF(PCRE2_SUPPORT_PCRE2GREP_JIT) SET(SUPPORT_PCRE2GREP_JIT 1) ENDIF(PCRE2_SUPPORT_PCRE2GREP_JIT) +IF(PCRE2_SUPPORT_PCRE2GREP_CALLOUT) + SET(SUPPORT_PCRE2GREP_CALLOUT 1) +ENDIF(PCRE2_SUPPORT_PCRE2GREP_CALLOUT) + IF(PCRE2_SUPPORT_VALGRIND) SET(SUPPORT_VALGRIND 1) ENDIF(PCRE2_SUPPORT_VALGRIND) @@ -456,6 +469,18 @@ SET(PCRE2POSIX_SOURCES ENDIF (EXISTS ${PROJECT_SOURCE_DIR}/pcre2posix.rc) ENDIF(MSVC AND NOT PCRE2_STATIC) +# Fix static compilation with MSVC: https://bugs.exim.org/show_bug.cgi?id=1681 +# This code was taken from the CMake wiki, not from WebM. + +IF(MSVC AND PCRE2_STATIC_RUNTIME) + MESSAGE(STATUS "** MSVC and PCRE2_STATIC_RUNTIME: modifying compiler flags to use static runtime library") + foreach(flag_var + CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE + CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO) + string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") + endforeach() +ENDIF(MSVC AND PCRE2_STATIC_RUNTIME) + # Build setup ADD_DEFINITIONS(-DHAVE_CONFIG_H) @@ -740,6 +765,7 @@ IF(PCRE2_SHOW_REPORT) MESSAGE(STATUS " Build static libs ............... : ${BUILD_STATIC_LIBS}") MESSAGE(STATUS " Build pcre2grep ................. : ${PCRE2_BUILD_PCRE2GREP}") MESSAGE(STATUS " Enable JIT in pcre2grep ......... : ${PCRE2_SUPPORT_PCRE2GREP_JIT}") + MESSAGE(STATUS " Enable callouts in pcre2grep .... : ${PCRE2_SUPPORT_PCRE2GREP_CALLOUT}") MESSAGE(STATUS " Buffer size for pcre2grep ....... : ${PCRE2GREP_BUFSIZE}") MESSAGE(STATUS " Build tests (implies pcre2test . : ${PCRE2_BUILD_TESTS}") MESSAGE(STATUS " and pcre2grep)") diff --git a/pcre2-10.21/COPYING b/pcre2-10.22/COPYING similarity index 100% rename from pcre2-10.21/COPYING rename to pcre2-10.22/COPYING diff --git a/pcre2-10.21/ChangeLog b/pcre2-10.22/ChangeLog similarity index 81% rename from pcre2-10.21/ChangeLog rename to pcre2-10.22/ChangeLog index 2035490c6..3dcebb954 100644 --- a/pcre2-10.21/ChangeLog +++ b/pcre2-10.22/ChangeLog @@ -1,6 +1,182 @@ Change Log for PCRE2 -------------------- + +Version 10.22 29-July-2016 +-------------------------- + +1. Applied Jason Hood's patches to RunTest.bat and testdata/wintestoutput3 +to fix problems with running the tests under Windows. + +2. Implemented a facility for quoting literal characters within hexadecimal +patterns in pcre2test, to make it easier to create patterns with just a few +non-printing characters. + +3. Binary zeros are not supported in pcre2test input files. It now detects them +and gives an error. + +4. Updated the valgrind parameters in RunTest: (a) changed smc-check=all to +smc-check=all-non-file; (b) changed obj:* in the suppression file to obj:??? so +that it matches only unknown objects. + +5. Updated the maintenance script maint/ManyConfigTests to make it easier to +select individual groups of tests. + +6. When the POSIX wrapper function regcomp() is called, the REG_NOSUB option +used to set PCRE2_NO_AUTO_CAPTURE when calling pcre2_compile(). However, this +disables the use of back references (and subroutine calls), which are supported +by other implementations of regcomp() with RE_NOSUB. Therefore, REG_NOSUB no +longer causes PCRE2_NO_AUTO_CAPTURE to be set, though it still ignores nmatch +and pmatch when regexec() is called. + +7. Because of 6 above, pcre2test has been modified with a new modifier called +posix_nosub, to call regcomp() with REG_NOSUB. Previously the no_auto_capture +modifier had this effect. That option is now ignored when the POSIX API is in +use. + +8. Minor tidies to the pcre2demo.c sample program, including more comments +about its 8-bit-ness. + +9. Detect unmatched closing parentheses and give the error in the pre-scan +instead of later. Previously the pre-scan carried on and could give a +misleading incorrect error message. For example, /(?J)(?'a'))(?'a')/ gave a +message about invalid duplicate group names. + +10. It has happened that pcre2test was accidentally linked with another POSIX +regex library instead of libpcre2-posix. In this situation, a call to regcomp() +(in the other library) may succeed, returning zero, but of course putting its +own data into the regex_t block. In one example the re_pcre2_code field was +left as NULL, which made pcre2test think it had not got a compiled POSIX regex, +so it treated the next line as another pattern line, resulting in a confusing +error message. A check has been added to pcre2test to see if the data returned +from a successful call of regcomp() are valid for PCRE2's regcomp(). If they +are not, an error message is output and the pcre2test run is abandoned. The +message points out the possibility of a mis-linking. Hopefully this will avoid +some head-scratching the next time this happens. + +11. A pattern such as /(?<=((?C)0))/, which has a callout inside a lookbehind +assertion, caused pcre2test to output a very large number of spaces when the +callout was taken, making the program appearing to loop. + +12. A pattern that included (*ACCEPT) in the middle of a sufficiently deeply +nested set of parentheses of sufficient size caused an overflow of the +compiling workspace (which was diagnosed, but of course is not desirable). + +13. Detect missing closing parentheses during the pre-pass for group +identification. + +14. Changed some integer variable types and put in a number of casts, following +a report of compiler warnings from Visual Studio 2013 and a few tests with +gcc's -Wconversion (which still throws up a lot). + +15. Implemented pcre2_code_copy(), and added pushcopy and #popcopy to pcre2test +for testing it. + +16. Change 66 for 10.21 introduced the use of snprintf() in PCRE2's version of +regerror(). When the error buffer is too small, my version of snprintf() puts a +binary zero in the final byte. Bug #1801 seems to show that other versions do +not do this, leading to bad output from pcre2test when it was checking for +buffer overflow. It no longer assumes a binary zero at the end of a too-small +regerror() buffer. + +17. Fixed typo ("&&" for "&") in pcre2_study(). Fortunately, this could not +actually affect anything, by sheer luck. + +18. Two minor fixes for MSVC compilation: (a) removal of apparently incorrect +"const" qualifiers in pcre2test and (b) defining snprintf as _snprintf for +older MSVC compilers. This has been done both in src/pcre2_internal.h for most +of the library, and also in src/pcre2posix.c, which no longer includes +pcre2_internal.h (see 24 below). + +19. Applied Chris Wilson's patch (Bugzilla #1681) to CMakeLists.txt for MSVC +static compilation. Subsequently applied Chris Wilson's second patch, putting +the first patch under a new option instead of being unconditional when +PCRE_STATIC is set. + +20. Updated pcre2grep to set stdout as binary when run under Windows, so as not +to convert \r\n at the ends of reflected lines into \r\r\n. This required +ensuring that other output that is written to stdout (e.g. file names) uses the +appropriate line terminator: \r\n for Windows, \n otherwise. + +21. When a line is too long for pcre2grep's internal buffer, show the maximum +length in the error message. + +22. Added support for string callouts to pcre2grep (Zoltan's patch with PH +additions). + +23. RunTest.bat was missing a "set type" line for test 22. + +24. The pcre2posix.c file was including pcre2_internal.h, and using some +"private" knowledge of the data structures. This is unnecessary; the code has +been re-factored and no longer includes pcre2_internal.h. + +25. A racing condition is fixed in JIT reported by Mozilla. + +26. Minor code refactor to avoid "array subscript is below array bounds" +compiler warning. + +27. Minor code refactor to avoid "left shift of negative number" warning. + +28. Add a bit more sanity checking to pcre2_serialize_decode() and document +that it expects trusted data. + +29. Fix typo in pcre2_jit_test.c + +30. Due to an oversight, pcre2grep was not making use of JIT when available. +This is now fixed. + +31. The RunGrepTest script is updated to use the valgrind suppressions file +when testing with JIT under valgrind (compare 10.21/51 below). The suppressions +file is updated so that is now the same as for PCRE1: it suppresses the +Memcheck warnings Addr16 and Cond in unknown objects (that is, JIT-compiled +code). Also changed smc-check=all to smc-check=all-non-file as was done for +RunTest (see 4 above). + +32. Implemented the PCRE2_NO_JIT option for pcre2_match(). + +33. Fix typo that gave a compiler error when JIT not supported. + +34. Fix comment describing the returns from find_fixedlength(). + +35. Fix potential negative index in pcre2test. + +36. Calls to pcre2_get_error_message() with error numbers that are never +returned by PCRE2 functions were returning empty strings. Now the error code +PCRE2_ERROR_BADDATA is returned. A facility has been added to pcre2test to +show the texts for given error numbers (i.e. to call pcre2_get_error_message() +and display what it returns) and a few representative error codes are now +checked in RunTest. + +37. Added "&& !defined(__INTEL_COMPILER)" to the test for __GNUC__ in +pcre2_match.c, in anticipation that this is needed for the same reason it was +recently added to pcrecpp.cc in PCRE1. + +38. Using -o with -M in pcre2grep could cause unnecessary repeated output when +the match extended over a line boundary, as it tried to find more matches "on +the same line" - but it was already over the end. + +39. Allow \C in lookbehinds and DFA matching in UTF-32 mode (by converting it +to the same code as '.' when PCRE2_DOTALL is set). + +40. Fix two clang compiler warnings in pcre2test when only one code unit width +is supported. + +41. Upgrade RunTest to automatically re-run test 2 with a large (64M) stack if +it fails when running the interpreter with a 16M stack (and if changing the +stack size via pcre2test is possible). This avoids having to manually set a +large stack size when testing with clang. + +42. Fix register overwite in JIT when SSE2 acceleration is enabled. + +43. Detect integer overflow in pcre2test pattern and data repetition counts. + +44. In pcre2test, ignore "allcaptures" after DFA matching. + +45. Fix unaligned accesses on x86. Patch by Marc Mutz. + +46. Fix some more clang compiler warnings. + + Version 10.21 12-January-2016 ----------------------------- @@ -371,7 +547,7 @@ space or a #-type comment that was followed by (?-x), which turns off PCRE2_EXTENDED, and there was no subsequent (?x) to turn it on again, pcre2_compile() assumed that (?-x) applied to the whole pattern and consequently mis-compiled it. This bug was found by the LLVM fuzzer. The fix -for this bug means that a setting of any of the (?imsxU) options at the start +for this bug means that a setting of any of the (?imsxJU) options at the start of a pattern is no longer transferred to the options that are returned by PCRE2_INFO_ALLOPTIONS. In fact, this was an anachronism that should have changed when the effects of those options were all moved to compile time. diff --git a/pcre2-10.21/CheckMan b/pcre2-10.22/CheckMan similarity index 100% rename from pcre2-10.21/CheckMan rename to pcre2-10.22/CheckMan diff --git a/pcre2-10.21/CleanTxt b/pcre2-10.22/CleanTxt similarity index 100% rename from pcre2-10.21/CleanTxt rename to pcre2-10.22/CleanTxt diff --git a/pcre2-10.21/Detrail b/pcre2-10.22/Detrail similarity index 100% rename from pcre2-10.21/Detrail rename to pcre2-10.22/Detrail diff --git a/pcre2-10.21/HACKING b/pcre2-10.22/HACKING similarity index 99% rename from pcre2-10.21/HACKING rename to pcre2-10.22/HACKING index 051520c28..883aa64a8 100644 --- a/pcre2-10.21/HACKING +++ b/pcre2-10.22/HACKING @@ -228,6 +228,11 @@ OP_ASSERT_ACCEPT is used when (*ACCEPT) is encountered within an assertion. This ends the assertion, not the entire pattern match. The assertion (?!) is always optimized to OP_FAIL. +OP_ALLANY is used for '.' when PCRE2_DOTALL is set. It is also used for \C in +non-UTF modes and in UTF-32 mode (since one code unit still equals one +character). Another use is for [^] when empty classes are permitted +(PCRE2_ALLOW_EMPTY_CLASS is set). + Backtracking control verbs with optional data --------------------------------------------- @@ -601,4 +606,4 @@ not a real opcode, but is used to check that tables indexed by opcode are the correct length, in order to catch updating errors. Philip Hazel -June 2015 +June 2016 diff --git a/pcre2-10.21/INSTALL b/pcre2-10.22/INSTALL similarity index 100% rename from pcre2-10.21/INSTALL rename to pcre2-10.22/INSTALL diff --git a/pcre2-10.21/LICENCE b/pcre2-10.22/LICENCE similarity index 100% rename from pcre2-10.21/LICENCE rename to pcre2-10.22/LICENCE diff --git a/pcre2-10.21/Makefile.am b/pcre2-10.22/Makefile.am similarity index 99% rename from pcre2-10.21/Makefile.am rename to pcre2-10.22/Makefile.am index 5977ba06b..38f1d41b8 100644 --- a/pcre2-10.21/Makefile.am +++ b/pcre2-10.22/Makefile.am @@ -25,6 +25,7 @@ dist_html_DATA = \ doc/html/pcre2-config.html \ doc/html/pcre2.html \ doc/html/pcre2_callout_enumerate.html \ + doc/html/pcre2_code_copy.html \ doc/html/pcre2_code_free.html \ doc/html/pcre2_compile.html \ doc/html/pcre2_compile_context_copy.html \ @@ -105,6 +106,7 @@ dist_man_MANS = \ doc/pcre2-config.1 \ doc/pcre2.3 \ doc/pcre2_callout_enumerate.3 \ + doc/pcre2_code_copy.3 \ doc/pcre2_code_free.3 \ doc/pcre2_compile.3 \ doc/pcre2_compile_context_copy.3 \ @@ -568,6 +570,7 @@ EXTRA_DIST += \ testdata/greplist \ testdata/grepoutput \ testdata/grepoutput8 \ + testdata/grepoutputC \ testdata/grepoutputN \ testdata/greppatN4 \ testdata/testinput1 \ diff --git a/pcre2-10.21/Makefile.in b/pcre2-10.22/Makefile.in similarity index 99% rename from pcre2-10.21/Makefile.in rename to pcre2-10.22/Makefile.in index fd07c58cb..9aead2f54 100644 --- a/pcre2-10.21/Makefile.in +++ b/pcre2-10.22/Makefile.in @@ -832,6 +832,7 @@ dist_html_DATA = \ doc/html/pcre2-config.html \ doc/html/pcre2.html \ doc/html/pcre2_callout_enumerate.html \ + doc/html/pcre2_code_copy.html \ doc/html/pcre2_code_free.html \ doc/html/pcre2_compile.html \ doc/html/pcre2_compile_context_copy.html \ @@ -912,6 +913,7 @@ dist_man_MANS = \ doc/pcre2-config.1 \ doc/pcre2.3 \ doc/pcre2_callout_enumerate.3 \ + doc/pcre2_code_copy.3 \ doc/pcre2_code_free.3 \ doc/pcre2_compile.3 \ doc/pcre2_compile_context_copy.3 \ @@ -1053,16 +1055,17 @@ EXTRA_DIST = m4/ax_pthread.m4 m4/pcre2_visibility.m4 \ testdata/grepfilelist testdata/grepinput testdata/grepinput3 \ testdata/grepinput8 testdata/grepinputv testdata/grepinputx \ testdata/greplist testdata/grepoutput testdata/grepoutput8 \ - testdata/grepoutputN testdata/greppatN4 testdata/testinput1 \ - testdata/testinput2 testdata/testinput3 testdata/testinput4 \ - testdata/testinput5 testdata/testinput6 testdata/testinput7 \ - testdata/testinput8 testdata/testinput9 testdata/testinput10 \ - testdata/testinput11 testdata/testinput12 testdata/testinput13 \ - testdata/testinput14 testdata/testinput15 testdata/testinput16 \ - testdata/testinput17 testdata/testinput18 testdata/testinput19 \ - testdata/testinput20 testdata/testinput21 testdata/testinput22 \ - testdata/testinput23 testdata/testinputEBC \ - testdata/testoutput1 testdata/testoutput2 testdata/testoutput3 \ + testdata/grepoutputC testdata/grepoutputN testdata/greppatN4 \ + testdata/testinput1 testdata/testinput2 testdata/testinput3 \ + testdata/testinput4 testdata/testinput5 testdata/testinput6 \ + testdata/testinput7 testdata/testinput8 testdata/testinput9 \ + testdata/testinput10 testdata/testinput11 testdata/testinput12 \ + testdata/testinput13 testdata/testinput14 testdata/testinput15 \ + testdata/testinput16 testdata/testinput17 testdata/testinput18 \ + testdata/testinput19 testdata/testinput20 testdata/testinput21 \ + testdata/testinput22 testdata/testinput23 \ + testdata/testinputEBC testdata/testoutput1 \ + testdata/testoutput2 testdata/testoutput3 \ testdata/testoutput3A testdata/testoutput3B \ testdata/testoutput4 testdata/testoutput5 testdata/testoutput6 \ testdata/testoutput7 testdata/testoutput8-16-2 \ diff --git a/pcre2-10.21/NEWS b/pcre2-10.22/NEWS similarity index 83% rename from pcre2-10.21/NEWS rename to pcre2-10.22/NEWS index aaeee5c24..602e32425 100644 --- a/pcre2-10.21/NEWS +++ b/pcre2-10.22/NEWS @@ -1,6 +1,28 @@ News about PCRE2 releases ------------------------- +Version 10.22 29-July-2016 +-------------------------- + +1. ChangeLog has the details of a number of bug fixes. + +2. The POSIX wrapper function regcomp() did not used to support back references +and subroutine calls if called with the REG_NOSUB option. It now does. + +3. A new function, pcre2_code_copy(), is added, to make a copy of a compiled +pattern. + +4. Support for string callouts is added to pcre2grep. + +5. Added the PCRE2_NO_JIT option to pcre2_match(). + +6. The pcre2_get_error_message() function now returns with a negative error +code if the error number it is given is unknown. + +7. Several updates have been made to pcre2test and test scripts (see +ChangeLog). + + Version 10.21 12-January-2016 ----------------------------- diff --git a/pcre2-10.21/NON-AUTOTOOLS-BUILD b/pcre2-10.22/NON-AUTOTOOLS-BUILD similarity index 100% rename from pcre2-10.21/NON-AUTOTOOLS-BUILD rename to pcre2-10.22/NON-AUTOTOOLS-BUILD diff --git a/pcre2-10.21/PrepareRelease b/pcre2-10.22/PrepareRelease similarity index 100% rename from pcre2-10.21/PrepareRelease rename to pcre2-10.22/PrepareRelease diff --git a/pcre2-10.21/README b/pcre2-10.22/README similarity index 98% rename from pcre2-10.21/README rename to pcre2-10.22/README index 48d2ffdd7..03d67f65f 100644 --- a/pcre2-10.21/README +++ b/pcre2-10.22/README @@ -168,15 +168,12 @@ library. They are also documented in the pcre2build man page. built. If you want only the 16-bit or 32-bit library, use --disable-pcre2-8 to disable building the 8-bit library. -. If you want to include support for just-in-time compiling, which can give - large performance improvements on certain platforms, add --enable-jit to the - "configure" command. This support is available only for certain hardware +. If you want to include support for just-in-time (JIT) compiling, which can + give large performance improvements on certain platforms, add --enable-jit to + the "configure" command. This support is available only for certain hardware architectures. If you try to enable it on an unsupported architecture, there will be a compile time error. -. When JIT support is enabled, pcre2grep automatically makes use of it, unless - you add --disable-pcre2grep-jit to the "configure" command. - . If you do not want to make use of the support for UTF-8 Unicode character strings in the 8-bit library, UTF-16 Unicode character strings in the 16-bit library, or UTF-32 Unicode character strings in the 32-bit library, you can @@ -324,6 +321,14 @@ library. They are also documented in the pcre2build man page. running "make" to build PCRE2. There is more information about coverage reporting in the "pcre2build" documentation. +. When JIT support is enabled, pcre2grep automatically makes use of it, unless + you add --disable-pcre2grep-jit to the "configure" command. + +. On non-Windows sytems there is support for calling external scripts during + matching in the pcre2grep command via PCRE2's callout facility with string + arguments. This support can be disabled by adding --disable-pcre2grep-callout + to the "configure" command. + . The pcre2grep program currently supports only 8-bit data files, and so requires the 8-bit PCRE2 library. It is possible to compile pcre2grep to use libz and/or libbz2, in order to read .gz and .bz2 files (respectively), by @@ -840,4 +845,4 @@ The distribution should contain the files listed below. Philip Hazel Email local part: ph10 Email domain: cam.ac.uk -Last updated: 16 October 2015 +Last updated: 01 April 2016 diff --git a/pcre2-10.21/RunGrepTest b/pcre2-10.22/RunGrepTest similarity index 59% rename from pcre2-10.21/RunGrepTest rename to pcre2-10.22/RunGrepTest index 67d672ba3..a3e13120c 100755 --- a/pcre2-10.21/RunGrepTest +++ b/pcre2-10.22/RunGrepTest @@ -34,17 +34,22 @@ fi valgrind= while [ $# -gt 0 ] ; do case $1 in - valgrind) valgrind="valgrind -q --leak-check=no --smc-check=all";; + valgrind) valgrind="valgrind -q --leak-check=no --smc-check=all-non-file";; *) echo "RunGrepTest: Unknown argument $1"; exit 1;; esac shift done +vjs= pcre2grep_version=`$pcre2grep -V` if [ "$valgrind" = "" ] ; then echo "Testing $pcre2grep_version" else echo "Testing $pcre2grep_version using valgrind" + $pcre2test -C jit >/dev/null + if [ $? -ne 0 ]; then + vjs="--suppressions=./testdata/valgrind-jit.supp" + fi fi # Set up a suitable "diff" command for comparison. Some systems have a diff @@ -101,253 +106,253 @@ checkspecial() echo "Testing pcre2grep main features" echo "---------------------------- Test 1 ------------------------------" >testtrygrep -(cd $srcdir; $valgrind $pcre2grep PATTERN ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep PATTERN ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 2 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep '^PATTERN' ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep '^PATTERN' ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 3 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -in PATTERN ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -in PATTERN ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 4 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -ic PATTERN ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -ic PATTERN ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 5 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -in PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -in PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 6 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -inh PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -inh PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 7 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -il PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -il PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 8 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -l PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -l PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 9 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -q PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -q PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 10 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -q NEVER-PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -q NEVER-PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 11 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -vn pattern ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -vn pattern ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 12 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -ix pattern ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -ix pattern ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 13 -----------------------------" >>testtrygrep echo seventeen >testtemp1grep -(cd $srcdir; $valgrind $pcre2grep -f./testdata/greplist -f $builddir/testtemp1grep ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -f./testdata/greplist -f $builddir/testtemp1grep ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 14 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -w pat ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -w pat ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 15 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep 'abc^*' ./testdata/grepinput) 2>>testtrygrep >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep 'abc^*' ./testdata/grepinput) 2>>testtrygrep >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 16 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep abc ./testdata/grepinput ./testdata/nonexistfile) 2>>testtrygrep >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep abc ./testdata/grepinput ./testdata/nonexistfile) 2>>testtrygrep >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 17 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -M 'the\noutput' ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -M 'the\noutput' ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 18 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -Mn '(the\noutput|dog\.\n--)' ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -Mn '(the\noutput|dog\.\n--)' ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 19 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -Mix 'Pattern' ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -Mix 'Pattern' ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 20 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -Mixn 'complete pair\nof lines' ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -Mixn 'complete pair\nof lines' ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 21 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -nA3 'four' ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -nA3 'four' ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 22 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -nB3 'four' ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -nB3 'four' ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 23 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -C3 'four' ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -C3 'four' ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 24 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -A9 'four' ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -A9 'four' ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 25 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -nB9 'four' ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -nB9 'four' ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 26 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -A9 -B9 'four' ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -A9 -B9 'four' ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 27 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -A10 'four' ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -A10 'four' ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 28 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -nB10 'four' ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -nB10 'four' ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 29 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -C12 -B10 'four' ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -C12 -B10 'four' ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 30 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -inB3 'pattern' ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -inB3 'pattern' ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 31 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -inA3 'pattern' ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -inA3 'pattern' ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 32 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -L 'fox' ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -L 'fox' ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 33 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep 'fox' ./testdata/grepnonexist) >>testtrygrep 2>&1 +(cd $srcdir; $valgrind $vjs $pcre2grep 'fox' ./testdata/grepnonexist) >>testtrygrep 2>&1 echo "RC=$?" >>testtrygrep echo "---------------------------- Test 34 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -s 'fox' ./testdata/grepnonexist) >>testtrygrep 2>&1 +(cd $srcdir; $valgrind $vjs $pcre2grep -s 'fox' ./testdata/grepnonexist) >>testtrygrep 2>&1 echo "RC=$?" >>testtrygrep echo "---------------------------- Test 35 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -L -r --include=grepinputx --include grepinput8 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -L -r --include=grepinputx --include grepinput8 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 36 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -L -r --include=grepinput --exclude 'grepinput$' --exclude=grepinput8 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -L -r --include=grepinput --exclude 'grepinput$' --exclude=grepinput8 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 37 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep '^(a+)*\d' ./testdata/grepinput) >>testtrygrep 2>teststderrgrep +(cd $srcdir; $valgrind $vjs $pcre2grep '^(a+)*\d' ./testdata/grepinput) >>testtrygrep 2>teststderrgrep echo "RC=$?" >>testtrygrep echo "======== STDERR ========" >>testtrygrep cat teststderrgrep >>testtrygrep echo "---------------------------- Test 38 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep '>\x00<' ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep '>\x00<' ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 39 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -A1 'before the binary zero' ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -A1 'before the binary zero' ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 40 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -B1 'after the binary zero' ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -B1 'after the binary zero' ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 41 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -B1 -o '\w+ the binary zero' ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -B1 -o '\w+ the binary zero' ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 42 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -B1 -onH '\w+ the binary zero' ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -B1 -onH '\w+ the binary zero' ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 43 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -on 'before|zero|after' ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -on 'before|zero|after' ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 44 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -on -e before -ezero -e after ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -on -e before -ezero -e after ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 45 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -on -f ./testdata/greplist -e binary ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -on -f ./testdata/greplist -e binary ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 46 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -eabc -e '(unclosed' ./testdata/grepinput) 2>>testtrygrep >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -eabc -e '(unclosed' ./testdata/grepinput) 2>>testtrygrep >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 47 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -Fx "AB.VE +(cd $srcdir; $valgrind $vjs $pcre2grep -Fx "AB.VE elephant" ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 48 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -F "AB.VE +(cd $srcdir; $valgrind $vjs $pcre2grep -F "AB.VE elephant" ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 49 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -F -e DATA -e "AB.VE +(cd $srcdir; $valgrind $vjs $pcre2grep -F -e DATA -e "AB.VE elephant" ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 50 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep "^(abc|def|ghi|jkl)" ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep "^(abc|def|ghi|jkl)" ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 51 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -Mv "brown\sfox" ./testdata/grepinputv) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -Mv "brown\sfox" ./testdata/grepinputv) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 52 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --colour=always jumps ./testdata/grepinputv) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep --colour=always jumps ./testdata/grepinputv) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 53 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --file-offsets 'before|zero|after' ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep --file-offsets 'before|zero|after' ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 54 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --line-offsets 'before|zero|after' ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep --line-offsets 'before|zero|after' ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 55 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -f./testdata/greplist --color=always ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -f./testdata/greplist --color=always ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 56 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -c lazy ./testdata/grepinput*) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -c lazy ./testdata/grepinput*) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 57 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -c -l lazy ./testdata/grepinput*) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -c -l lazy ./testdata/grepinput*) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 58 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --regex=PATTERN ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep --regex=PATTERN ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 59 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --regexp=PATTERN ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep --regexp=PATTERN ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 60 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --regex PATTERN ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep --regex PATTERN ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 61 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --regexp PATTERN ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep --regexp PATTERN ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 62 -----------------------------" >>testtrygrep @@ -359,196 +364,208 @@ echo "---------------------------- Test 63 -----------------------------" >>test echo "RC=$?" >>testtrygrep echo "---------------------------- Test 64 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o1 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -o1 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 65 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o2 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -o2 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 66 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o3 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -o3 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 67 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o12 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -o12 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 68 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --only-matching=2 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep --only-matching=2 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 69 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -vn --colour=always pattern ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -vn --colour=always pattern ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 70 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --color=always -M "triple:\t.*\n\n" ./testdata/grepinput3) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep --color=always -M "triple:\t.*\n\n" ./testdata/grepinput3) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 71 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o "^01|^02|^03" ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -o "^01|^02|^03" ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 72 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --color=always "^01|^02|^03" ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep --color=always "^01|^02|^03" ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 73 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o --colour=always "^01|^02|^03" ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -o --colour=always "^01|^02|^03" ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 74 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o "^01|02|^03" ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -o "^01|02|^03" ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 75 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --color=always "^01|02|^03" ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep --color=always "^01|02|^03" ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 76 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o --colour=always "^01|02|^03" ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -o --colour=always "^01|02|^03" ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 77 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o "^01|^02|03" ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -o "^01|^02|03" ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 78 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --color=always "^01|^02|03" ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep --color=always "^01|^02|03" ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 79 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o --colour=always "^01|^02|03" ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -o --colour=always "^01|^02|03" ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 80 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o "\b01|\b02" ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -o "\b01|\b02" ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 81 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --color=always "\\b01|\\b02" ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep --color=always "\\b01|\\b02" ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 82 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o --colour=always "\\b01|\\b02" ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -o --colour=always "\\b01|\\b02" ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 83 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --buffer-size=100 "^a" ./testdata/grepinput3) >>testtrygrep 2>&1 +(cd $srcdir; $valgrind $vjs $pcre2grep --buffer-size=100 "^a" ./testdata/grepinput3) >>testtrygrep 2>&1 echo "RC=$?" >>testtrygrep echo "---------------------------- Test 84 -----------------------------" >>testtrygrep echo testdata/grepinput3 >testtemp1grep -(cd $srcdir; $valgrind $pcre2grep --file-list ./testdata/grepfilelist --file-list $builddir/testtemp1grep "fox|complete|t7") >>testtrygrep 2>&1 +(cd $srcdir; $valgrind $vjs $pcre2grep --file-list ./testdata/grepfilelist --file-list $builddir/testtemp1grep "fox|complete|t7") >>testtrygrep 2>&1 echo "RC=$?" >>testtrygrep echo "---------------------------- Test 85 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --file-list=./testdata/grepfilelist "dolor" ./testdata/grepinput3) >>testtrygrep 2>&1 +(cd $srcdir; $valgrind $vjs $pcre2grep --file-list=./testdata/grepfilelist "dolor" ./testdata/grepinput3) >>testtrygrep 2>&1 echo "RC=$?" >>testtrygrep echo "---------------------------- Test 86 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 +(cd $srcdir; $valgrind $vjs $pcre2grep "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 echo "RC=$?" >>testtrygrep echo "---------------------------- Test 87 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep "cat" ./testdata/grepbinary) >>testtrygrep 2>&1 +(cd $srcdir; $valgrind $vjs $pcre2grep "cat" ./testdata/grepbinary) >>testtrygrep 2>&1 echo "RC=$?" >>testtrygrep echo "---------------------------- Test 88 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -v "cat" ./testdata/grepbinary) >>testtrygrep 2>&1 +(cd $srcdir; $valgrind $vjs $pcre2grep -v "cat" ./testdata/grepbinary) >>testtrygrep 2>&1 echo "RC=$?" >>testtrygrep echo "---------------------------- Test 89 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -I "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 +(cd $srcdir; $valgrind $vjs $pcre2grep -I "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 echo "RC=$?" >>testtrygrep echo "---------------------------- Test 90 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --binary-files=without-match "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 +(cd $srcdir; $valgrind $vjs $pcre2grep --binary-files=without-match "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 echo "RC=$?" >>testtrygrep echo "---------------------------- Test 91 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -a "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 +(cd $srcdir; $valgrind $vjs $pcre2grep -a "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 echo "RC=$?" >>testtrygrep echo "---------------------------- Test 92 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --binary-files=text "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 +(cd $srcdir; $valgrind $vjs $pcre2grep --binary-files=text "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 echo "RC=$?" >>testtrygrep echo "---------------------------- Test 93 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --text "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 +(cd $srcdir; $valgrind $vjs $pcre2grep --text "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 echo "RC=$?" >>testtrygrep echo "---------------------------- Test 94 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -L -r --include=grepinputx --include grepinput8 'fox' ./testdata/grepinput* | sort) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -L -r --include=grepinputx --include grepinput8 'fox' ./testdata/grepinput* | sort) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 95 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --file-list ./testdata/grepfilelist --exclude grepinputv "fox|complete") >>testtrygrep 2>&1 +(cd $srcdir; $valgrind $vjs $pcre2grep --file-list ./testdata/grepfilelist --exclude grepinputv "fox|complete") >>testtrygrep 2>&1 echo "RC=$?" >>testtrygrep echo "---------------------------- Test 96 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -L -r --include-dir=testdata --exclude '^(?!grepinput)' 'fox' ./test* | sort) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -L -r --include-dir=testdata --exclude '^(?!grepinput)' 'fox' ./test* | sort) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 97 -----------------------------" >>testtrygrep echo "grepinput$" >testtemp1grep echo "grepinput8" >>testtemp1grep -(cd $srcdir; $valgrind $pcre2grep -L -r --include=grepinput --exclude-from $builddir/testtemp1grep --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -L -r --include=grepinput --exclude-from $builddir/testtemp1grep --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 98 -----------------------------" >>testtrygrep echo "grepinput$" >testtemp1grep echo "grepinput8" >>testtemp1grep -(cd $srcdir; $valgrind $pcre2grep -L -r --exclude=grepinput3 --include=grepinput --exclude-from $builddir/testtemp1grep --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -L -r --exclude=grepinput3 --include=grepinput --exclude-from $builddir/testtemp1grep --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 99 -----------------------------" >>testtrygrep echo "grepinput$" >testtemp1grep echo "grepinput8" >testtemp2grep -(cd $srcdir; $valgrind $pcre2grep -L -r --include grepinput --exclude-from $builddir/testtemp1grep --exclude-from=$builddir/testtemp2grep --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -L -r --include grepinput --exclude-from $builddir/testtemp1grep --exclude-from=$builddir/testtemp2grep --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 100 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -Ho2 --only-matching=1 -o3 '(\w+) binary (\w+)(\.)?' ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -Ho2 --only-matching=1 -o3 '(\w+) binary (\w+)(\.)?' ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 101 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -o3 -Ho2 -o12 --only-matching=1 -o3 --colour=always --om-separator='|' '(\w+) binary (\w+)(\.)?' ./testdata/grepinput) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -o3 -Ho2 -o12 --only-matching=1 -o3 --colour=always --om-separator='|' '(\w+) binary (\w+)(\.)?' ./testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 102 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -n "^$" ./testdata/grepinput3) >>testtrygrep 2>&1 +(cd $srcdir; $valgrind $vjs $pcre2grep -n "^$" ./testdata/grepinput3) >>testtrygrep 2>&1 echo "RC=$?" >>testtrygrep echo "---------------------------- Test 103 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --only-matching "^$" ./testdata/grepinput3) >>testtrygrep 2>&1 +(cd $srcdir; $valgrind $vjs $pcre2grep --only-matching "^$" ./testdata/grepinput3) >>testtrygrep 2>&1 echo "RC=$?" >>testtrygrep echo "---------------------------- Test 104 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -n --only-matching "^$" ./testdata/grepinput3) >>testtrygrep 2>&1 +(cd $srcdir; $valgrind $vjs $pcre2grep -n --only-matching "^$" ./testdata/grepinput3) >>testtrygrep 2>&1 echo "RC=$?" >>testtrygrep echo "---------------------------- Test 105 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep --colour=always "ipsum|" ./testdata/grepinput3) >>testtrygrep 2>&1 +(cd $srcdir; $valgrind $vjs $pcre2grep --colour=always "ipsum|" ./testdata/grepinput3) >>testtrygrep 2>&1 echo "RC=$?" >>testtrygrep echo "---------------------------- Test 106 -----------------------------" >>testtrygrep -(cd $srcdir; echo "a" | $valgrind $pcre2grep -M "|a" ) >>testtrygrep 2>&1 +(cd $srcdir; echo "a" | $valgrind $vjs $pcre2grep -M "|a" ) >>testtrygrep 2>&1 echo "RC=$?" >>testtrygrep echo "---------------------------- Test 107 -----------------------------" >>testtrygrep echo "a" >testtemp1grep echo "aaaaa" >>testtemp1grep -(cd $srcdir; $valgrind $pcre2grep --line-offsets '(?<=\Ka)' $builddir/testtemp1grep) >>testtrygrep 2>&1 +(cd $srcdir; $valgrind $vjs $pcre2grep --line-offsets '(?<=\Ka)' $builddir/testtemp1grep) >>testtrygrep 2>&1 echo "RC=$?" >>testtrygrep echo "---------------------------- Test 108 ------------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -lq PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -lq PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test 109 -----------------------------" >>testtrygrep -(cd $srcdir; $valgrind $pcre2grep -cq lazy ./testdata/grepinput*) >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -cq lazy ./testdata/grepinput*) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 110 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep --om-separator / -Mo0 -o1 -o2 'match (\d+):\n (.)\n' testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 111 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep --line-offsets -M 'match (\d+):\n (.)\n' testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 112 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep --file-offsets -M 'match (\d+):\n (.)\n' testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep # Now compare the results. @@ -563,15 +580,15 @@ if [ $utf8 -ne 0 ] ; then echo "Testing pcre2grep UTF-8 features" echo "---------------------------- Test U1 ------------------------------" >testtrygrep - (cd $srcdir; $valgrind $pcre2grep -n -u --newline=any "^X" ./testdata/grepinput8) >>testtrygrep + (cd $srcdir; $valgrind $vjs $pcre2grep -n -u --newline=any "^X" ./testdata/grepinput8) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test U2 ------------------------------" >>testtrygrep - (cd $srcdir; $valgrind $pcre2grep -n -u -C 3 --newline=any "Match" ./testdata/grepinput8) >>testtrygrep + (cd $srcdir; $valgrind $vjs $pcre2grep -n -u -C 3 --newline=any "Match" ./testdata/grepinput8) >>testtrygrep echo "RC=$?" >>testtrygrep echo "---------------------------- Test U3 ------------------------------" >>testtrygrep - (cd $srcdir; $valgrind $pcre2grep --line-offsets -u --newline=any '(?<=\K\x{17f})' ./testdata/grepinput8) >>testtrygrep + (cd $srcdir; $valgrind $vjs $pcre2grep --line-offsets -u --newline=any '(?<=\K\x{17f})' ./testdata/grepinput8) >>testtrygrep echo "RC=$?" >>testtrygrep $cf $srcdir/testdata/grepoutput8 testtrygrep @@ -593,27 +610,38 @@ echo "Testing pcre2grep newline settings" printf "abc\rdef\r\nghi\njkl" >testNinputgrep printf "%c--------------------------- Test N1 ------------------------------\r\n" - >testtrygrep -$valgrind $pcre2grep -n -N CR "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep +$valgrind $vjs $pcre2grep -n -N CR "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep printf "%c--------------------------- Test N2 ------------------------------\r\n" - >>testtrygrep -$valgrind $pcre2grep -n --newline=crlf "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep +$valgrind $vjs $pcre2grep -n --newline=crlf "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep printf "%c--------------------------- Test N3 ------------------------------\r\n" - >>testtrygrep pattern=`printf 'def\rjkl'` -$valgrind $pcre2grep -n --newline=cr -F "$pattern" testNinputgrep >>testtrygrep +$valgrind $vjs $pcre2grep -n --newline=cr -F "$pattern" testNinputgrep >>testtrygrep printf "%c--------------------------- Test N4 ------------------------------\r\n" - >>testtrygrep -$valgrind $pcre2grep -n --newline=crlf -F -f $srcdir/testdata/greppatN4 testNinputgrep >>testtrygrep +$valgrind $vjs $pcre2grep -n --newline=crlf -F -f $srcdir/testdata/greppatN4 testNinputgrep >>testtrygrep printf "%c--------------------------- Test N5 ------------------------------\r\n" - >>testtrygrep -$valgrind $pcre2grep -n --newline=any "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep +$valgrind $vjs $pcre2grep -n --newline=any "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep printf "%c--------------------------- Test N6 ------------------------------\r\n" - >>testtrygrep -$valgrind $pcre2grep -n --newline=anycrlf "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep +$valgrind $vjs $pcre2grep -n --newline=anycrlf "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep $cf $srcdir/testdata/grepoutputN testtrygrep if [ $? != 0 ] ; then exit 1; fi +# If pcre2grep supports script callouts, run some tests on them. + +if $valgrind $vjs $pcre2grep --help | $valgrind $vjs $pcre2grep -q 'Callout scripts in patterns are supported'; then + echo "Testing pcre2grep script callouts" + $valgrind $vjs $pcre2grep '(T)(..(.))(?C"/bin/echo|Arg1: [$1] [$2] [$3]|Arg2: $|${1}$| ($4) ($14) ($0)")()' $srcdir/testdata/grepinputv >testtrygrep + $valgrind $vjs $pcre2grep '(T)(..(.))()()()()()()()(..)(?C"/bin/echo|Arg1: [$11] [${11}]")' $srcdir/testdata/grepinputv >>testtrygrep + $cf $srcdir/testdata/grepoutputC testtrygrep + if [ $? != 0 ] ; then exit 1; fi +else + echo "Script callouts are not supported" +fi # Finally, some tests to exercise code that is not tested above, just to be # sure that it runs OK. Doing this improves the coverage statistics. The output diff --git a/pcre2-10.21/RunTest b/pcre2-10.22/RunTest similarity index 93% rename from pcre2-10.21/RunTest rename to pcre2-10.22/RunTest index 36dc638ed..d0eec77e0 100755 --- a/pcre2-10.21/RunTest +++ b/pcre2-10.22/RunTest @@ -53,7 +53,7 @@ title0="Test 0: Unchecked pcre2test argument tests (to improve coverage)" title1="Test 1: Main non-UTF, non-UCP functionality (compatible with Perl >= 5.10)" -title2="Test 2: API, errors, internals, and non-Perl stuff" +title2="Test 2: API, errors, internals and non-Perl stuff" title3="Test 3: Locale-specific features" title4A="Test 4: UTF" title4B=" and Unicode property support (compatible with Perl >= 5.10)" @@ -74,7 +74,7 @@ title16="Test 16: JIT-specific features when JIT is not available" title17="Test 17: JIT-specific features when JIT is available" title18="Test 18: Tests of the POSIX interface, excluding UTF/UCP" title19="Test 19: Tests of the POSIX interface with UTF/UCP" -title20="Test 20: Serialization tests" +title20="Test 20: Serialization and code copy tests" title21="Test 21: \C tests without UTF (supported for DFA matching)" title22="Test 22: \C tests with UTF (not supported for DFA matching)" title23="Test 23: \C disabled test" @@ -265,8 +265,8 @@ while [ $# -gt 0 ] ; do bigstack|-bigstack) bigstack=yes;; nojit|-nojit) nojit=yes;; sim|-sim) shift; sim=$1;; - valgrind|-valgrind) valgrind="valgrind --tool=memcheck -q --smc-check=all";; - valgrind-log|-valgrind-log) valgrind="valgrind --tool=memcheck --num-callers=30 --leak-check=no --error-limit=no --smc-check=all --log-file=report.%p ";; + valgrind|-valgrind) valgrind="valgrind --tool=memcheck -q --smc-check=all-non-file";; + valgrind-log|-valgrind-log) valgrind="valgrind --tool=memcheck --num-callers=30 --leak-check=no --error-limit=no --smc-check=all-non-file --log-file=report.%p ";; ~*) if expr "$1" : '~[0-9][0-9]*$' >/dev/null; then skip="$skip `expr "$1" : '~\([0-9]*\)*$'`" @@ -310,9 +310,12 @@ fi # If it is possible to set the system stack size, arrange to set a value for # test 2, which needs more than the even the Linux default when PCRE2 has been -# compiled by gcc with -fsanitize=address. When the compiler is clang, sanitize -# options require an even bigger stack for test 2, and an increased stack for -# some of the other tests. +# compiled by gcc with -fsanitize=address. If "bigstack" is on the command +# line, set even bigger numbers. When the compiler is clang, sanitize options +# require an even bigger stack for test 2, and an increased stack for some of +# the other tests. Test 2 now has code to automatically try again with a 64M +# stack if it crashes when test2stack is "-S 16" when matching with the +# interpreter. $sim ./pcre2test -S 1 /dev/null /dev/null if [ $? -eq 0 ] ; then @@ -499,15 +502,32 @@ for bmode in "$test8" "$test16" "$test32"; do for opt in "" $jitopt; do $sim $valgrind ${opt:+$vjs} ./pcre2test -q $test2stack $bmode $opt $testdata/testinput2 testtry if [ $? = 0 ] ; then + $sim $valgrind ${opt:+$vjs} ./pcre2test -q $bmode $opt -error -63,-62,-2,-1,0,100,188,189 >>testtry checkresult $? 2 "$opt" else echo " " - echo "** Test 2 requires a lot of stack. If it has crashed with a" - echo "** segmentation fault, it may be that you do not have enough" - echo "** stack available by default. Please see the 'pcre2stack' man" - echo "** page for a discussion of PCRE2's stack usage." + echo "** Test 2, when run under the interpreter, requires a lot of stack." + echo "** If it has crashed with a segmentation fault, it may be that you" + echo "** do not have enough stack available by default. Please see the" + echo "** 'pcre2stack' man page for a discussion of PCRE2's stack usage." + if [ "$test2stack" != "-S 16" -o "$opt" != "" ]; then + echo " " + exit 1 + fi echo " " - exit 1 + echo "** Trying again with an increased stack size." + echo " " + echo $title2 "(excluding UTF-$bits) (64M stack)" + $sim $valgrind ${opt:+$vjs} ./pcre2test -q -S 64 $bmode $opt $testdata/testinput2 testtry + if [ $? = 0 ] ; then + $sim $valgrind ${opt:+$vjs} ./pcre2test -q $bmode $opt -error -63,-62,-2,-1,0,100,188,189 >>testtry + checkresult $? 2 "$opt" + else + echo " " + echo "** Failed with an increased stack size. Tests abandoned." + echo " " + exit 1 + fi fi done fi diff --git a/pcre2-10.21/aclocal.m4 b/pcre2-10.22/aclocal.m4 similarity index 99% rename from pcre2-10.21/aclocal.m4 rename to pcre2-10.22/aclocal.m4 index 795657e89..d8d43fb0d 100644 --- a/pcre2-10.21/aclocal.m4 +++ b/pcre2-10.22/aclocal.m4 @@ -21,7 +21,7 @@ If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -dnl serial 11 (pkg-config-0.29) +dnl serial 11 (pkg-config-0.29.1) dnl dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson @@ -63,7 +63,7 @@ dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], -[m4_define([PKG_MACROS_VERSION], [0.29]) +[m4_define([PKG_MACROS_VERSION], [0.29.1]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ diff --git a/pcre2-10.21/ar-lib b/pcre2-10.22/ar-lib similarity index 100% rename from pcre2-10.21/ar-lib rename to pcre2-10.22/ar-lib diff --git a/pcre2-10.21/cmake/COPYING-CMAKE-SCRIPTS b/pcre2-10.22/cmake/COPYING-CMAKE-SCRIPTS similarity index 100% rename from pcre2-10.21/cmake/COPYING-CMAKE-SCRIPTS rename to pcre2-10.22/cmake/COPYING-CMAKE-SCRIPTS diff --git a/pcre2-10.21/cmake/FindEditline.cmake b/pcre2-10.22/cmake/FindEditline.cmake similarity index 100% rename from pcre2-10.21/cmake/FindEditline.cmake rename to pcre2-10.22/cmake/FindEditline.cmake diff --git a/pcre2-10.21/cmake/FindPackageHandleStandardArgs.cmake b/pcre2-10.22/cmake/FindPackageHandleStandardArgs.cmake similarity index 100% rename from pcre2-10.21/cmake/FindPackageHandleStandardArgs.cmake rename to pcre2-10.22/cmake/FindPackageHandleStandardArgs.cmake diff --git a/pcre2-10.21/cmake/FindReadline.cmake b/pcre2-10.22/cmake/FindReadline.cmake similarity index 100% rename from pcre2-10.21/cmake/FindReadline.cmake rename to pcre2-10.22/cmake/FindReadline.cmake diff --git a/pcre2-10.21/compile b/pcre2-10.22/compile similarity index 100% rename from pcre2-10.21/compile rename to pcre2-10.22/compile diff --git a/pcre2-10.21/config-cmake.h.in b/pcre2-10.22/config-cmake.h.in similarity index 100% rename from pcre2-10.21/config-cmake.h.in rename to pcre2-10.22/config-cmake.h.in diff --git a/pcre2-10.21/config.guess b/pcre2-10.22/config.guess similarity index 100% rename from pcre2-10.21/config.guess rename to pcre2-10.22/config.guess diff --git a/pcre2-10.21/config.sub b/pcre2-10.22/config.sub similarity index 100% rename from pcre2-10.21/config.sub rename to pcre2-10.22/config.sub diff --git a/pcre2-10.21/configure b/pcre2-10.22/configure similarity index 99% rename from pcre2-10.21/configure rename to pcre2-10.22/configure index ad2696549..622da4fa8 100755 --- a/pcre2-10.21/configure +++ b/pcre2-10.22/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for PCRE2 10.21. +# Generated by GNU Autoconf 2.69 for PCRE2 10.22. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -587,8 +587,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='PCRE2' PACKAGE_TARNAME='pcre2' -PACKAGE_VERSION='10.21' -PACKAGE_STRING='PCRE2 10.21' +PACKAGE_VERSION='10.22' +PACKAGE_STRING='PCRE2 10.22' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -825,6 +825,7 @@ enable_pcre2_32 enable_debug enable_jit enable_pcre2grep_jit +enable_pcre2grep_callout enable_rebuild_chartables enable_unicode enable_newline_is_cr @@ -1406,7 +1407,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures PCRE2 10.21 to adapt to many kinds of systems. +\`configure' configures PCRE2 10.22 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1476,7 +1477,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of PCRE2 10.21:";; + short | recursive ) echo "Configuration of PCRE2 10.22:";; esac cat <<\_ACEOF @@ -1505,6 +1506,8 @@ Optional Features: --enable-debug enable debugging code --enable-jit enable Just-In-Time compiling support --disable-pcre2grep-jit disable JIT support in pcre2grep + --disable-pcre2grep-callout + disable callout script support in pcre2grep --enable-rebuild-chartables rebuild character tables in current locale --disable-unicode disable Unicode support @@ -1645,7 +1648,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -PCRE2 configure 10.21 +PCRE2 configure 10.22 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2140,7 +2143,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by PCRE2 $as_me 10.21, which was +It was created by PCRE2 $as_me 10.22, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3004,7 +3007,7 @@ fi # Define the identity of the package. PACKAGE='pcre2' - VERSION='10.21' + VERSION='10.22' cat >>confdefs.h <<_ACEOF @@ -13628,9 +13631,9 @@ _ACEOF # Versioning PCRE2_MAJOR="10" -PCRE2_MINOR="21" +PCRE2_MINOR="22" PCRE2_PRERELEASE="" -PCRE2_DATE="2016-01-12" +PCRE2_DATE="2016-07-29" if test "$PCRE2_MINOR" = "08" -o "$PCRE2_MINOR" = "09" then @@ -13738,6 +13741,20 @@ else fi +# Handle --disable-pcre2grep-callout (enabled by default) but not supported +# for Windows. +if test "$HAVE_WINDOWS_H" != "1"; then + # Check whether --enable-pcre2grep-callout was given. +if test "${enable_pcre2grep_callout+set}" = set; then : + enableval=$enable_pcre2grep_callout; +else + enable_pcre2grep_callout=yes +fi + +else + enable_pcre2grep_callout=no +fi + # Handle --enable-rebuild-chartables # Check whether --enable-rebuild-chartables was given. if test "${enable_rebuild_chartables+set}" = set; then : @@ -14154,6 +14171,18 @@ fi done +for ac_header in sys/wait.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/wait.h" "ac_cv_header_sys_wait_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_wait_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_WAIT_H 1 +_ACEOF + HAVE_SYS_WAIT_H=1 +fi + +done + # Conditional compilation if test "x$enable_pcre2_8" = "xyes"; then @@ -15275,6 +15304,23 @@ $as_echo "#define SUPPORT_PCRE2GREP_JIT /**/" >>confdefs.h fi +# Currently pcre2grep callout string is not supported under Windows. + +if test "$enable_pcre2grep_callout" = "yes"; then + if test "$HAVE_WINDOWS_H" != "1"; then + if test "$HAVE_SYS_WAIT_H" != "1"; then + as_fn_error $? "Callout script support needs sys/wait.h." "$LINENO" 5 + fi + +$as_echo "#define SUPPORT_PCRE2GREP_CALLOUT /**/" >>confdefs.h + + else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Callout script support is not available for Windows: disabled" >&5 +$as_echo "$as_me: WARNING: Callout script support is not available for Windows: disabled" >&2;} + enable_pcre2grep_callout=no + fi +fi + if test "$enable_unicode" = "yes"; then $as_echo "#define SUPPORT_UNICODE /**/" >>confdefs.h @@ -15418,16 +15464,16 @@ esac # are m4 variables, assigned above. EXTRA_LIBPCRE2_8_LDFLAGS="$EXTRA_LIBPCRE2_8_LDFLAGS \ - $NO_UNDEFINED -version-info 3:0:3" + $NO_UNDEFINED -version-info 4:0:4" EXTRA_LIBPCRE2_16_LDFLAGS="$EXTRA_LIBPCRE2_16_LDFLAGS \ - $NO_UNDEFINED -version-info 3:0:3" + $NO_UNDEFINED -version-info 4:0:4" EXTRA_LIBPCRE2_32_LDFLAGS="$EXTRA_LIBPCRE2_32_LDFLAGS \ - $NO_UNDEFINED -version-info 3:0:3" + $NO_UNDEFINED -version-info 4:0:4" EXTRA_LIBPCRE2_POSIX_LDFLAGS="$EXTRA_LIBPCRE2_POSIX_LDFLAGS \ - $NO_UNDEFINED -version-info 0:1:0" + $NO_UNDEFINED -version-info 1:0:0" @@ -16474,7 +16520,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by PCRE2 $as_me 10.21, which was +This file was extended by PCRE2 $as_me 10.22, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -16540,7 +16586,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -PCRE2 config.status 10.21 +PCRE2 config.status 10.22 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -18284,6 +18330,7 @@ $PACKAGE-$VERSION configuration summary: Build shared libs ............... : ${enable_shared} Build static libs ............... : ${enable_static} Use JIT in pcre2grep ............ : ${enable_pcre2grep_jit} + Enable callouts in pcre2grep .... : ${enable_pcre2grep_callout} Buffer size for pcre2grep ....... : ${with_pcre2grep_bufsize} Link pcre2grep with libz ........ : ${enable_pcre2grep_libz} Link pcre2grep with libbz2 ...... : ${enable_pcre2grep_libbz2} diff --git a/pcre2-10.21/configure.ac b/pcre2-10.22/configure.ac similarity index 96% rename from pcre2-10.21/configure.ac rename to pcre2-10.22/configure.ac index 32307644e..c8a09ac15 100644 --- a/pcre2-10.21/configure.ac +++ b/pcre2-10.22/configure.ac @@ -9,18 +9,18 @@ dnl The PCRE2_PRERELEASE feature is for identifying release candidates. It might dnl be defined as -RC2, for example. For real releases, it should be empty. m4_define(pcre2_major, [10]) -m4_define(pcre2_minor, [21]) +m4_define(pcre2_minor, [22]) m4_define(pcre2_prerelease, []) -m4_define(pcre2_date, [2016-01-12]) +m4_define(pcre2_date, [2016-07-29]) # NOTE: The CMakeLists.txt file searches for the above variables in the first # 50 lines of this file. Please update that if the variables above are moved. # Libtool shared library interface versions (current:revision:age) -m4_define(libpcre2_8_version, [3:0:3]) -m4_define(libpcre2_16_version, [3:0:3]) -m4_define(libpcre2_32_version, [3:0:3]) -m4_define(libpcre2_posix_version, [0:1:0]) +m4_define(libpcre2_8_version, [4:0:4]) +m4_define(libpcre2_16_version, [4:0:4]) +m4_define(libpcre2_32_version, [4:0:4]) +m4_define(libpcre2_posix_version, [1:0:0]) AC_PREREQ(2.57) AC_INIT(PCRE2, pcre2_major.pcre2_minor[]pcre2_prerelease, , pcre2) @@ -154,6 +154,17 @@ AC_ARG_ENABLE(pcre2grep-jit, [disable JIT support in pcre2grep]), , enable_pcre2grep_jit=yes) +# Handle --disable-pcre2grep-callout (enabled by default) but not supported +# for Windows. +if test "$HAVE_WINDOWS_H" != "1"; then + AC_ARG_ENABLE(pcre2grep-callout, + AS_HELP_STRING([--disable-pcre2grep-callout], + [disable callout script support in pcre2grep]), + , enable_pcre2grep_callout=yes) +else + enable_pcre2grep_callout=no +fi + # Handle --enable-rebuild-chartables AC_ARG_ENABLE(rebuild-chartables, AS_HELP_STRING([--enable-rebuild-chartables], @@ -398,6 +409,7 @@ sure both macros are undefined; an emulation function will then be used. */]) AC_HEADER_STDC AC_CHECK_HEADERS(limits.h sys/types.h sys/stat.h dirent.h) AC_CHECK_HEADERS([windows.h], [HAVE_WINDOWS_H=1]) +AC_CHECK_HEADERS([sys/wait.h], [HAVE_SYS_WAIT_H=1]) # Conditional compilation AM_CONDITIONAL(WITH_PCRE2_8, test "x$enable_pcre2_8" = "xyes") @@ -552,6 +564,21 @@ if test "$enable_pcre2grep_jit" = "yes"; then Define to any value to enable JIT support in pcre2grep.]) fi +# Currently pcre2grep callout string is not supported under Windows. + +if test "$enable_pcre2grep_callout" = "yes"; then + if test "$HAVE_WINDOWS_H" != "1"; then + if test "$HAVE_SYS_WAIT_H" != "1"; then + AC_MSG_ERROR([Callout script support needs sys/wait.h.]) + fi + AC_DEFINE([SUPPORT_PCRE2GREP_CALLOUT], [], [ + Define to any value to enable callout script support in pcre2grep.]) + else + AC_MSG_WARN([Callout script support is not available for Windows: disabled]) + enable_pcre2grep_callout=no + fi +fi + if test "$enable_unicode" = "yes"; then AC_DEFINE([SUPPORT_UNICODE], [], [ Define to any value to enable support for Unicode and UTF encoding. @@ -914,6 +941,7 @@ $PACKAGE-$VERSION configuration summary: Build shared libs ............... : ${enable_shared} Build static libs ............... : ${enable_static} Use JIT in pcre2grep ............ : ${enable_pcre2grep_jit} + Enable callouts in pcre2grep .... : ${enable_pcre2grep_callout} Buffer size for pcre2grep ....... : ${with_pcre2grep_bufsize} Link pcre2grep with libz ........ : ${enable_pcre2grep_libz} Link pcre2grep with libbz2 ...... : ${enable_pcre2grep_libbz2} diff --git a/pcre2-10.21/depcomp b/pcre2-10.22/depcomp similarity index 100% rename from pcre2-10.21/depcomp rename to pcre2-10.22/depcomp diff --git a/pcre2-10.21/install-sh b/pcre2-10.22/install-sh similarity index 100% rename from pcre2-10.21/install-sh rename to pcre2-10.22/install-sh diff --git a/pcre2-10.21/libpcre2-16.pc.in b/pcre2-10.22/libpcre2-16.pc.in similarity index 100% rename from pcre2-10.21/libpcre2-16.pc.in rename to pcre2-10.22/libpcre2-16.pc.in diff --git a/pcre2-10.21/libpcre2-32.pc.in b/pcre2-10.22/libpcre2-32.pc.in similarity index 100% rename from pcre2-10.21/libpcre2-32.pc.in rename to pcre2-10.22/libpcre2-32.pc.in diff --git a/pcre2-10.21/libpcre2-8.pc.in b/pcre2-10.22/libpcre2-8.pc.in similarity index 100% rename from pcre2-10.21/libpcre2-8.pc.in rename to pcre2-10.22/libpcre2-8.pc.in diff --git a/pcre2-10.21/libpcre2-posix.pc.in b/pcre2-10.22/libpcre2-posix.pc.in similarity index 100% rename from pcre2-10.21/libpcre2-posix.pc.in rename to pcre2-10.22/libpcre2-posix.pc.in diff --git a/pcre2-10.21/ltmain.sh b/pcre2-10.22/ltmain.sh similarity index 100% rename from pcre2-10.21/ltmain.sh rename to pcre2-10.22/ltmain.sh diff --git a/pcre2-10.21/m4/ax_pthread.m4 b/pcre2-10.22/m4/ax_pthread.m4 similarity index 100% rename from pcre2-10.21/m4/ax_pthread.m4 rename to pcre2-10.22/m4/ax_pthread.m4 diff --git a/pcre2-10.21/m4/libtool.m4 b/pcre2-10.22/m4/libtool.m4 similarity index 100% rename from pcre2-10.21/m4/libtool.m4 rename to pcre2-10.22/m4/libtool.m4 diff --git a/pcre2-10.21/m4/ltoptions.m4 b/pcre2-10.22/m4/ltoptions.m4 similarity index 100% rename from pcre2-10.21/m4/ltoptions.m4 rename to pcre2-10.22/m4/ltoptions.m4 diff --git a/pcre2-10.21/m4/ltsugar.m4 b/pcre2-10.22/m4/ltsugar.m4 similarity index 100% rename from pcre2-10.21/m4/ltsugar.m4 rename to pcre2-10.22/m4/ltsugar.m4 diff --git a/pcre2-10.21/m4/ltversion.m4 b/pcre2-10.22/m4/ltversion.m4 similarity index 100% rename from pcre2-10.21/m4/ltversion.m4 rename to pcre2-10.22/m4/ltversion.m4 diff --git a/pcre2-10.21/m4/lt~obsolete.m4 b/pcre2-10.22/m4/lt~obsolete.m4 similarity index 100% rename from pcre2-10.21/m4/lt~obsolete.m4 rename to pcre2-10.22/m4/lt~obsolete.m4 diff --git a/pcre2-10.21/m4/pcre2_visibility.m4 b/pcre2-10.22/m4/pcre2_visibility.m4 similarity index 100% rename from pcre2-10.21/m4/pcre2_visibility.m4 rename to pcre2-10.22/m4/pcre2_visibility.m4 diff --git a/pcre2-10.21/missing b/pcre2-10.22/missing similarity index 100% rename from pcre2-10.21/missing rename to pcre2-10.22/missing diff --git a/pcre2-10.21/pcre2-config.in b/pcre2-10.22/pcre2-config.in similarity index 100% rename from pcre2-10.21/pcre2-config.in rename to pcre2-10.22/pcre2-config.in diff --git a/pcre2-10.21/perltest.sh b/pcre2-10.22/perltest.sh similarity index 100% rename from pcre2-10.21/perltest.sh rename to pcre2-10.22/perltest.sh diff --git a/pcre2-10.21/src/config.h.generic b/pcre2-10.22/src/config.h.generic similarity index 97% rename from pcre2-10.21/src/config.h.generic rename to pcre2-10.22/src/config.h.generic index 744f19898..8a71be01e 100644 --- a/pcre2-10.21/src/config.h.generic +++ b/pcre2-10.22/src/config.h.generic @@ -111,6 +111,9 @@ sure both macros are undefined; an emulation function will then be used. */ /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_TYPES_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_WAIT_H */ + /* Define to 1 if you have the header file. */ /* #undef HAVE_UNISTD_H */ @@ -203,7 +206,7 @@ sure both macros are undefined; an emulation function will then be used. */ #define PACKAGE_NAME "PCRE2" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "PCRE2 10.21" +#define PACKAGE_STRING "PCRE2 10.22" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "pcre2" @@ -212,7 +215,7 @@ sure both macros are undefined; an emulation function will then be used. */ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "10.21" +#define PACKAGE_VERSION "10.22" /* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested parentheses (of any kind) in a pattern. This limits the amount of system @@ -271,6 +274,9 @@ sure both macros are undefined; an emulation function will then be used. */ is able to handle .gz files. */ /* #undef SUPPORT_LIBZ */ +/* Define to any value to enable callout script support in pcre2grep. */ +/* #undef SUPPORT_PCRE2GREP_CALLOUT */ + /* Define to any value to enable JIT support in pcre2grep. */ /* #undef SUPPORT_PCRE2GREP_JIT */ @@ -293,7 +299,7 @@ sure both macros are undefined; an emulation function will then be used. */ /* #undef SUPPORT_VALGRIND */ /* Version number of package */ -#define VERSION "10.21" +#define VERSION "10.22" /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ diff --git a/pcre2-10.21/src/config.h.in b/pcre2-10.22/src/config.h.in similarity index 98% rename from pcre2-10.21/src/config.h.in rename to pcre2-10.22/src/config.h.in index e55d0a048..d4821af94 100644 --- a/pcre2-10.21/src/config.h.in +++ b/pcre2-10.22/src/config.h.in @@ -111,6 +111,9 @@ sure both macros are undefined; an emulation function will then be used. */ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_WAIT_H + /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H @@ -262,6 +265,9 @@ sure both macros are undefined; an emulation function will then be used. */ is able to handle .gz files. */ #undef SUPPORT_LIBZ +/* Define to any value to enable callout script support in pcre2grep. */ +#undef SUPPORT_PCRE2GREP_CALLOUT + /* Define to any value to enable JIT support in pcre2grep. */ #undef SUPPORT_PCRE2GREP_JIT diff --git a/pcre2-10.21/src/dftables.c b/pcre2-10.22/src/dftables.c similarity index 100% rename from pcre2-10.21/src/dftables.c rename to pcre2-10.22/src/dftables.c diff --git a/pcre2-10.21/src/pcre2.h.generic b/pcre2-10.22/src/pcre2.h.generic similarity index 98% rename from pcre2-10.21/src/pcre2.h.generic rename to pcre2-10.22/src/pcre2.h.generic index 7f9ba4f19..20d221b80 100644 --- a/pcre2-10.21/src/pcre2.h.generic +++ b/pcre2-10.22/src/pcre2.h.generic @@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE. /* The current PCRE version information. */ #define PCRE2_MAJOR 10 -#define PCRE2_MINOR 21 +#define PCRE2_MINOR 22 #define PCRE2_PRERELEASE -#define PCRE2_DATE 2016-01-12 +#define PCRE2_DATE 2016-07-29 /* When an application links to a PCRE DLL in Windows, the symbols that are imported have to be identified as such. When building PCRE2, the appropriate @@ -146,7 +146,8 @@ sanity checks). */ #define PCRE2_DFA_RESTART 0x00000040u #define PCRE2_DFA_SHORTEST 0x00000080u -/* These are additional options for pcre2_substitute(). */ +/* These are additional options for pcre2_substitute(), which passes any others +through to pcre2_match(). */ #define PCRE2_SUBSTITUTE_GLOBAL 0x00000100u #define PCRE2_SUBSTITUTE_EXTENDED 0x00000200u @@ -154,6 +155,11 @@ sanity checks). */ #define PCRE2_SUBSTITUTE_UNKNOWN_UNSET 0x00000800u #define PCRE2_SUBSTITUTE_OVERFLOW_LENGTH 0x00001000u +/* A further option for pcre2_match(), not allowed for pcre2_dfa_match(), +ignored for pcre2_jit_match(). */ + +#define PCRE2_NO_JIT 0x00002000u + /* Newline and \R settings, for use in compile contexts. The newline values must be kept in step with values set in config.h and both sets must all be greater than zero. */ @@ -245,6 +251,7 @@ numbers must not be changed. */ #define PCRE2_ERROR_BADSUBSTITUTION (-59) #define PCRE2_ERROR_BADSUBSPATTERN (-60) #define PCRE2_ERROR_TOOMANYREPLACE (-61) +#define PCRE2_ERROR_BADSERIALIZEDDATA (-62) /* Request types for pcre2_pattern_info() */ @@ -436,7 +443,9 @@ PCRE2_EXP_DECL int pcre2_set_recursion_memory_management( \ PCRE2_EXP_DECL \ pcre2_code *pcre2_compile(PCRE2_SPTR, PCRE2_SIZE, uint32_t, \ int *, PCRE2_SIZE *, pcre2_compile_context *); \ -PCRE2_EXP_DECL void pcre2_code_free(pcre2_code *); +PCRE2_EXP_DECL void pcre2_code_free(pcre2_code *); \ +PCRE2_EXP_DECL \ + pcre2_code *pcre2_code_copy(const pcre2_code *); /* Functions that give information about a compiled pattern. */ @@ -585,6 +594,7 @@ pcre2_compile are called by application code. */ /* Functions: the complete list in alphabetical order */ #define pcre2_callout_enumerate PCRE2_SUFFIX(pcre2_callout_enumerate_) +#define pcre2_code_copy PCRE2_SUFFIX(pcre2_code_copy_) #define pcre2_code_free PCRE2_SUFFIX(pcre2_code_free_) #define pcre2_compile PCRE2_SUFFIX(pcre2_compile_) #define pcre2_compile_context_copy PCRE2_SUFFIX(pcre2_compile_context_copy_) diff --git a/pcre2-10.21/src/pcre2.h.in b/pcre2-10.22/src/pcre2.h.in similarity index 98% rename from pcre2-10.21/src/pcre2.h.in rename to pcre2-10.22/src/pcre2.h.in index 49f190965..e1d944dc8 100644 --- a/pcre2-10.21/src/pcre2.h.in +++ b/pcre2-10.22/src/pcre2.h.in @@ -146,7 +146,8 @@ sanity checks). */ #define PCRE2_DFA_RESTART 0x00000040u #define PCRE2_DFA_SHORTEST 0x00000080u -/* These are additional options for pcre2_substitute(). */ +/* These are additional options for pcre2_substitute(), which passes any others +through to pcre2_match(). */ #define PCRE2_SUBSTITUTE_GLOBAL 0x00000100u #define PCRE2_SUBSTITUTE_EXTENDED 0x00000200u @@ -154,6 +155,11 @@ sanity checks). */ #define PCRE2_SUBSTITUTE_UNKNOWN_UNSET 0x00000800u #define PCRE2_SUBSTITUTE_OVERFLOW_LENGTH 0x00001000u +/* A further option for pcre2_match(), not allowed for pcre2_dfa_match(), +ignored for pcre2_jit_match(). */ + +#define PCRE2_NO_JIT 0x00002000u + /* Newline and \R settings, for use in compile contexts. The newline values must be kept in step with values set in config.h and both sets must all be greater than zero. */ @@ -245,6 +251,7 @@ numbers must not be changed. */ #define PCRE2_ERROR_BADSUBSTITUTION (-59) #define PCRE2_ERROR_BADSUBSPATTERN (-60) #define PCRE2_ERROR_TOOMANYREPLACE (-61) +#define PCRE2_ERROR_BADSERIALIZEDDATA (-62) /* Request types for pcre2_pattern_info() */ @@ -436,7 +443,9 @@ PCRE2_EXP_DECL int pcre2_set_recursion_memory_management( \ PCRE2_EXP_DECL \ pcre2_code *pcre2_compile(PCRE2_SPTR, PCRE2_SIZE, uint32_t, \ int *, PCRE2_SIZE *, pcre2_compile_context *); \ -PCRE2_EXP_DECL void pcre2_code_free(pcre2_code *); +PCRE2_EXP_DECL void pcre2_code_free(pcre2_code *); \ +PCRE2_EXP_DECL \ + pcre2_code *pcre2_code_copy(const pcre2_code *); /* Functions that give information about a compiled pattern. */ @@ -585,6 +594,7 @@ pcre2_compile are called by application code. */ /* Functions: the complete list in alphabetical order */ #define pcre2_callout_enumerate PCRE2_SUFFIX(pcre2_callout_enumerate_) +#define pcre2_code_copy PCRE2_SUFFIX(pcre2_code_copy_) #define pcre2_code_free PCRE2_SUFFIX(pcre2_code_free_) #define pcre2_compile PCRE2_SUFFIX(pcre2_compile_) #define pcre2_compile_context_copy PCRE2_SUFFIX(pcre2_compile_context_copy_) diff --git a/pcre2-10.21/src/pcre2_auto_possess.c b/pcre2-10.22/src/pcre2_auto_possess.c similarity index 99% rename from pcre2-10.21/src/pcre2_auto_possess.c rename to pcre2-10.22/src/pcre2_auto_possess.c index d4d2334d8..8d0fa896e 100644 --- a/pcre2-10.21/src/pcre2_auto_possess.c +++ b/pcre2-10.22/src/pcre2_auto_possess.c @@ -91,6 +91,7 @@ static const uint8_t autoposstab[APTROWS][APTCOLS] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } /* \X */ }; +#ifdef SUPPORT_UNICODE /* This table is used to check whether auto-possessification is possible between adjacent Unicode property opcodes (OP_PROP and OP_NOTPROP). The left-hand (repeated) opcode is used to select the row, and the right-hand @@ -170,6 +171,7 @@ static const uint8_t posspropstab[3][4] = { { ucp_Z, ucp_Z, ucp_C, ucp_Cc }, /* SPACE and PXSPACE, 2nd value redundant */ { ucp_L, ucp_N, ucp_P, ucp_Po } /* WORD */ }; +#endif /* SUPPORT_UNICODE */ diff --git a/pcre2-10.21/src/pcre2_chartables.c.dist b/pcre2-10.22/src/pcre2_chartables.c.dist similarity index 100% rename from pcre2-10.21/src/pcre2_chartables.c.dist rename to pcre2-10.22/src/pcre2_chartables.c.dist diff --git a/pcre2-10.21/src/pcre2_compile.c b/pcre2-10.22/src/pcre2_compile.c similarity index 98% rename from pcre2-10.21/src/pcre2_compile.c rename to pcre2-10.22/src/pcre2_compile.c index 876109036..bb9736cd5 100644 --- a/pcre2-10.21/src/pcre2_compile.c +++ b/pcre2-10.22/src/pcre2_compile.c @@ -81,7 +81,7 @@ by defining macros in order to minimize #if usage. */ /* Function definitions to allow mutual recursion */ -static int +static unsigned int add_list_to_class(uint8_t *, PCRE2_UCHAR **, uint32_t, compile_block *, const uint32_t *, unsigned int); @@ -149,9 +149,16 @@ have to check them every time. */ #define OFLOW_MAX (INT_MAX - 20) -/* Macro for setting individual bits in class bitmaps. */ +/* Macro for setting individual bits in class bitmaps. It took some +experimenting to figure out how to stop gcc 5.3.0 from warning with +-Wconversion. This version gets a warning: -#define SETBIT(a,b) a[(b)/8] |= (1 << ((b)&7)) + #define SETBIT(a,b) a[(b)/8] |= (uint8_t)(1 << ((b)&7)) + +Let's hope the apparently less efficient version isn't actually so bad if the +compiler is clever with identical subexpressions. */ + +#define SETBIT(a,b) a[(b)/8] = (uint8_t)(a[(b)/8] | (1 << ((b)&7))) /* Private flags added to firstcu and reqcu. */ @@ -722,6 +729,39 @@ static const uint8_t opcode_possessify[] = { +/************************************************* +* Copy compiled code * +*************************************************/ + +/* Compiled JIT code cannot be copied, so the new compiled block has no +associated JIT data. */ + +PCRE2_EXP_DEFN pcre2_code * PCRE2_CALL_CONVENTION +pcre2_code_copy(const pcre2_code *code) +{ +PCRE2_SIZE* ref_count; +pcre2_code *newcode; + +if (code == NULL) return NULL; +newcode = code->memctl.malloc(code->blocksize, code->memctl.memory_data); +if (newcode == NULL) return NULL; +memcpy(newcode, code, code->blocksize); +newcode->executable_jit = NULL; + +/* If the code is one that has been deserialized, increment the reference count +in the decoded tables. */ + +if ((code->flags & PCRE2_DEREF_TABLES) != 0) + { + ref_count = (PCRE2_SIZE *)(code->tables + tables_length); + (*ref_count)++; + } + +return newcode; +} + + + /************************************************* * Free compiled code * *************************************************/ @@ -804,7 +844,7 @@ static void complete_callout(PCRE2_UCHAR *previous_callout, PCRE2_SPTR ptr, compile_block *cb) { -size_t length = ptr - cb->start_pattern - GET(previous_callout, 1); +size_t length = (size_t)(ptr - cb->start_pattern - GET(previous_callout, 1)); PUT(previous_callout, 1 + LINK_SIZE, length); } @@ -839,9 +879,10 @@ as LOOKBEHIND_MAX. Returns: if non-negative, the fixed length, or -1 if an OP_RECURSE item was encountered and atend is FALSE or -2 if there is no fixed length, - or -3 if \C was encountered (in UTF-8 mode only) - or -4 length is too long - or -5 if an unknown opcode was encountered (internal error) + or -3 if \C was encountered (in UTF mode only) + or -4 if length is too long + or -5 if regex is too complicated + or -6 if an unknown opcode was encountered (internal error) */ #define FFL_LATER (-1) @@ -855,11 +896,11 @@ static int find_fixedlength(PCRE2_UCHAR *code, BOOL utf, BOOL atend, compile_block *cb, recurse_check *recurses, int *countptr) { -int length = -1; +uint32_t length = 0xffffffffu; /* Unset */ uint32_t group = 0; uint32_t groupinfo = 0; recurse_check this_recurse; -register int branchlength = 0; +register uint32_t branchlength = 0; register PCRE2_UCHAR *cc = code + 1 + LINK_SIZE; /* If this is a capturing group, we may have the answer cached, but we can only @@ -910,7 +951,7 @@ for (;;) case OP_COND: d = find_fixedlength(cc, utf, atend, cb, recurses, countptr); if (d < 0) return d; - branchlength += d; + branchlength += (uint32_t)d; do cc += GET(cc, 1); while (*cc == OP_ALT); cc += 1 + LINK_SIZE; break; @@ -926,16 +967,16 @@ for (;;) case OP_END: case OP_ACCEPT: case OP_ASSERT_ACCEPT: - if (length < 0) length = branchlength; + if (length == 0xffffffffu) length = branchlength; else if (length != branchlength) goto ISNOTFIXED; if (*cc != OP_ALT) { if (group > 0) { - groupinfo |= (GI_SET_FIXED_LENGTH | length); + groupinfo |= (uint32_t)(GI_SET_FIXED_LENGTH | length); cb->groupinfo[group] = groupinfo; } - return length; + return (int)length; } cc += 1 + LINK_SIZE; branchlength = 0; @@ -960,7 +1001,7 @@ for (;;) this_recurse.group = cs; d = find_fixedlength(cs, utf, atend, cb, &this_recurse, countptr); if (d < 0) return d; - branchlength += d; + branchlength += (uint32_t)d; cc += 1 + LINK_SIZE; break; @@ -1039,7 +1080,7 @@ for (;;) case OP_EXACTI: case OP_NOTEXACT: case OP_NOTEXACTI: - branchlength += (int)GET2(cc,1); + branchlength += GET2(cc,1); cc += 2 + IMM2_SIZE; #ifdef SUPPORT_UNICODE if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); @@ -1076,8 +1117,8 @@ for (;;) cc++; break; - /* The single-byte matcher isn't allowed. This only happens in UTF-8 mode; - otherwise \C is coded as OP_ALLANY. */ + /* The single-byte matcher isn't allowed. This only happens in UTF-8 or + UTF-16 mode; otherwise \C is coded as OP_ALLANY. */ case OP_ANYBYTE: return FFL_BACKSLASHC; @@ -1115,7 +1156,7 @@ for (;;) case OP_CRMINRANGE: case OP_CRPOSRANGE: if (GET2(cc,1) != GET2(cc,1+IMM2_SIZE)) goto ISNOTFIXED; - branchlength += (int)GET2(cc,1); + branchlength += GET2(cc,1); cc += 1 + 2 * IMM2_SIZE; break; @@ -1941,7 +1982,7 @@ else overflow = TRUE; break; } - s = s * 10 + (int)(*(++ptr) - CHAR_0); + s = s * 10 + (unsigned int)(*(++ptr) - CHAR_0); } if (overflow) /* Integer overflow */ { @@ -2005,7 +2046,7 @@ else overflow = TRUE; break; } - s = s * 10 + (int)(*(++ptr) - CHAR_0); + s = s * 10 + (unsigned int)(*(++ptr) - CHAR_0); } if (overflow) /* Integer overflow */ { @@ -2285,7 +2326,7 @@ get_ucp(PCRE2_SPTR *ptrptr, BOOL *negptr, unsigned int *ptypeptr, unsigned int *pdataptr, int *errorcodeptr, compile_block *cb) { register PCRE2_UCHAR c; -int i, bot, top; +size_t i, bot, top; PCRE2_SPTR ptr = *ptrptr; PCRE2_UCHAR name[32]; @@ -2753,13 +2794,13 @@ Returns: the number of < 256 characters added the pointer to extra data is updated */ -static int +static unsigned int add_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, uint32_t options, compile_block *cb, uint32_t start, uint32_t end) { uint32_t c; uint32_t classbits_end = (end <= 0xff ? end : 0xff); -int n8 = 0; +unsigned int n8 = 0; /* If caseless matching is required, scan the range and process alternate cases. In Unicode, there are 8-bit characters that have alternate cases that @@ -2907,14 +2948,14 @@ Returns: the number of < 256 characters added the pointer to extra data is updated */ -static int +static unsigned int add_list_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, uint32_t options, compile_block *cb, const uint32_t *p, unsigned int except) { -int n8 = 0; +unsigned int n8 = 0; while (p[0] < NOTACHAR) { - int n = 0; + unsigned int n = 0; if (p[0] != except) { while(p[n+1] == p[0] + n + 1) n++; @@ -2945,12 +2986,12 @@ Returns: the number of < 256 characters added the pointer to extra data is updated */ -static int +static unsigned int add_not_list_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, uint32_t options, compile_block *cb, const uint32_t *p) { BOOL utf = (options & PCRE2_UTF) != 0; -int n8 = 0; +unsigned int n8 = 0; if (p[0] > 0) n8 += add_to_class(classbits, uchardptr, options, cb, 0, p[0] - 1); while (p[0] < NOTACHAR) @@ -3099,7 +3140,7 @@ for (; ptr < cb->end_pattern; ptr++) /* Not UTF */ { - if (code != NULL) *code++ = x; + if (code != NULL) *code++ = (PCRE2_UCHAR)x; } arglen++; @@ -3173,20 +3214,20 @@ typedef struct nest_save { #define NSF_EXTENDED 0x0002u #define NSF_DUPNAMES 0x0004u -static uint32_t scan_for_captures(PCRE2_SPTR *ptrptr, uint32_t options, +static int scan_for_captures(PCRE2_SPTR *ptrptr, uint32_t options, compile_block *cb) { uint32_t c; uint32_t delimiter; -uint32_t nest_depth = 0; uint32_t set, unset, *optset; +uint32_t skiptoket = 0; +uint16_t nest_depth = 0; int errorcode = 0; int escape; int namelen; int i; BOOL inescq = FALSE; BOOL isdupname; -BOOL skiptoket = FALSE; BOOL utf = (options & PCRE2_UTF) != 0; BOOL negate_class; PCRE2_SPTR name; @@ -3213,10 +3254,10 @@ for (; ptr < cb->end_pattern; ptr++) next closing parenthesis must be ignored. The parenthesis itself must be processed (to end the nested parenthesized item). */ - if (skiptoket) + if (skiptoket != 0) { if (c != CHAR_RIGHT_PARENTHESIS) continue; - skiptoket = FALSE; + skiptoket = 0; } /* Skip over literals */ @@ -3231,17 +3272,16 @@ for (; ptr < cb->end_pattern; ptr++) continue; } - /* Skip over comments and whitespace in extended mode. Need a loop to handle - whitespace after a comment. */ + /* Skip over # comments and whitespace in extended mode. */ if ((options & PCRE2_EXTENDED) != 0) { - for (;;) + PCRE2_SPTR wscptr = ptr; + while (MAX_255(c) && (cb->ctypes[c] & ctype_space) != 0) c = *(++ptr); + if (c == CHAR_NUMBER_SIGN) { - while (MAX_255(c) && (cb->ctypes[c] & ctype_space) != 0) c = *(++ptr); - if (c != CHAR_NUMBER_SIGN) break; ptr++; - while (*ptr != CHAR_NULL) + while (ptr < cb->end_pattern) { if (IS_NEWLINE(ptr)) /* For non-fixed-length newline cases, */ { /* IS_NEWLINE sets cb->nllen. */ @@ -3253,7 +3293,15 @@ for (; ptr < cb->end_pattern; ptr++) if (utf) FORWARDCHAR(ptr); #endif } - c = *ptr; /* Either NULL or the char after a newline */ + } + + /* If we skipped any characters, restart the loop. Otherwise, we didn't see + a comment. */ + + if (ptr > wscptr) + { + ptr--; + continue; } } @@ -3377,27 +3425,24 @@ for (; ptr < cb->end_pattern; ptr++) if ((options & PCRE2_NO_AUTO_CAPTURE) == 0) cb->bracount++; } - /* (*something) - just skip to closing ket unless PCRE2_ALT_VERBNAMES is - set, in which case we have to process escapes in the string after the - name. */ + /* (*something) - skip over a name, and then just skip to closing ket + unless PCRE2_ALT_VERBNAMES is set, in which case we have to process + escapes in the string after a verb name terminated by a colon. */ else { ptr += 2; while (MAX_255(*ptr) && (cb->ctypes[*ptr] & ctype_word) != 0) ptr++; - if (*ptr == CHAR_COLON) + if (*ptr == CHAR_COLON && (options & PCRE2_ALT_VERBNAMES) != 0) { ptr++; - if ((options & PCRE2_ALT_VERBNAMES) != 0) - { - if (process_verb_name(&ptr, NULL, &errorcode, options, utf, cb) < 0) - goto FAILED; - } - else - { - while (ptr < cb->end_pattern && *ptr != CHAR_RIGHT_PARENTHESIS) - ptr++; - } + if (process_verb_name(&ptr, NULL, &errorcode, options, utf, cb) < 0) + goto FAILED; + } + else + { + while (ptr < cb->end_pattern && *ptr != CHAR_RIGHT_PARENTHESIS) + ptr++; } nest_depth--; } @@ -3414,7 +3459,7 @@ for (; ptr < cb->end_pattern; ptr++) IS_DIGIT(ptr[0]) || /* (?n) */ (ptr[0] == CHAR_MINUS && IS_DIGIT(ptr[1]))) /* (?-n) */ { - skiptoket = TRUE; + skiptoket = ptr[0]; break; } @@ -3434,8 +3479,8 @@ for (; ptr < cb->end_pattern; ptr++) if (*ptr == CHAR_VERTICAL_LINE) { - top_nest->reset_group = cb->bracount; - top_nest->max_group = cb->bracount; + top_nest->reset_group = (uint16_t)cb->bracount; + top_nest->max_group = (uint16_t)cb->bracount; top_nest->flags |= NSF_RESET; cb->external_flags |= PCRE2_DUPCAPUSED; break; @@ -3470,9 +3515,10 @@ for (; ptr < cb->end_pattern; ptr++) case CHAR_U: break; - default: errorcode = ERR11; - ptr--; /* Correct the offset */ - goto FAILED; + default: + errorcode = ERR11; + ptr--; /* Correct the offset */ + goto FAILED; } } @@ -3648,7 +3694,7 @@ for (; ptr < cb->end_pattern; ptr++) } if (namelen + IMM2_SIZE + 1 > cb->name_entry_size) - cb->name_entry_size = namelen + IMM2_SIZE + 1; + cb->name_entry_size = (uint16_t)(namelen + IMM2_SIZE + 1); /* We have a valid name for this capturing group. */ @@ -3666,7 +3712,7 @@ for (; ptr < cb->end_pattern; ptr++) for (i = 0; i < cb->names_found; i++, ng++) { if (namelen == ng->length && - PRIV(strncmp)(name, ng->name, namelen) == 0) + PRIV(strncmp)(name, ng->name, (size_t)namelen) == 0) { if (ng->number == cb->bracount) break; if ((options & PCRE2_DUPNAMES) == 0) @@ -3690,7 +3736,7 @@ for (; ptr < cb->end_pattern; ptr++) if (cb->names_found >= cb->named_group_list_size) { - int newsize = cb->named_group_list_size * 2; + uint32_t newsize = cb->named_group_list_size * 2; named_group *newspace = cb->cx->memctl.malloc(newsize * sizeof(named_group), cb->cx->memctl.memory_data); @@ -3712,9 +3758,9 @@ for (; ptr < cb->end_pattern; ptr++) /* Add this name to the list */ cb->named_groups[cb->names_found].name = name; - cb->named_groups[cb->names_found].length = namelen; + cb->named_groups[cb->names_found].length = (uint16_t)namelen; cb->named_groups[cb->names_found].number = cb->bracount; - cb->named_groups[cb->names_found].isdup = isdupname; + cb->named_groups[cb->names_found].isdup = (uint16_t)isdupname; cb->names_found++; break; } /* End of (? switch */ @@ -3727,7 +3773,7 @@ for (; ptr < cb->end_pattern; ptr++) (top_nest->flags & NSF_RESET) != 0) { if (cb->bracount > top_nest->max_group) - top_nest->max_group = cb->bracount; + top_nest->max_group = (uint16_t)cb->bracount; cb->bracount = top_nest->reset_group; } break; @@ -3748,13 +3794,26 @@ for (; ptr < cb->end_pattern; ptr++) if (top_nest == (nest_save *)(cb->start_workspace)) top_nest = NULL; else top_nest--; } - if (nest_depth > 0) nest_depth--; /* Can be 0 for unmatched ) */ + if (nest_depth == 0) /* Unmatched closing parenthesis */ + { + errorcode = ERR22; + goto FAILED; + } + nest_depth--; break; } } -cb->final_bracount = cb->bracount; -return 0; +if (nest_depth == 0) + { + cb->final_bracount = cb->bracount; + return 0; + } + +/* We give a special error for a missing closing parentheses after (?# because +it might otherwise be hard to see where the missing character is. */ + +errorcode = (skiptoket == CHAR_NUMBER_SIGN)? ERR18 : ERR14; FAILED: *ptrptr = ptr; @@ -3905,6 +3964,10 @@ for (;; ptr++) int32_t subreqcuflags, subfirstcuflags; /* Must be signed */ PCRE2_UCHAR mcbuffer[8]; + /* Come here to restart the loop. */ + + REDO_LOOP: + /* Get next character in the pattern */ c = *ptr; @@ -3949,7 +4012,7 @@ for (;; ptr++) *errorcodeptr = ERR20; goto FAILED; } - *lengthptr += code - last_code; + *lengthptr += (size_t)(code - last_code); /* If "previous" is set and it is not at the start of the work space, move it back to there, in order to avoid filling up the work space. Otherwise, @@ -3959,7 +4022,7 @@ for (;; ptr++) { if (previous > orig_code) { - memmove(orig_code, previous, CU2BYTES(code - previous)); + memmove(orig_code, previous, (size_t)CU2BYTES(code - previous)); code -= previous - orig_code; previous = orig_code; } @@ -4045,11 +4108,7 @@ for (;; ptr++) /* If we skipped any characters, restart the loop. Otherwise, we didn't see a comment. */ - if (ptr > wscptr) - { - ptr--; - continue; - } + if (ptr > wscptr) goto REDO_LOOP; } /* Skip over (?# comments. */ @@ -4120,7 +4179,7 @@ for (;; ptr++) *errorcodeptr = ERR20; goto FAILED; } - *lengthptr += code - last_code; /* To include callout length */ + *lengthptr += (size_t)(code - last_code); /* To include callout length */ } return TRUE; @@ -4189,17 +4248,15 @@ for (;; ptr++) if (PRIV(strncmp_c8)(ptr+1, STRING_WEIRD_STARTWORD, 6) == 0) { cb->nestptr[0] = ptr + 7; - ptr = sub_start_of_word; /* Do not combine these statements; clang's */ - ptr--; /* sanitizer moans about a negative index. */ - continue; + ptr = sub_start_of_word; + goto REDO_LOOP; } if (PRIV(strncmp_c8)(ptr+1, STRING_WEIRD_ENDWORD, 6) == 0) { cb->nestptr[0] = ptr + 7; - ptr = sub_end_of_word; /* Do not combine these statements; clang's */ - ptr--; /* sanitizer moans about a negative index. */ - continue; + ptr = sub_end_of_word; + goto REDO_LOOP; } /* Handle a real character class. */ @@ -4408,7 +4465,7 @@ for (;; ptr++) case PC_PUNCT: if (ptype == 0) ptype = PT_PXPUNCT; *class_uchardata++ = local_negate? XCL_NOTPROP : XCL_PROP; - *class_uchardata++ = ptype; + *class_uchardata++ = (PCRE2_UCHAR)ptype; *class_uchardata++ = 0; xclass_has_prop = TRUE; ptr = tempptr + 1; @@ -4456,9 +4513,9 @@ for (;; ptr++) if (taboffset >= 0) { if (tabopt >= 0) - for (c = 0; c < 32; c++) pbits[c] |= cbits[c + taboffset]; + for (c = 0; c < 32; c++) pbits[c] |= cbits[(int)c + taboffset]; else - for (c = 0; c < 32; c++) pbits[c] &= ~cbits[c + taboffset]; + for (c = 0; c < 32; c++) pbits[c] &= ~cbits[(int)c + taboffset]; } /* Now see if we need to remove any special characters. An option @@ -4866,6 +4923,7 @@ for (;; ptr++) /* For a single, positive character, get the value into mcbuffer, and then we can handle this with the normal one-character code. */ + mclength = PUTCHAR(c, mcbuffer); goto ONE_CHAR; } /* End of 1-char optimization */ @@ -5898,9 +5956,11 @@ for (;; ptr++) goto FAILED; } cb->had_accept = TRUE; + /* In the first pass, just accumulate the length required; - otherwise hitting (*ACCEPT) inside many nested parentheses can - cause workspace overflow. */ + otherwise hitting (*ACCEPT) inside many nested parentheses can + cause workspace overflow. */ + for (oc = cb->open_caps; oc != NULL; oc = oc->next) { if (lengthptr != NULL) @@ -5913,7 +5973,6 @@ for (;; ptr++) PUT2INC(code, 0, oc->number); } } - setverb = *code++ = (cb->assert_depth > 0)? OP_ASSERT_ACCEPT : OP_ACCEPT; @@ -7052,7 +7111,9 @@ for (;; ptr++) } } - /* Error if hit end of pattern */ + /* At the end of a group, it's an error if we hit end of pattern or + any non-closing parenthesis. This check also happens in the pre-scan, + so should not trigger here, but leave this code as an insurance. */ if (*ptr != CHAR_RIGHT_PARENTHESIS) { @@ -7359,12 +7420,17 @@ for (;; ptr++) } else #endif - /* In non-UTF mode, we turn \C into OP_ALLANY instead of OP_ANYBYTE - so that it works in DFA mode and in lookbehinds. */ + /* In non-UTF mode, and for both 32-bit modes, we turn \C into + OP_ALLANY instead of OP_ANYBYTE so that it works in DFA mode and in + lookbehinds. */ { previous = (escape > ESC_b && escape < ESC_Z)? code : NULL; +#if PCRE2_CODE_UNIT_WIDTH == 32 + *code++ = (escape == ESC_C)? OP_ALLANY : escape; +#else *code++ = (!utf && escape == ESC_C)? OP_ALLANY : escape; +#endif } } continue; @@ -8714,14 +8780,11 @@ if (cb.had_accept) reqcuflags = REQ_NONE; } -/* If we have not reached end of pattern after a successful compile, there's an -excess bracket. Fill in the final opcode and check for disastrous overflow. -If no overflow, but the estimated length exceeds the really used length, adjust -the value of re->blocksize, and if valgrind support is configured, mark the -extra allocated memory as unaddressable, so that any out-of-bound reads can be -detected. */ +/* Fill in the final opcode and check for disastrous overflow. If no overflow, +but the estimated length exceeds the really used length, adjust the value of +re->blocksize, and if valgrind support is configured, mark the extra allocated +memory as unaddressable, so that any out-of-bound reads can be detected. */ -if (errorcode == 0 && ptr < cb.end_pattern) errorcode = ERR22; *code++ = OP_END; usedlength = code - codestart; if (usedlength > length) errorcode = ERR23; else diff --git a/pcre2-10.21/src/pcre2_config.c b/pcre2-10.22/src/pcre2_config.c similarity index 91% rename from pcre2-10.21/src/pcre2_config.c rename to pcre2-10.22/src/pcre2_config.c index 921845949..e99272f57 100644 --- a/pcre2-10.21/src/pcre2_config.c +++ b/pcre2-10.22/src/pcre2_config.c @@ -61,15 +61,16 @@ convenient for user programs that want to test their values. */ * Return info about what features are configured * *************************************************/ -/* +/* If where is NULL, the length of memory required is returned. + Arguments: what what information is required where where to put the information -Returns: 0 if data returned - >= 0 if where is NULL, giving length required +Returns: 0 if a numerical value is returned + >= 0 if a string value PCRE2_ERROR_BADOPTION if "where" not recognized - or JIT target requested when JIT not enabled + or JIT target requested when JIT not enabled */ PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION @@ -127,15 +128,15 @@ switch (what) #ifdef SUPPORT_JIT { const char *v = PRIV(jit_get_target)(); - return 1 + ((where == NULL)? - strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v)); + return (int)(1 + ((where == NULL)? + strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v))); } #else return PCRE2_ERROR_BADOPTION; #endif case PCRE2_CONFIG_LINKSIZE: - *((uint32_t *)where) = configured_link_size; + *((uint32_t *)where) = (uint32_t)configured_link_size; break; case PCRE2_CONFIG_MATCHLIMIT: @@ -169,8 +170,8 @@ switch (what) #else const char *v = "Unicode not supported"; #endif - return 1 + ((where == NULL)? - strlen(v): PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v)); + return (int)(1 + ((where == NULL)? + strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v))); } break; @@ -206,8 +207,8 @@ switch (what) const char *v = (XSTRING(Z PCRE2_PRERELEASE)[1] == 0)? XSTRING(PCRE2_MAJOR.PCRE2_MINOR PCRE2_DATE) : XSTRING(PCRE2_MAJOR.PCRE2_MINOR) XSTRING(PCRE2_PRERELEASE PCRE2_DATE); - return 1 + ((where == NULL)? - strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v)); + return (int)(1 + ((where == NULL)? + strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v))); } } diff --git a/pcre2-10.21/src/pcre2_context.c b/pcre2-10.22/src/pcre2_context.c similarity index 100% rename from pcre2-10.21/src/pcre2_context.c rename to pcre2-10.22/src/pcre2_context.c diff --git a/pcre2-10.21/src/pcre2_dfa_match.c b/pcre2-10.22/src/pcre2_dfa_match.c similarity index 97% rename from pcre2-10.21/src/pcre2_dfa_match.c rename to pcre2-10.22/src/pcre2_dfa_match.c index 76bc08525..12b31b1b3 100644 --- a/pcre2-10.21/src/pcre2_dfa_match.c +++ b/pcre2-10.22/src/pcre2_dfa_match.c @@ -401,7 +401,7 @@ BOOL utf = FALSE; BOOL reset_could_continue = FALSE; rlevel++; -offsetcount &= (-2); +offsetcount &= (uint32_t)(-2); /* Round down */ wscount -= 2; wscount = (wscount - (wscount % (INTS_PER_STATEBLOCK * 2))) / @@ -439,7 +439,7 @@ if (*first_op == OP_REVERSE) end_code = this_start_code; do { - size_t back = GET(end_code, 2+LINK_SIZE); + size_t back = (size_t)GET(end_code, 2+LINK_SIZE); if (back > max_back) max_back = back; end_code += GET(end_code, 1); } @@ -481,11 +481,11 @@ if (*first_op == OP_REVERSE) end_code = this_start_code; do { - size_t back = GET(end_code, 2+LINK_SIZE); + size_t back = (size_t)GET(end_code, 2+LINK_SIZE); if (back <= gone_back) { int bstate = (int)(end_code - start_code + 2 + 2*LINK_SIZE); - ADD_NEW_DATA(-bstate, 0, gone_back - back); + ADD_NEW_DATA(-bstate, 0, (int)(gone_back - back)); } end_code += GET(end_code, 1); } @@ -509,7 +509,7 @@ else do { end_code += GET(end_code, 1); } while (*end_code == OP_ALT); new_count = workspace[1]; if (!workspace[0]) - memcpy(new_states, active_states, new_count * sizeof(stateblock)); + memcpy(new_states, active_states, (size_t)new_count * sizeof(stateblock)); } /* Not restarting */ @@ -593,8 +593,9 @@ for (;;) stateblock *current_state = active_states + i; BOOL caseless = FALSE; PCRE2_SPTR code; + uint32_t codevalue; int state_offset = current_state->offset; - int codevalue, rrc; + int rrc; int count; /* A negative offset is a special case meaning "hold off going to this @@ -719,7 +720,7 @@ for (;;) ADD_ACTIVE(state_offset + 1 + LINK_SIZE, 0); if (codevalue != OP_KET) { - ADD_ACTIVE(state_offset - GET(code, 1), 0); + ADD_ACTIVE(state_offset - (int)GET(code, 1), 0); } } else @@ -733,11 +734,12 @@ for (;;) else if (match_count > 0 && ++match_count * 2 > (int)offsetcount) match_count = 0; count = ((match_count == 0)? (int)offsetcount : match_count * 2) - 2; - if (count > 0) memmove(offsets + 2, offsets, count * sizeof(PCRE2_SIZE)); + if (count > 0) memmove(offsets + 2, offsets, + (size_t)count * sizeof(PCRE2_SIZE)); if (offsetcount >= 2) { - offsets[0] = (int)(current_subject - start_subject); - offsets[1] = (int)(ptr - start_subject); + offsets[0] = (PCRE2_SIZE)(current_subject - start_subject); + offsets[1] = (PCRE2_SIZE)(ptr - start_subject); } if ((mb->moptions & PCRE2_DFA_SHORTEST) != 0) return match_count; } @@ -959,7 +961,7 @@ for (;;) { if (d == '_') left_word = TRUE; else { - int cat = UCD_CATEGORY(d); + uint32_t cat = UCD_CATEGORY(d); left_word = (cat == ucp_L || cat == ucp_N); } } @@ -984,7 +986,7 @@ for (;;) { if (c == '_') right_word = TRUE; else { - int cat = UCD_CATEGORY(c); + uint32_t cat = UCD_CATEGORY(c); right_word = (cat == ucp_L || cat == ucp_N); } } @@ -1369,7 +1371,7 @@ for (;;) if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } if (clen > 0) { - int lgb, rgb; + uint32_t lgb, rgb; PCRE2_SPTR nptr = ptr + clen; int ncount = 0; if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS) @@ -1383,7 +1385,7 @@ for (;;) dlen = 1; if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); } rgb = UCD_GRAPHBREAK(d); - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + if ((PRIV(ucp_gbtable)[lgb] & (1u << rgb)) == 0) break; ncount++; lgb = rgb; nptr += dlen; @@ -1630,7 +1632,7 @@ for (;;) ADD_ACTIVE(state_offset + 2, 0); if (clen > 0) { - int lgb, rgb; + uint32_t lgb, rgb; PCRE2_SPTR nptr = ptr + clen; int ncount = 0; if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR || @@ -1645,7 +1647,7 @@ for (;;) dlen = 1; if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); } rgb = UCD_GRAPHBREAK(d); - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + if ((PRIV(ucp_gbtable)[lgb] & (1u << rgb)) == 0) break; ncount++; lgb = rgb; nptr += dlen; @@ -1902,7 +1904,7 @@ for (;;) count = current_state->count; /* Number already matched */ if (clen > 0) { - int lgb, rgb; + uint32_t lgb, rgb; PCRE2_SPTR nptr = ptr + clen; int ncount = 0; if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO) @@ -1916,7 +1918,7 @@ for (;;) dlen = 1; if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); } rgb = UCD_GRAPHBREAK(d); - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + if ((PRIV(ucp_gbtable)[lgb] & (1u << rgb)) == 0) break; ncount++; lgb = rgb; nptr += dlen; @@ -2097,7 +2099,7 @@ for (;;) case OP_EXTUNI: if (clen > 0) { - int lgb, rgb; + uint32_t lgb, rgb; PCRE2_SPTR nptr = ptr + clen; int ncount = 0; lgb = UCD_GRAPHBREAK(c); @@ -2106,7 +2108,7 @@ for (;;) dlen = 1; if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); } rgb = UCD_GRAPHBREAK(d); - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + if ((PRIV(ucp_gbtable)[lgb] & (1u << rgb)) == 0) break; ncount++; lgb = rgb; nptr += dlen; @@ -2582,7 +2584,7 @@ for (;;) mb, /* static match data */ code, /* this subexpression's code */ ptr, /* where we currently are */ - (int)(ptr - start_subject), /* start offset */ + (PCRE2_SIZE)(ptr - start_subject), /* start offset */ local_offsets, /* offset vector */ sizeof(local_offsets)/sizeof(PCRE2_SIZE), /* size of same */ local_workspace, /* workspace vector */ @@ -2601,8 +2603,8 @@ for (;;) { PCRE2_SIZE local_offsets[1000]; int local_workspace[1000]; - int codelink = GET(code, 1); - int condcode; + int codelink = (int)GET(code, 1); + PCRE2_UCHAR condcode; /* Because of the way auto-callout works during compile, a callout item is inserted between OP_COND and an assertion condition. This does not @@ -2611,8 +2613,10 @@ for (;;) if (code[LINK_SIZE + 1] == OP_CALLOUT || code[LINK_SIZE + 1] == OP_CALLOUT_STR) { - unsigned int callout_length = (code[LINK_SIZE + 1] == OP_CALLOUT) - ? PRIV(OP_lengths)[OP_CALLOUT] : GET(code, 2 + 3*LINK_SIZE); + PCRE2_SIZE callout_length = (code[LINK_SIZE + 1] == OP_CALLOUT)? + (PCRE2_SIZE)PRIV(OP_lengths)[OP_CALLOUT] : + (PCRE2_SIZE)GET(code, 2 + 3*LINK_SIZE); + rrc = 0; if (mb->callout != NULL) { @@ -2678,7 +2682,7 @@ for (;;) else if (condcode == OP_RREF) { - int value = GET2(code, LINK_SIZE + 2); + unsigned int value = GET2(code, LINK_SIZE + 2); if (value != RREF_ANY) return PCRE2_ERROR_DFA_UCOND; if (mb->recursive != NULL) { ADD_ACTIVE(state_offset + LINK_SIZE + 2 + IMM2_SIZE, 0); } @@ -2699,7 +2703,7 @@ for (;;) mb, /* fixed match data */ asscode, /* this subexpression's code */ ptr, /* where we currently are */ - (int)(ptr - start_subject), /* start offset */ + (PCRE2_SIZE)(ptr - start_subject), /* start offset */ local_offsets, /* offset vector */ sizeof(local_offsets)/sizeof(PCRE2_SIZE), /* size of same */ local_workspace, /* workspace vector */ @@ -2747,7 +2751,7 @@ for (;;) mb, /* fixed match data */ callpat, /* this subexpression's code */ ptr, /* where we currently are */ - (int)(ptr - start_subject), /* start offset */ + (PCRE2_SIZE)(ptr - start_subject), /* start offset */ local_offsets, /* offset vector */ sizeof(local_offsets)/sizeof(PCRE2_SIZE), /* size of same */ local_workspace, /* workspace vector */ @@ -2768,7 +2772,7 @@ for (;;) { for (rc = rc*2 - 2; rc >= 0; rc -= 2) { - int charcount = local_offsets[rc+1] - local_offsets[rc]; + PCRE2_SIZE charcount = local_offsets[rc+1] - local_offsets[rc]; #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 if (utf) { @@ -2779,7 +2783,8 @@ for (;;) #endif if (charcount > 0) { - ADD_NEW_DATA(-(state_offset + LINK_SIZE + 1), 0, (charcount - 1)); + ADD_NEW_DATA(-(state_offset + LINK_SIZE + 1), 0, + (int)(charcount - 1)); } else { @@ -2798,7 +2803,7 @@ for (;;) case OP_SCBRAPOS: case OP_BRAPOSZERO: { - int charcount, matched_count; + PCRE2_SIZE charcount, matched_count; PCRE2_SPTR local_ptr = ptr; BOOL allow_zero; @@ -2821,7 +2826,7 @@ for (;;) mb, /* fixed match data */ code, /* this subexpression's code */ local_ptr, /* where we currently are */ - (int)(ptr - start_subject), /* start offset */ + (PCRE2_SIZE)(ptr - start_subject), /* start offset */ local_offsets, /* offset vector */ sizeof(local_offsets)/sizeof(PCRE2_SIZE), /* size of same */ local_workspace, /* workspace vector */ @@ -2872,11 +2877,11 @@ for (;;) { PCRE2_SPTR p = ptr; PCRE2_SPTR pp = local_ptr; - charcount = (int)(pp - p); + charcount = (PCRE2_SIZE)(pp - p); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 if (utf) while (p < pp) if (NOT_FIRSTCU(*p++)) charcount--; #endif - ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1)); + ADD_NEW_DATA(-next_state_offset, 0, (int)(charcount - 1)); } } } @@ -2893,7 +2898,7 @@ for (;;) mb, /* fixed match data */ code, /* this subexpression's code */ ptr, /* where we currently are */ - (int)(ptr - start_subject), /* start offset */ + (PCRE2_SIZE)(ptr - start_subject), /* start offset */ local_offsets, /* offset vector */ sizeof(local_offsets)/sizeof(PCRE2_SIZE), /* size of same */ local_workspace, /* workspace vector */ @@ -2903,7 +2908,7 @@ for (;;) if (rc >= 0) { PCRE2_SPTR end_subpattern = code; - int charcount = local_offsets[1] - local_offsets[0]; + PCRE2_SIZE charcount = local_offsets[1] - local_offsets[0]; int next_state_offset, repeat_state_offset; do { end_subpattern += GET(end_subpattern, 1); } @@ -2963,9 +2968,9 @@ for (;;) while (p < pp) if (NOT_FIRSTCU(*p++)) charcount--; } #endif - ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1)); + ADD_NEW_DATA(-next_state_offset, 0, (int)(charcount - 1)); if (repeat_state_offset >= 0) - { ADD_NEW_DATA(-repeat_state_offset, 0, (charcount - 1)); } + { ADD_NEW_DATA(-repeat_state_offset, 0, (int)(charcount - 1)); } } } else if (rc != PCRE2_ERROR_NOMATCH) return rc; @@ -3018,7 +3023,7 @@ for (;;) return rrc; /* Abandon */ } if (rrc == 0) - { ADD_ACTIVE(state_offset + callout_length, 0); } + { ADD_ACTIVE(state_offset + (int)callout_length, 0); } } break; @@ -3307,10 +3312,10 @@ if (utf && (options & PCRE2_NO_UTF_CHECK) == 0) offset to be an absolute offset in the whole string. */ match_data->rc = PRIV(valid_utf)(check_subject, - length - (check_subject - subject), &(match_data->startchar)); + length - (PCRE2_SIZE)(check_subject - subject), &(match_data->startchar)); if (match_data->rc != 0) { - match_data->startchar += check_subject - subject; + match_data->startchar += (PCRE2_SIZE)(check_subject - subject); return match_data->rc; } } @@ -3332,7 +3337,8 @@ if (!anchored) { first_cu2 = TABLE_GET(first_cu, mb->tables + fcc_offset, first_cu); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 - if (utf && first_cu > 127) first_cu2 = UCD_OTHERCASE(first_cu); + if (utf && first_cu > 127) + first_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(first_cu); #endif } } @@ -3352,7 +3358,7 @@ if ((re->flags & PCRE2_LASTSET) != 0) { req_cu2 = TABLE_GET(req_cu, mb->tables + fcc_offset, req_cu); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 - if (utf && req_cu > 127) req_cu2 = UCD_OTHERCASE(req_cu); + if (utf && req_cu > 127) req_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(req_cu); #endif } } @@ -3560,9 +3566,9 @@ for (;;) start_match, /* where we currently are */ start_offset, /* start offset in subject */ match_data->ovector, /* offset vector */ - match_data->oveccount * 2, /* actual size of same */ + (uint32_t)match_data->oveccount * 2, /* actual size of same */ workspace, /* workspace vector */ - wscount, /* size of same */ + (int)wscount, /* size of same */ 0); /* function recurse level */ /* Anything other than "no match" means we are done, always; otherwise, carry @@ -3576,7 +3582,7 @@ for (;;) match_data->ovector[1] = (PCRE2_SIZE)(end_subject - subject); } match_data->leftchar = (PCRE2_SIZE)(mb->start_used_ptr - subject); - match_data->rightchar = mb->last_used_ptr - subject; + match_data->rightchar = (PCRE2_SIZE)( mb->last_used_ptr - subject); match_data->startchar = (PCRE2_SIZE)(start_match - subject); match_data->rc = rc; return rc; diff --git a/pcre2-10.21/src/pcre2_error.c b/pcre2-10.22/src/pcre2_error.c similarity index 95% rename from pcre2-10.21/src/pcre2_error.c rename to pcre2-10.22/src/pcre2_error.c index 6b4756aec..77fd5f412 100644 --- a/pcre2-10.21/src/pcre2_error.c +++ b/pcre2-10.22/src/pcre2_error.c @@ -62,7 +62,7 @@ Each substring ends with \0 to insert a null character. This includes the final substring, so that the whole string ends with \0\0, which can be detected when counting through. */ -static const char compile_error_texts[] = +static const unsigned char compile_error_texts[] = "no error\0" "\\ at end of pattern\0" "\\c at end of pattern\0" @@ -106,7 +106,7 @@ static const char compile_error_texts[] = "character code point value in \\x{} or \\o{} is too large\0" /* 35 */ "invalid condition (?(0)\0" - "\\C is not allowed in a lookbehind assertion\0" + "\\C is not allowed in a lookbehind assertion in UTF-" XSTRING(PCRE2_CODE_UNIT_WIDTH) " mode\0" "PCRE does not support \\L, \\l, \\N{name}, \\U, or \\u\0" "number after (?C is greater than 255\0" "closing parenthesis for (?C expected\0" @@ -177,7 +177,7 @@ static const char compile_error_texts[] = /* Match-time and UTF error texts are in the same format. */ -static const char match_error_texts[] = +static const unsigned char match_error_texts[] = "no error\0" "no match\0" "partial match\0" @@ -252,6 +252,7 @@ static const char match_error_texts[] = /* 60 */ "match with end before start is not supported\0" "too many replacements (more than INT_MAX)\0" + "bad serialized data\0" ; @@ -276,32 +277,32 @@ Returns: length of message if all is well PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION pcre2_get_error_message(int enumber, PCRE2_UCHAR *buffer, size_t size) { -char xbuff[128]; -const char *message; +const unsigned char *message; size_t i; -uint32_t n; +int n; if (size == 0) return PCRE2_ERROR_NOMEMORY; -if (enumber > COMPILE_ERROR_BASE) /* Compile error */ +if (enumber >= COMPILE_ERROR_BASE) /* Compile error */ { message = compile_error_texts; n = enumber - COMPILE_ERROR_BASE; } -else /* Match or UTF error */ +else if (enumber < 0) /* Match or UTF error */ { message = match_error_texts; n = -enumber; } +else /* Invalid error number */ + { + message = (unsigned char *)"\0"; /* Empty message list */ + n = 1; + } for (; n > 0; n--) { while (*message++ != CHAR_NULL) {}; - if (*message == CHAR_NULL) - { - sprintf(xbuff, "No text for error %d", enumber); - break; - } + if (*message == CHAR_NULL) return PCRE2_ERROR_BADDATA; } for (i = 0; *message != 0; i++) @@ -315,7 +316,7 @@ for (i = 0; *message != 0; i++) } buffer[i] = 0; -return i; +return (int)i; } /* End of pcre2_error.c */ diff --git a/pcre2-10.21/src/pcre2_find_bracket.c b/pcre2-10.22/src/pcre2_find_bracket.c similarity index 100% rename from pcre2-10.21/src/pcre2_find_bracket.c rename to pcre2-10.22/src/pcre2_find_bracket.c diff --git a/pcre2-10.21/src/pcre2_internal.h b/pcre2-10.22/src/pcre2_internal.h similarity index 94% rename from pcre2-10.21/src/pcre2_internal.h rename to pcre2-10.22/src/pcre2_internal.h index 7c9f66cc0..56908708a 100644 --- a/pcre2-10.21/src/pcre2_internal.h +++ b/pcre2-10.22/src/pcre2_internal.h @@ -2,7 +2,7 @@ * Perl-Compatible Regular Expressions * *************************************************/ -/* PCRE is a library of functions to support regular expressions whose syntax +/* PCRE2 is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel @@ -73,6 +73,14 @@ typedef int BOOL; #include #endif +/* Older versions of MSVC lack snprintf(). This define allows for +warning/error-free compilation and testing with MSVC compilers back to at least +MSVC 10/2010. Except for VC6 (which is missing some fundamentals and fails). */ + +#if defined(_MSC_VER) && (_MSC_VER < 1900) +#define snprintf _snprintf +#endif + /* When compiling a DLL for Windows, the exported symbols have to be declared using some MS magic. I found some useful information on this web page: http://msdn2.microsoft.com/en-us/library/y4h7bcy6(VS.80).aspx. According to the @@ -169,7 +177,7 @@ by "configure". */ #endif /* When compiling for use with the Virtual Pascal compiler, these functions -need to have their names changed. PCRE must be compiled with the -DVPCOMPAT +need to have their names changed. PCRE2 must be compiled with the -DVPCOMPAT option on the command line. */ #ifdef VPCOMPAT @@ -192,7 +200,7 @@ neither (there some non-Unix environments where this is the case). */ #define memmove(a, b, c) bcopy(b, a, c) #else /* HAVE_BCOPY */ static void * -pcre_memmove(void *d, const void *s, size_t n) +pcre2_memmove(void *d, const void *s, size_t n) { size_t i; unsigned char *dest = (unsigned char *)d; @@ -210,7 +218,7 @@ else return (void *)(dest - n); } } -#define memmove(a, b, c) pcre_memmove(a, b, c) +#define memmove(a, b, c) pcre2_memmove(a, b, c) #endif /* not HAVE_BCOPY */ #endif /* not HAVE_MEMMOVE */ #endif /* not VPCOMPAT */ @@ -234,8 +242,15 @@ Unicode doesn't go beyond 0x0010ffff. */ #define MAX_UTF_CODE_POINT 0x10ffff -/* Compile-time errors are added to this value. As they are documented, it -should probably never be changed. */ +/* Compile-time positive error numbers (all except UTF errors, which are +negative) start at this value. It should probably never be changed, in case +some application is checking for specific numbers. There is a copy of this +#define in pcre2posix.c (which now no longer includes this file). Ideally, a +way of having a single definition should be found, but as the number is +unlikely to change, this is not a pressing issue. The original reason for +having a base other than 0 was to keep the absolute values of compile-time and +run-time error numbers numerically different, but in the event the code does +not rely on this. */ #define COMPILE_ERROR_BASE 100 @@ -269,21 +284,21 @@ advancing the pointer. */ #define GETUTF8(c, eptr) \ { \ - if ((c & 0x20) == 0) \ - c = ((c & 0x1f) << 6) | (eptr[1] & 0x3f); \ - else if ((c & 0x10) == 0) \ - c = ((c & 0x0f) << 12) | ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \ - else if ((c & 0x08) == 0) \ - c = ((c & 0x07) << 18) | ((eptr[1] & 0x3f) << 12) | \ - ((eptr[2] & 0x3f) << 6) | (eptr[3] & 0x3f); \ - else if ((c & 0x04) == 0) \ - c = ((c & 0x03) << 24) | ((eptr[1] & 0x3f) << 18) | \ - ((eptr[2] & 0x3f) << 12) | ((eptr[3] & 0x3f) << 6) | \ - (eptr[4] & 0x3f); \ + if ((c & 0x20u) == 0) \ + c = ((c & 0x1fu) << 6) | (eptr[1] & 0x3fu); \ + else if ((c & 0x10u) == 0) \ + c = ((c & 0x0fu) << 12) | ((eptr[1] & 0x3fu) << 6) | (eptr[2] & 0x3fu); \ + else if ((c & 0x08u) == 0) \ + c = ((c & 0x07u) << 18) | ((eptr[1] & 0x3fu) << 12) | \ + ((eptr[2] & 0x3fu) << 6) | (eptr[3] & 0x3fu); \ + else if ((c & 0x04u) == 0) \ + c = ((c & 0x03u) << 24) | ((eptr[1] & 0x3fu) << 18) | \ + ((eptr[2] & 0x3fu) << 12) | ((eptr[3] & 0x3fu) << 6) | \ + (eptr[4] & 0x3fu); \ else \ - c = ((c & 0x01) << 30) | ((eptr[1] & 0x3f) << 24) | \ - ((eptr[2] & 0x3f) << 18) | ((eptr[3] & 0x3f) << 12) | \ - ((eptr[4] & 0x3f) << 6) | (eptr[5] & 0x3f); \ + c = ((c & 0x01u) << 30) | ((eptr[1] & 0x3fu) << 24) | \ + ((eptr[2] & 0x3fu) << 18) | ((eptr[3] & 0x3fu) << 12) | \ + ((eptr[4] & 0x3fu) << 6) | (eptr[5] & 0x3fu); \ } /* Base macro to pick up the remaining bytes of a UTF-8 character, advancing @@ -291,31 +306,31 @@ the pointer. */ #define GETUTF8INC(c, eptr) \ { \ - if ((c & 0x20) == 0) \ - c = ((c & 0x1f) << 6) | (*eptr++ & 0x3f); \ - else if ((c & 0x10) == 0) \ + if ((c & 0x20u) == 0) \ + c = ((c & 0x1fu) << 6) | (*eptr++ & 0x3fu); \ + else if ((c & 0x10u) == 0) \ { \ - c = ((c & 0x0f) << 12) | ((*eptr & 0x3f) << 6) | (eptr[1] & 0x3f); \ + c = ((c & 0x0fu) << 12) | ((*eptr & 0x3fu) << 6) | (eptr[1] & 0x3fu); \ eptr += 2; \ } \ - else if ((c & 0x08) == 0) \ + else if ((c & 0x08u) == 0) \ { \ - c = ((c & 0x07) << 18) | ((*eptr & 0x3f) << 12) | \ - ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \ + c = ((c & 0x07u) << 18) | ((*eptr & 0x3fu) << 12) | \ + ((eptr[1] & 0x3fu) << 6) | (eptr[2] & 0x3fu); \ eptr += 3; \ } \ - else if ((c & 0x04) == 0) \ + else if ((c & 0x04u) == 0) \ { \ - c = ((c & 0x03) << 24) | ((*eptr & 0x3f) << 18) | \ - ((eptr[1] & 0x3f) << 12) | ((eptr[2] & 0x3f) << 6) | \ - (eptr[3] & 0x3f); \ + c = ((c & 0x03u) << 24) | ((*eptr & 0x3fu) << 18) | \ + ((eptr[1] & 0x3fu) << 12) | ((eptr[2] & 0x3fu) << 6) | \ + (eptr[3] & 0x3fu); \ eptr += 4; \ } \ else \ { \ - c = ((c & 0x01) << 30) | ((*eptr & 0x3f) << 24) | \ - ((eptr[1] & 0x3f) << 18) | ((eptr[2] & 0x3f) << 12) | \ - ((eptr[3] & 0x3f) << 6) | (eptr[4] & 0x3f); \ + c = ((c & 0x01u) << 30) | ((*eptr & 0x3fu) << 24) | \ + ((eptr[1] & 0x3fu) << 18) | ((eptr[2] & 0x3fu) << 12) | \ + ((eptr[3] & 0x3fu) << 6) | (eptr[4] & 0x3fu); \ eptr += 5; \ } \ } @@ -325,34 +340,34 @@ advancing the pointer, incrementing the length. */ #define GETUTF8LEN(c, eptr, len) \ { \ - if ((c & 0x20) == 0) \ + if ((c & 0x20u) == 0) \ { \ - c = ((c & 0x1f) << 6) | (eptr[1] & 0x3f); \ + c = ((c & 0x1fu) << 6) | (eptr[1] & 0x3fu); \ len++; \ } \ - else if ((c & 0x10) == 0) \ + else if ((c & 0x10u) == 0) \ { \ - c = ((c & 0x0f) << 12) | ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \ + c = ((c & 0x0fu) << 12) | ((eptr[1] & 0x3fu) << 6) | (eptr[2] & 0x3fu); \ len += 2; \ } \ - else if ((c & 0x08) == 0) \ + else if ((c & 0x08u) == 0) \ {\ - c = ((c & 0x07) << 18) | ((eptr[1] & 0x3f) << 12) | \ - ((eptr[2] & 0x3f) << 6) | (eptr[3] & 0x3f); \ + c = ((c & 0x07u) << 18) | ((eptr[1] & 0x3fu) << 12) | \ + ((eptr[2] & 0x3fu) << 6) | (eptr[3] & 0x3fu); \ len += 3; \ } \ - else if ((c & 0x04) == 0) \ + else if ((c & 0x04u) == 0) \ { \ - c = ((c & 0x03) << 24) | ((eptr[1] & 0x3f) << 18) | \ - ((eptr[2] & 0x3f) << 12) | ((eptr[3] & 0x3f) << 6) | \ - (eptr[4] & 0x3f); \ + c = ((c & 0x03u) << 24) | ((eptr[1] & 0x3fu) << 18) | \ + ((eptr[2] & 0x3fu) << 12) | ((eptr[3] & 0x3fu) << 6) | \ + (eptr[4] & 0x3fu); \ len += 4; \ } \ else \ {\ - c = ((c & 0x01) << 30) | ((eptr[1] & 0x3f) << 24) | \ - ((eptr[2] & 0x3f) << 18) | ((eptr[3] & 0x3f) << 12) | \ - ((eptr[4] & 0x3f) << 6) | (eptr[5] & 0x3f); \ + c = ((c & 0x01u) << 30) | ((eptr[1] & 0x3fu) << 24) | \ + ((eptr[2] & 0x3fu) << 18) | ((eptr[3] & 0x3fu) << 12) | \ + ((eptr[4] & 0x3fu) << 6) | (eptr[5] & 0x3fu); \ len += 5; \ } \ } @@ -382,7 +397,7 @@ other. NOTE: The values also appear in pcre2_jit_compile.c. */ /* Character U+180E (Mongolian Vowel Separator) is not included in the list of spaces in the Unicode file PropList.txt, and Perl does not recognize it as a space. However, in many other sources it is listed as a space and has been in -PCRE for a long time. */ +PCRE (both APIs) for a long time. */ #define HSPACE_LIST \ CHAR_HT, CHAR_SPACE, CHAR_NBSP, \ @@ -550,17 +565,9 @@ req_unit match. */ #define REQ_CU_MAX 1000 -/* Bit definitions for entries in the pcre_ctypes table. */ - -#define ctype_space 0x01 -#define ctype_letter 0x02 -#define ctype_digit 0x04 -#define ctype_xdigit 0x08 -#define ctype_word 0x10 /* alphanumeric or '_' */ -#define ctype_meta 0x80 /* regexp meta char or zero (end pattern) */ - -/* Offsets for the bitmap tables in pcre_cbits. Each table contains a set -of bits for a class map. Some classes are built by combining these tables. */ +/* Offsets for the bitmap tables in the cbits set of tables. Each table +contains a set of bits for a class map. Some classes are built by combining +these tables. */ #define cbit_space 0 /* [:space:] or \s */ #define cbit_xdigit 32 /* [:xdigit:] */ @@ -574,19 +581,28 @@ of bits for a class map. Some classes are built by combining these tables. */ #define cbit_cntrl 288 /* [:cntrl:] */ #define cbit_length 320 /* Length of the cbits table */ -/* Offsets of the various tables from the base tables pointer, and -total length. */ +/* Bit definitions for entries in the ctypes table. */ -#define lcc_offset 0 -#define fcc_offset 256 -#define cbits_offset 512 -#define ctypes_offset (cbits_offset + cbit_length) +#define ctype_space 0x01 +#define ctype_letter 0x02 +#define ctype_digit 0x04 +#define ctype_xdigit 0x08 +#define ctype_word 0x10 /* alphanumeric or '_' */ +#define ctype_meta 0x80 /* regexp meta char or zero (end pattern) */ + +/* Offsets of the various tables from the base tables pointer, and +total length of the tables. */ + +#define lcc_offset 0 /* Lower case */ +#define fcc_offset 256 /* Flip case */ +#define cbits_offset 512 /* Character classes */ +#define ctypes_offset (cbits_offset + cbit_length) /* Character types */ #define tables_length (ctypes_offset + 256) /* -------------------- Character and string names ------------------------ */ -/* If PCRE is to support UTF-8 on EBCDIC platforms, we cannot use normal +/* If PCRE2 is to support UTF-8 on EBCDIC platforms, we cannot use normal character constants like '*' because the compiler would emit their EBCDIC code, which is different from their ASCII/UTF-8 code. Instead we define macros for the characters so that they always use the ASCII/UTF-8 code when UTF-8 support @@ -594,7 +610,7 @@ is enabled. When UTF-8 support is not enabled, the definitions use character literals. Both character and string versions of each character are needed, and there are some longer strings as well. -This means that, on EBCDIC platforms, the PCRE library can handle either +This means that, on EBCDIC platforms, the PCRE2 library can handle either EBCDIC, or UTF-8, but not both. To support both in the same compiled library would need different lookups depending on whether PCRE2_UTF was set or not. This would make it impossible to use characters in switch/case statements, @@ -606,7 +622,7 @@ macros to give the functions distinct names. */ #ifndef SUPPORT_UNICODE /* UTF-8 support is not enabled; use the platform-dependent character literals -so that PCRE works in both ASCII and EBCDIC environments, but only in non-UTF +so that PCRE2 works in both ASCII and EBCDIC environments, but only in non-UTF mode. Newline characters are problematic in EBCDIC. Though it has CR and LF characters, a common practice has been to use its NL (0x15) character as the line terminator in C-like processing environments. However, sometimes the LF @@ -614,7 +630,7 @@ line terminator in C-like processing environments. However, sometimes the LF http://unicode.org/standard/reports/tr13/tr13-5.html -PCRE defaults EBCDIC NL to 0x15, but has a build-time option to select 0x25 +PCRE2 defaults EBCDIC NL to 0x15, but has a build-time option to select 0x25 instead. Whichever is *not* chosen is defined as NEL. In both ASCII and EBCDIC environments, CHAR_NL and CHAR_LF are synonyms for the @@ -1219,7 +1235,7 @@ only. */ #define PT_TABSIZE 11 /* Size of square table for autopossessify tests */ /* The following special properties are used only in XCLASS items, when POSIX -classes are specified and PCRE_UCP is set - in other words, for Unicode +classes are specified and PCRE2_UCP is set - in other words, for Unicode handling of these classes. They are not available via the \p or \P escapes like those in the above list, and so they do not take part in the autopossessifying table. */ @@ -1283,7 +1299,7 @@ compatibility mode, and for \C in non-utf mode. In non-DOTALL mode, "." behaves like \N. The special values ESC_DU, ESC_du, etc. are used instead of ESC_D, ESC_d, etc. -when PCRE_UCP is set and replacement of \d etc by \p sequences is required. +when PCRE2_UCP is set and replacement of \d etc by \p sequences is required. They must be contiguous, and remain in order so that the replacements can be looked up from a table. @@ -1308,12 +1324,12 @@ enum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, Starting from 1 (i.e. after OP_END), the values up to OP_EOD must correspond in order to the list of escapes immediately above. Furthermore, values up to OP_DOLLM must not be changed without adjusting the table called autoposstab in -pcre_compile.c +pcre2_auto_possess.c Whenever this list is updated, the two macro definitions that follow must be updated to match. The possessification table called "opcode_possessify" in -pcre_compile.c must also be updated, and also the tables called "coptable" -and "poptable" in pcre_dfa_exec.c. +pcre2_compile.c must also be updated, and also the tables called "coptable" +and "poptable" in pcre2_dfa_match.c. ****** NOTE NOTE NOTE ******/ @@ -1890,7 +1906,7 @@ private structures. */ /* Private "external" functions. These are internal functions that are called from modules other than the one in which they are defined. They have to be -"external" in the C sense, but are not part of the PCRE public API. They are +"external" in the C sense, but are not part of the PCRE2 public API. They are not referenced from pcre2test, and must not be defined when no code unit width is available. */ diff --git a/pcre2-10.21/src/pcre2_intmodedep.h b/pcre2-10.22/src/pcre2_intmodedep.h similarity index 93% rename from pcre2-10.21/src/pcre2_intmodedep.h rename to pcre2-10.22/src/pcre2_intmodedep.h index 90b7959e0..596d62cfd 100644 --- a/pcre2-10.21/src/pcre2_intmodedep.h +++ b/pcre2-10.22/src/pcre2_intmodedep.h @@ -94,7 +94,7 @@ easier to maintain, the storing and loading of offsets from the compiled code unit string is now handled by the macros that are defined here. The macros are controlled by the value of LINK_SIZE. This defaults to 2, but -values of 2 or 4 are also supported. */ +values of 3 or 4 are also supported. */ /* ------------------- 8-bit support ------------------ */ @@ -102,29 +102,29 @@ values of 2 or 4 are also supported. */ #if LINK_SIZE == 2 #define PUT(a,n,d) \ - (a[n] = (d) >> 8), \ - (a[(n)+1] = (d) & 255) + (a[n] = (PCRE2_UCHAR)((d) >> 8)), \ + (a[(n)+1] = (PCRE2_UCHAR)((d) & 255)) #define GET(a,n) \ - (((a)[n] << 8) | (a)[(n)+1]) + (unsigned int)(((a)[n] << 8) | (a)[(n)+1]) #define MAX_PATTERN_SIZE (1 << 16) #elif LINK_SIZE == 3 #define PUT(a,n,d) \ - (a[n] = (d) >> 16), \ - (a[(n)+1] = (d) >> 8), \ - (a[(n)+2] = (d) & 255) + (a[n] = (PCRE2_UCHAR)((d) >> 16)), \ + (a[(n)+1] = (PCRE2_UCHAR)((d) >> 8)), \ + (a[(n)+2] = (PCRE2_UCHAR)((d) & 255)) #define GET(a,n) \ - (((a)[n] << 16) | ((a)[(n)+1] << 8) | (a)[(n)+2]) + (unsigned int)(((a)[n] << 16) | ((a)[(n)+1] << 8) | (a)[(n)+2]) #define MAX_PATTERN_SIZE (1 << 24) #elif LINK_SIZE == 4 #define PUT(a,n,d) \ - (a[n] = (d) >> 24), \ - (a[(n)+1] = (d) >> 16), \ - (a[(n)+2] = (d) >> 8), \ - (a[(n)+3] = (d) & 255) + (a[n] = (PCRE2_UCHAR)((d) >> 24)), \ + (a[(n)+1] = (PCRE2_UCHAR)((d) >> 16)), \ + (a[(n)+2] = (PCRE2_UCHAR)((d) >> 8)), \ + (a[(n)+3] = (PCRE2_UCHAR)((d) & 255)) #define GET(a,n) \ - (((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3]) + (unsigned int)(((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3]) #define MAX_PATTERN_SIZE (1 << 30) /* Keep it positive */ #else @@ -149,10 +149,10 @@ values of 2 or 4 are also supported. */ #undef LINK_SIZE #define LINK_SIZE 2 #define PUT(a,n,d) \ - (a[n] = (d) >> 16), \ - (a[(n)+1] = (d) & 65535) + (a[n] = (PCRE2_UCHAR)((d) >> 16)), \ + (a[(n)+1] = (PCRE2_UCHAR)((d) & 65535)) #define GET(a,n) \ - (((a)[n] << 16) | (a)[(n)+1]) + (unsigned int)(((a)[n] << 16) | (a)[(n)+1]) #define MAX_PATTERN_SIZE (1 << 30) /* Keep it positive */ #else @@ -283,47 +283,47 @@ UTF support is omitted, we don't even define them. */ /* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE. Otherwise it has an undefined behaviour. */ -#define GET_EXTRALEN(c) (PRIV(utf8_table4)[(c) & 0x3f]) +#define GET_EXTRALEN(c) (PRIV(utf8_table4)[(c) & 0x3fu]) /* Returns TRUE, if the given value is not the first code unit of a UTF sequence. */ -#define NOT_FIRSTCU(c) (((c) & 0xc0) == 0x80) +#define NOT_FIRSTCU(c) (((c) & 0xc0u) == 0x80u) /* Get the next UTF-8 character, not advancing the pointer. This is called when we know we are in UTF-8 mode. */ #define GETCHAR(c, eptr) \ c = *eptr; \ - if (c >= 0xc0) GETUTF8(c, eptr); + if (c >= 0xc0u) GETUTF8(c, eptr); /* Get the next UTF-8 character, testing for UTF-8 mode, and not advancing the pointer. */ #define GETCHARTEST(c, eptr) \ c = *eptr; \ - if (utf && c >= 0xc0) GETUTF8(c, eptr); + if (utf && c >= 0xc0u) GETUTF8(c, eptr); /* Get the next UTF-8 character, advancing the pointer. This is called when we know we are in UTF-8 mode. */ #define GETCHARINC(c, eptr) \ c = *eptr++; \ - if (c >= 0xc0) GETUTF8INC(c, eptr); + if (c >= 0xc0u) GETUTF8INC(c, eptr); /* Get the next character, testing for UTF-8 mode, and advancing the pointer. This is called when we don't know if we are in UTF-8 mode. */ #define GETCHARINCTEST(c, eptr) \ c = *eptr++; \ - if (utf && c >= 0xc0) GETUTF8INC(c, eptr); + if (utf && c >= 0xc0u) GETUTF8INC(c, eptr); /* Get the next UTF-8 character, not advancing the pointer, incrementing length if there are extra bytes. This is called when we know we are in UTF-8 mode. */ #define GETCHARLEN(c, eptr, len) \ c = *eptr; \ - if (c >= 0xc0) GETUTF8LEN(c, eptr, len); + if (c >= 0xc0u) GETUTF8LEN(c, eptr, len); /* Get the next UTF-8 character, testing for UTF-8 mode, not advancing the pointer, incrementing length if there are extra bytes. This is called when we @@ -331,21 +331,21 @@ do not know if we are in UTF-8 mode. */ #define GETCHARLENTEST(c, eptr, len) \ c = *eptr; \ - if (utf && c >= 0xc0) GETUTF8LEN(c, eptr, len); + if (utf && c >= 0xc0u) GETUTF8LEN(c, eptr, len); /* If the pointer is not at the start of a character, move it back until it is. This is called only in UTF-8 mode - we don't put a test within the macro because almost all calls are already within a block of UTF-8 only code. */ -#define BACKCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr-- +#define BACKCHAR(eptr) while((*eptr & 0xc0u) == 0x80u) eptr-- /* Same as above, just in the other direction. */ -#define FORWARDCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr++ -#define FORWARDCHARTEST(eptr,end) while(eptr < end && (*eptr & 0xc0) == 0x80) eptr++ +#define FORWARDCHAR(eptr) while((*eptr & 0xc0u) == 0x80u) eptr++ +#define FORWARDCHARTEST(eptr,end) while(eptr < end && (*eptr & 0xc0u) == 0x80u) eptr++ /* Same as above, but it allows a fully customizable form. */ #define ACROSSCHAR(condition, eptr, action) \ - while((condition) && ((eptr) & 0xc0) == 0x80) action + while((condition) && ((eptr) & 0xc0u) == 0x80u) action /* Deposit a character into memory, returning the number of code units. */ @@ -364,7 +364,7 @@ because almost all calls are already within a block of UTF-8 only code. */ /* Tests whether the code point needs extra characters to decode. */ -#define HAS_EXTRALEN(c) (((c) & 0xfc00) == 0xd800) +#define HAS_EXTRALEN(c) (((c) & 0xfc00u) == 0xd800u) /* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE. Otherwise it has an undefined behaviour. */ @@ -374,53 +374,53 @@ Otherwise it has an undefined behaviour. */ /* Returns TRUE, if the given value is not the first code unit of a UTF sequence. */ -#define NOT_FIRSTCU(c) (((c) & 0xfc00) == 0xdc00) +#define NOT_FIRSTCU(c) (((c) & 0xfc00u) == 0xdc00u) /* Base macro to pick up the low surrogate of a UTF-16 character, not advancing the pointer. */ #define GETUTF16(c, eptr) \ - { c = (((c & 0x3ff) << 10) | (eptr[1] & 0x3ff)) + 0x10000; } + { c = (((c & 0x3ffu) << 10) | (eptr[1] & 0x3ffu)) + 0x10000u; } /* Get the next UTF-16 character, not advancing the pointer. This is called when we know we are in UTF-16 mode. */ #define GETCHAR(c, eptr) \ c = *eptr; \ - if ((c & 0xfc00) == 0xd800) GETUTF16(c, eptr); + if ((c & 0xfc00u) == 0xd800u) GETUTF16(c, eptr); /* Get the next UTF-16 character, testing for UTF-16 mode, and not advancing the pointer. */ #define GETCHARTEST(c, eptr) \ c = *eptr; \ - if (utf && (c & 0xfc00) == 0xd800) GETUTF16(c, eptr); + if (utf && (c & 0xfc00u) == 0xd800u) GETUTF16(c, eptr); /* Base macro to pick up the low surrogate of a UTF-16 character, advancing the pointer. */ #define GETUTF16INC(c, eptr) \ - { c = (((c & 0x3ff) << 10) | (*eptr++ & 0x3ff)) + 0x10000; } + { c = (((c & 0x3ffu) << 10) | (*eptr++ & 0x3ffu)) + 0x10000u; } /* Get the next UTF-16 character, advancing the pointer. This is called when we know we are in UTF-16 mode. */ #define GETCHARINC(c, eptr) \ c = *eptr++; \ - if ((c & 0xfc00) == 0xd800) GETUTF16INC(c, eptr); + if ((c & 0xfc00u) == 0xd800u) GETUTF16INC(c, eptr); /* Get the next character, testing for UTF-16 mode, and advancing the pointer. This is called when we don't know if we are in UTF-16 mode. */ #define GETCHARINCTEST(c, eptr) \ c = *eptr++; \ - if (utf && (c & 0xfc00) == 0xd800) GETUTF16INC(c, eptr); + if (utf && (c & 0xfc00u) == 0xd800u) GETUTF16INC(c, eptr); /* Base macro to pick up the low surrogate of a UTF-16 character, not advancing the pointer, incrementing the length. */ #define GETUTF16LEN(c, eptr, len) \ - { c = (((c & 0x3ff) << 10) | (eptr[1] & 0x3ff)) + 0x10000; len++; } + { c = (((c & 0x3ffu) << 10) | (eptr[1] & 0x3ffu)) + 0x10000u; len++; } /* Get the next UTF-16 character, not advancing the pointer, incrementing length if there is a low surrogate. This is called when we know we are in @@ -428,7 +428,7 @@ UTF-16 mode. */ #define GETCHARLEN(c, eptr, len) \ c = *eptr; \ - if ((c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len); + if ((c & 0xfc00u) == 0xd800u) GETUTF16LEN(c, eptr, len); /* Get the next UTF-816character, testing for UTF-16 mode, not advancing the pointer, incrementing length if there is a low surrogate. This is called when @@ -436,22 +436,22 @@ we do not know if we are in UTF-16 mode. */ #define GETCHARLENTEST(c, eptr, len) \ c = *eptr; \ - if (utf && (c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len); + if (utf && (c & 0xfc00u) == 0xd800u) GETUTF16LEN(c, eptr, len); /* If the pointer is not at the start of a character, move it back until it is. This is called only in UTF-16 mode - we don't put a test within the macro because almost all calls are already within a block of UTF-16 only code. */ -#define BACKCHAR(eptr) if ((*eptr & 0xfc00) == 0xdc00) eptr-- +#define BACKCHAR(eptr) if ((*eptr & 0xfc00u) == 0xdc00u) eptr-- /* Same as above, just in the other direction. */ -#define FORWARDCHAR(eptr) if ((*eptr & 0xfc00) == 0xdc00) eptr++ -#define FORWARDCHARTEST(eptr,end) if (eptr < end && (*eptr & 0xfc00) == 0xdc00) eptr++ +#define FORWARDCHAR(eptr) if ((*eptr & 0xfc00u) == 0xdc00u) eptr++ +#define FORWARDCHARTEST(eptr,end) if (eptr < end && (*eptr & 0xfc00u) == 0xdc00u) eptr++ /* Same as above, but it allows a fully customizable form. */ #define ACROSSCHAR(condition, eptr, action) \ - if ((condition) && ((eptr) & 0xfc00) == 0xdc00) action + if ((condition) && ((eptr) & 0xfc00u) == 0xdc00u) action /* Deposit a character into memory, returning the number of code units. */ diff --git a/pcre2-10.21/src/pcre2_jit_compile.c b/pcre2-10.22/src/pcre2_jit_compile.c similarity index 97% rename from pcre2-10.21/src/pcre2_jit_compile.c rename to pcre2-10.22/src/pcre2_jit_compile.c index b46f4e394..8dea90a1c 100644 --- a/pcre2-10.21/src/pcre2_jit_compile.c +++ b/pcre2-10.22/src/pcre2_jit_compile.c @@ -38,7 +38,6 @@ POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ - #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -187,9 +186,9 @@ typedef struct jit_arguments { void *callout_data; /* Everything else after. */ sljit_uw offset_limit; - sljit_ui limit_match; - uint32_t oveccount; - uint32_t options; + sljit_u32 limit_match; + sljit_u32 oveccount; + sljit_u32 options; } jit_arguments; #define JIT_NUMBER_OF_COMPILE_MODES 3 @@ -198,8 +197,8 @@ typedef struct executable_functions { void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES]; void *read_only_data_heads[JIT_NUMBER_OF_COMPILE_MODES]; sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES]; - sljit_ui top_bracket; - sljit_ui limit_match; + sljit_u32 top_bracket; + sljit_u32 limit_match; } executable_functions; typedef struct jump_list { @@ -350,46 +349,46 @@ typedef struct compiler_common { /* First byte code. */ PCRE2_SPTR start; /* Maps private data offset to each opcode. */ - sljit_si *private_data_ptrs; + sljit_s32 *private_data_ptrs; /* Chain list of read-only data ptrs. */ void *read_only_data_head; /* Tells whether the capturing bracket is optimized. */ - sljit_ub *optimized_cbracket; + sljit_u8 *optimized_cbracket; /* Tells whether the starting offset is a target of then. */ - sljit_ub *then_offsets; + sljit_u8 *then_offsets; /* Current position where a THEN must jump. */ then_trap_backtrack *then_trap; /* Starting offset of private data for capturing brackets. */ - sljit_si cbra_ptr; + sljit_s32 cbra_ptr; /* Output vector starting point. Must be divisible by 2. */ - sljit_si ovector_start; + sljit_s32 ovector_start; /* Points to the starting character of the current match. */ - sljit_si start_ptr; + sljit_s32 start_ptr; /* Last known position of the requested byte. */ - sljit_si req_char_ptr; + sljit_s32 req_char_ptr; /* Head of the last recursion. */ - sljit_si recursive_head_ptr; + sljit_s32 recursive_head_ptr; /* First inspected character for partial matching. (Needed for avoiding zero length partial matches.) */ - sljit_si start_used_ptr; + sljit_s32 start_used_ptr; /* Starting pointer for partial soft matches. */ - sljit_si hit_start; + sljit_s32 hit_start; /* Pointer of the match end position. */ - sljit_si match_end_ptr; + sljit_s32 match_end_ptr; /* Points to the marked string. */ - sljit_si mark_ptr; + sljit_s32 mark_ptr; /* Recursive control verb management chain. */ - sljit_si control_head_ptr; + sljit_s32 control_head_ptr; /* Points to the last matched capture block index. */ - sljit_si capture_last_ptr; + sljit_s32 capture_last_ptr; /* Fast forward skipping byte code pointer. */ PCRE2_SPTR fast_forward_bc_ptr; /* Locals used by fast fail optimization. */ - sljit_si fast_fail_start_ptr; - sljit_si fast_fail_end_ptr; + sljit_s32 fast_fail_start_ptr; + sljit_s32 fast_fail_end_ptr; /* Flipped and lower case tables. */ - const sljit_ub *fcc; + const sljit_u8 *fcc; sljit_sw lcc; /* Mode can be PCRE2_JIT_COMPLETE and others. */ int mode; @@ -409,12 +408,12 @@ typedef struct compiler_common { BOOL positive_assert; /* Newline control. */ int nltype; - sljit_ui nlmax; - sljit_ui nlmin; + sljit_u32 nlmax; + sljit_u32 nlmin; int newline; int bsr_nltype; - sljit_ui bsr_nlmax; - sljit_ui bsr_nlmin; + sljit_u32 bsr_nlmax; + sljit_u32 bsr_nlmin; /* Dollar endonly. */ int endonly; /* Tables. */ @@ -471,27 +470,27 @@ typedef struct compare_context { #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED int ucharptr; union { - sljit_si asint; - sljit_uh asushort; + sljit_s32 asint; + sljit_u16 asushort; #if PCRE2_CODE_UNIT_WIDTH == 8 - sljit_ub asbyte; - sljit_ub asuchars[4]; + sljit_u8 asbyte; + sljit_u8 asuchars[4]; #elif PCRE2_CODE_UNIT_WIDTH == 16 - sljit_uh asuchars[2]; + sljit_u16 asuchars[2]; #elif PCRE2_CODE_UNIT_WIDTH == 32 - sljit_ui asuchars[1]; + sljit_u32 asuchars[1]; #endif } c; union { - sljit_si asint; - sljit_uh asushort; + sljit_s32 asint; + sljit_u16 asushort; #if PCRE2_CODE_UNIT_WIDTH == 8 - sljit_ub asbyte; - sljit_ub asuchars[4]; + sljit_u8 asbyte; + sljit_u8 asuchars[4]; #elif PCRE2_CODE_UNIT_WIDTH == 16 - sljit_uh asuchars[2]; + sljit_u16 asuchars[2]; #elif PCRE2_CODE_UNIT_WIDTH == 32 - sljit_ui asuchars[1]; + sljit_u32 asuchars[1]; #endif } oc; #endif @@ -533,19 +532,19 @@ the start pointers when the end of the capturing group has not yet reached. */ #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start]) #if PCRE2_CODE_UNIT_WIDTH == 8 -#define MOV_UCHAR SLJIT_MOV_UB -#define MOVU_UCHAR SLJIT_MOVU_UB +#define MOV_UCHAR SLJIT_MOV_U8 +#define MOVU_UCHAR SLJIT_MOVU_U8 #define IN_UCHARS(x) (x) #elif PCRE2_CODE_UNIT_WIDTH == 16 -#define MOV_UCHAR SLJIT_MOV_UH -#define MOVU_UCHAR SLJIT_MOVU_UH +#define MOV_UCHAR SLJIT_MOV_U16 +#define MOVU_UCHAR SLJIT_MOVU_U16 #define UCHAR_SHIFT (1) -#define IN_UCHARS(x) ((x) << UCHAR_SHIFT) +#define IN_UCHARS(x) ((x) * 2) #elif PCRE2_CODE_UNIT_WIDTH == 32 -#define MOV_UCHAR SLJIT_MOV_UI -#define MOVU_UCHAR SLJIT_MOVU_UI +#define MOV_UCHAR SLJIT_MOV_U32 +#define MOVU_UCHAR SLJIT_MOVU_U32 #define UCHAR_SHIFT (2) -#define IN_UCHARS(x) ((x) << UCHAR_SHIFT) +#define IN_UCHARS(x) ((x) * 4) #else #error Unsupported compiling mode #endif @@ -1056,7 +1055,7 @@ if (is_accelerated_repeat(cc)) return FALSE; } -static SLJIT_INLINE void detect_fast_fail(compiler_common *common, PCRE2_SPTR cc, int *private_data_start, sljit_si depth) +static SLJIT_INLINE void detect_fast_fail(compiler_common *common, PCRE2_SPTR cc, int *private_data_start, sljit_s32 depth) { PCRE2_SPTR next_alt; @@ -1121,8 +1120,8 @@ static SLJIT_INLINE void detect_fast_fail(compiler_common *common, PCRE2_SPTR cc static int get_class_iterator_size(PCRE2_SPTR cc) { -sljit_ui min; -sljit_ui max; +sljit_u32 min; +sljit_u32 max; switch(*cc) { case OP_CRSTAR: @@ -1159,7 +1158,7 @@ PCRE2_SPTR next_end; PCRE2_SPTR max_end; PCRE2_UCHAR type; sljit_sw length = end - begin; -sljit_si min, max, i; +sljit_s32 min, max, i; /* Detect fixed iterations first. */ if (end[-(1 + LINK_SIZE)] != OP_KET) @@ -1417,14 +1416,14 @@ while (cc < ccend) case OP_CLASS: case OP_NCLASS: - size = 1 + 32 / sizeof(PCRE2_UCHAR); space = get_class_iterator_size(cc + size); + size = 1 + 32 / sizeof(PCRE2_UCHAR); break; #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 case OP_XCLASS: - size = GET(cc, 1); space = get_class_iterator_size(cc + size); + size = GET(cc, 1); break; #endif @@ -2224,7 +2223,7 @@ if (save) SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty))); } -static SLJIT_INLINE PCRE2_SPTR set_then_offsets(compiler_common *common, PCRE2_SPTR cc, sljit_ub *current_offset) +static SLJIT_INLINE PCRE2_SPTR set_then_offsets(compiler_common *common, PCRE2_SPTR cc, sljit_u8 *current_offset) { PCRE2_SPTR end = bracketend(cc); BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT; @@ -2362,6 +2361,7 @@ add_stub(common, CMP(SLJIT_GREATER, STACK_TOP, 0, STACK_LIMIT, 0)); static SLJIT_INLINE void free_stack(compiler_common *common, int size) { DEFINE_COMPILER; + SLJIT_ASSERT(size > 0); OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw)); } @@ -2390,7 +2390,7 @@ static SLJIT_INLINE void reset_ovector(compiler_common *common, int length) { DEFINE_COMPILER; struct sljit_label *loop; -sljit_si i; +sljit_s32 i; /* At this point we can freely use all temporary registers. */ SLJIT_ASSERT(length > 1); @@ -2415,7 +2415,7 @@ else static SLJIT_INLINE void reset_fast_fail(compiler_common *common) { DEFINE_COMPILER; -sljit_si i; +sljit_s32 i; SLJIT_ASSERT(common->fast_fail_start_ptr < common->fast_fail_end_ptr); @@ -2496,7 +2496,7 @@ OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr); if (common->mark_ptr != 0) OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr); -OP1(SLJIT_MOV_UI, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, oveccount)); +OP1(SLJIT_MOV_U32, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, oveccount)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_S0, 0); if (common->mark_ptr != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R2, 0); @@ -2515,7 +2515,7 @@ OP2(SLJIT_ASHR, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_IMM, UCHAR_SHIFT); #endif SLJIT_ASSERT(sizeof(PCRE2_SIZE) == 4 || sizeof(PCRE2_SIZE) == 8); if (sizeof(PCRE2_SIZE) == 4) - OP1(SLJIT_MOVU_UI, SLJIT_MEM1(SLJIT_R2), sizeof(PCRE2_SIZE), SLJIT_S1, 0); + OP1(SLJIT_MOVU_U32, SLJIT_MEM1(SLJIT_R2), sizeof(PCRE2_SIZE), SLJIT_S1, 0); else OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_R2), sizeof(PCRE2_SIZE), SLJIT_S1, 0); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1); @@ -2541,7 +2541,7 @@ else static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit) { DEFINE_COMPILER; -sljit_si mov_opcode; +sljit_s32 mov_opcode; SLJIT_COMPILE_ASSERT(STR_END == SLJIT_S1, str_end_must_be_saved_reg2); SLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0 @@ -2557,7 +2557,7 @@ OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_R2, 0); OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, match_data)); -mov_opcode = (sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_UI : SLJIT_MOV; +mov_opcode = (sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_U32 : SLJIT_MOV; OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_S0, 0); #if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 @@ -2794,7 +2794,7 @@ else JUMPHERE(jump); } -static void peek_char(compiler_common *common, sljit_ui max) +static void peek_char(compiler_common *common, sljit_u32 max) { /* Reads the character into TMP1, keeps STR_PTR. Does not check STR_END. TMP2 Destroyed. */ @@ -2839,12 +2839,12 @@ if (common->utf) #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 -static BOOL is_char7_bitset(const sljit_ub *bitset, BOOL nclass) +static BOOL is_char7_bitset(const sljit_u8 *bitset, BOOL nclass) { /* Tells whether the character codes below 128 are enough to determine a match. */ -const sljit_ub value = nclass ? 0xff : 0; -const sljit_ub *end = bitset + 32; +const sljit_u8 value = nclass ? 0xff : 0; +const sljit_u8 *end = bitset + 32; bitset += 16; do @@ -2869,12 +2869,12 @@ SLJIT_ASSERT(common->utf); OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); +OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); if (full_read) { jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xc0); - OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); JUMPHERE(jump); } @@ -2882,7 +2882,7 @@ if (full_read) #endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */ -static void read_char_range(compiler_common *common, sljit_ui min, sljit_ui max, BOOL update_str_ptr) +static void read_char_range(compiler_common *common, sljit_u32 min, sljit_u32 max, BOOL update_str_ptr) { /* Reads the precise value of a character into TMP1, if the character is between min and max (c >= min && c <= max). Otherwise it returns with a value @@ -2913,7 +2913,7 @@ if (common->utf) { OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xf0); if (update_str_ptr) - OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x7); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); @@ -2937,7 +2937,7 @@ if (common->utf) { OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xe0); if (update_str_ptr) - OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xf); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); @@ -2957,7 +2957,7 @@ if (common->utf) add_jump(compiler, (max < 0x10000) ? &common->utfreadchar16 : &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); else if (max < 128) { - OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); } else @@ -2966,7 +2966,7 @@ if (common->utf) if (!update_str_ptr) OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); else - OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); @@ -3036,7 +3036,7 @@ if (common->utf) { /* This can be an extra read in some situations, but hopefully it is needed in most cases. */ - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xc0); if (!update_str_ptr) { @@ -3048,7 +3048,7 @@ if (common->utf) OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); JUMPHERE(jump2); } else @@ -3063,7 +3063,7 @@ if (common->utf) OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255); #endif -OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); +OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); #if PCRE2_CODE_UNIT_WIDTH != 8 JUMPHERE(jump); #endif @@ -3255,7 +3255,7 @@ compare = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x3); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0); -OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); +OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); JUMPHERE(compare); @@ -3264,7 +3264,7 @@ sljit_emit_fast_return(compiler, RETURN_ADDR, 0); /* We only have types for characters less than 256. */ JUMPHERE(jump); -OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0); +OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); @@ -3286,20 +3286,20 @@ SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8); sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); -OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1)); +OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1)); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2)); -OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1); +OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); -OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); +OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); } #endif /* SUPPORT_UNICODE */ -static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common, BOOL hascrorlf, uint32_t overall_options) +static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common, BOOL hascrorlf, sljit_u32 overall_options) { DEFINE_COMPILER; struct sljit_label *mainloop; @@ -3417,7 +3417,7 @@ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); if (common->utf) { singlechar = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); JUMPHERE(singlechar); } @@ -3478,13 +3478,13 @@ chars[len] = chr; chars[0] = len; } -static int scan_prefix(compiler_common *common, PCRE2_SPTR cc, PCRE2_UCHAR *chars, int max_chars, uint32_t *rec_count) +static int scan_prefix(compiler_common *common, PCRE2_SPTR cc, PCRE2_UCHAR *chars, int max_chars, sljit_u32 *rec_count) { /* Recursive function, which scans prefix literals. */ BOOL last, any, class, caseless; int len, repeat, len_save, consumed = 0; -sljit_ui chr; /* Any unicode character. */ -sljit_ub *bytes, *bytes_end, byte; +sljit_u32 chr; /* Any unicode character. */ +sljit_u8 *bytes, *bytes_end, byte; PCRE2_SPTR alternative, cc_save, oc; #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 PCRE2_UCHAR othercase[8]; @@ -3603,7 +3603,8 @@ while (TRUE) case OP_CLASS: #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - if (common->utf && !is_char7_bitset((const sljit_ub *)(cc + 1), FALSE)) return consumed; + if (common->utf && !is_char7_bitset((const sljit_u8 *)(cc + 1), FALSE)) + return consumed; #endif class = TRUE; break; @@ -3627,7 +3628,7 @@ while (TRUE) case OP_DIGIT: #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - if (common->utf && !is_char7_bitset((const sljit_ub *)common->ctypes - cbit_length + cbit_digit, FALSE)) + if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_digit, FALSE)) return consumed; #endif any = TRUE; @@ -3636,7 +3637,7 @@ while (TRUE) case OP_WHITESPACE: #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - if (common->utf && !is_char7_bitset((const sljit_ub *)common->ctypes - cbit_length + cbit_space, FALSE)) + if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_space, FALSE)) return consumed; #endif any = TRUE; @@ -3645,7 +3646,7 @@ while (TRUE) case OP_WORDCHAR: #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - if (common->utf && !is_char7_bitset((const sljit_ub *)common->ctypes - cbit_length + cbit_word, FALSE)) + if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_word, FALSE)) return consumed; #endif any = TRUE; @@ -3717,7 +3718,7 @@ while (TRUE) if (class) { - bytes = (sljit_ub*) (cc + 1); + bytes = (sljit_u8*) (cc + 1); cc += 1 + 32 / sizeof(PCRE2_UCHAR); switch (*cc) @@ -3877,9 +3878,9 @@ while (TRUE) #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) -static sljit_si character_to_int32(PCRE2_UCHAR chr) +static sljit_s32 character_to_int32(PCRE2_UCHAR chr) { -sljit_si value = (sljit_si)chr; +sljit_s32 value = (sljit_s32)chr; #if PCRE2_CODE_UNIT_WIDTH == 8 #define SSE2_COMPARE_TYPE_INDEX 0 return (value << 24) | (value << 16) | (value << 8) | value; @@ -3900,10 +3901,10 @@ DEFINE_COMPILER; struct sljit_label *start; struct sljit_jump *quit[3]; struct sljit_jump *nomatch; -sljit_ub instruction[8]; -sljit_si tmp1_ind = sljit_get_register_index(TMP1); -sljit_si tmp2_ind = sljit_get_register_index(TMP2); -sljit_si str_ptr_ind = sljit_get_register_index(STR_PTR); +sljit_u8 instruction[8]; +sljit_s32 tmp1_ind = sljit_get_register_index(TMP1); +sljit_s32 tmp2_ind = sljit_get_register_index(TMP2); +sljit_s32 str_ptr_ind = sljit_get_register_index(STR_PTR); BOOL load_twice = FALSE; PCRE2_UCHAR bit; @@ -4026,12 +4027,12 @@ sljit_emit_op_custom(compiler, instruction, 4); if (load_twice) { - OP1(SLJIT_MOV, TMP3, 0, TMP2, 0); + OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP2, 0); instruction[3] = 0xc0 | (tmp2_ind << 3) | 1; sljit_emit_op_custom(compiler, instruction, 4); OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); - OP1(SLJIT_MOV, TMP2, 0, TMP3, 0); + OP1(SLJIT_MOV, TMP2, 0, RETURN_ADDR, 0); } OP2(SLJIT_ASHR, TMP1, 0, TMP1, 0, TMP2, 0); @@ -4156,7 +4157,7 @@ SET_LABEL(quit[2], start); #endif -static void fast_forward_first_char2(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_si offset) +static void fast_forward_first_char2(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset) { DEFINE_COMPILER; struct sljit_label *start; @@ -4333,14 +4334,14 @@ struct sljit_jump *match; /* bytes[0] represent the number of characters between 0 and MAX_N_BYTES - 1, 255 represents any character. */ PCRE2_UCHAR chars[MAX_N_CHARS * MAX_DIFF_CHARS]; -sljit_si offset; +sljit_s32 offset; PCRE2_UCHAR mask; PCRE2_UCHAR *char_set, *char_set_end; int i, max, from; int range_right = -1, range_len; -sljit_ub *update_table = NULL; +sljit_u8 *update_table = NULL; BOOL in_range; -uint32_t rec_count; +sljit_u32 rec_count; for (i = 0; i < MAX_N_CHARS; i++) chars[i * MAX_DIFF_CHARS] = 0; @@ -4378,7 +4379,7 @@ for (i = 0; i <= max; i++) if (range_right >= 0) { - update_table = (sljit_ub *)allocate_read_only_data(common, 256); + update_table = (sljit_u8 *)allocate_read_only_data(common, 256); if (update_table == NULL) return TRUE; memset(update_table, IN_UCHARS(range_len), 256); @@ -4464,15 +4465,15 @@ start = LABEL(); quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); #if PCRE2_CODE_UNIT_WIDTH == 8 || (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) -OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right)); +OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right)); #else -OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right + 1) - 1); +OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right + 1) - 1); #endif #if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) -OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(RETURN_ADDR, TMP1), 0); +OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(RETURN_ADDR, TMP1), 0); #else -OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)update_table); +OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)update_table); #endif OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, start); @@ -4548,7 +4549,6 @@ return TRUE; } #undef MAX_N_CHARS -#undef MAX_N_BYTES static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, PCRE2_UCHAR first_char, BOOL caseless) { @@ -4654,9 +4654,9 @@ if (common->match_end_ptr != 0) OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); } -static BOOL check_class_ranges(compiler_common *common, const sljit_ub *bits, BOOL nclass, BOOL invert, jump_list **backtracks); +static BOOL check_class_ranges(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks); -static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, const sljit_ub *start_bits) +static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, const sljit_u8 *start_bits) { DEFINE_COMPILER; struct sljit_label *start; @@ -4690,7 +4690,7 @@ if (!check_class_ranges(common, start_bits, (start_bits[31] & 0x80) != 0, TRUE, #endif OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)start_bits); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)start_bits); OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); found = JUMP(SLJIT_NOT_ZERO); @@ -4706,7 +4706,7 @@ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); if (common->utf) { CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); } #elif PCRE2_CODE_UNIT_WIDTH == 16 @@ -4741,7 +4741,7 @@ struct sljit_jump *alreadyfound; struct sljit_jump *found; struct sljit_jump *foundoc = NULL; struct sljit_jump *notfound; -sljit_ui oc, bit; +sljit_u32 oc, bit; SLJIT_ASSERT(common->req_char_ptr != 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr); @@ -4878,7 +4878,7 @@ else if (common->utf) jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); #endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0); @@ -4923,7 +4923,7 @@ else if (common->utf) jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); #endif - OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes); + OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes); OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */); OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); #if PCRE2_CODE_UNIT_WIDTH != 8 @@ -4939,12 +4939,12 @@ OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOC sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0); } -static BOOL check_class_ranges(compiler_common *common, const sljit_ub *bits, BOOL nclass, BOOL invert, jump_list **backtracks) +static BOOL check_class_ranges(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks) { /* May destroy TMP1. */ DEFINE_COMPILER; int ranges[MAX_RANGE_SIZE]; -sljit_ub bit, cbit, all; +sljit_u8 bit, cbit, all; int i, byte, length = 0; bit = bits[0] & 0x1; @@ -5239,12 +5239,12 @@ OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); #if PCRE2_CODE_UNIT_WIDTH != 8 jump = CMP(SLJIT_GREATER, CHAR1, 0, SLJIT_IMM, 255); #endif -OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0); +OP1(SLJIT_MOV_U8, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0); #if PCRE2_CODE_UNIT_WIDTH != 8 JUMPHERE(jump); jump = CMP(SLJIT_GREATER, CHAR2, 0, SLJIT_IMM, 255); #endif -OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0); +OP1(SLJIT_MOV_U8, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0); #if PCRE2_CODE_UNIT_WIDTH != 8 JUMPHERE(jump); #endif @@ -5269,11 +5269,11 @@ sljit_emit_fast_return(compiler, RETURN_ADDR, 0); static PCRE2_SPTR SLJIT_CALL do_utf_caselesscmp(PCRE2_SPTR src1, jit_arguments *args, PCRE2_SPTR end1) { /* This function would be ineffective to do in JIT level. */ -sljit_ui c1, c2; +sljit_u32 c1, c2; PCRE2_SPTR src2 = args->startchar_ptr; PCRE2_SPTR end2 = args->end; const ucd_record *ur; -const sljit_ui *pp; +const sljit_u32 *pp; while (src1 < end1) { @@ -5297,8 +5297,6 @@ return src2; #endif /* SUPPORT_UNICODE */ -static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr); - static PCRE2_SPTR byte_sequence_compare(compiler_common *common, BOOL caseless, PCRE2_SPTR cc, compare_context *context, jump_list **backtracks) { @@ -5335,16 +5333,16 @@ if (context->sourcereg == -1) #if PCRE2_CODE_UNIT_WIDTH == 8 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED if (context->length >= 4) - OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); + OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); else if (context->length >= 2) - OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); + OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); else #endif - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); #elif PCRE2_CODE_UNIT_WIDTH == 16 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED if (context->length >= 4) - OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); + OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); else #endif OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); @@ -5386,12 +5384,12 @@ do #endif { if (context->length >= 4) - OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); + OP1(SLJIT_MOV_S32, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); else if (context->length >= 2) - OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); + OP1(SLJIT_MOV_U16, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); #if PCRE2_CODE_UNIT_WIDTH == 8 else if (context->length >= 1) - OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); + OP1(SLJIT_MOV_U8, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); #endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; @@ -5474,6 +5472,8 @@ return cc; } \ charoffset = (value); +static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr); + static void compile_xclass_matchingpath(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks) { DEFINE_COMPILER; @@ -5491,7 +5491,7 @@ BOOL utf = common->utf; BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE; BOOL charsaved = FALSE; int typereg = TMP1; -const sljit_ui *other_cases; +const sljit_u32 *other_cases; sljit_uw typeoffset; #endif @@ -5609,11 +5609,11 @@ if ((cc[-1] & XCL_HASPROP) == 0) if ((cc[-1] & XCL_MAP) != 0) { jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); - if (!check_class_ranges(common, (const sljit_ub *)cc, (((const sljit_ub *)cc)[31] & 0x80) != 0, TRUE, &found)) + if (!check_class_ranges(common, (const sljit_u8 *)cc, (((const sljit_u8 *)cc)[31] & 0x80) != 0, TRUE, &found)) { OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); add_jump(compiler, &found, JUMP(SLJIT_NOT_ZERO)); @@ -5636,7 +5636,7 @@ else if ((cc[-1] & XCL_MAP) != 0) #ifdef SUPPORT_UNICODE charsaved = TRUE; #endif - if (!check_class_ranges(common, (const sljit_ub *)cc, FALSE, TRUE, list)) + if (!check_class_ranges(common, (const sljit_u8 *)cc, FALSE, TRUE, list)) { #if PCRE2_CODE_UNIT_WIDTH == 8 jump = NULL; @@ -5646,7 +5646,7 @@ else if ((cc[-1] & XCL_MAP) != 0) OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); add_jump(compiler, list, JUMP(SLJIT_NOT_ZERO)); @@ -5668,18 +5668,18 @@ if (needstype || needsscript) OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); - OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1)); + OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1)); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2)); - OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1); + OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1); /* Before anything else, we deal with scripts. */ if (needsscript) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); ccbegin = cc; @@ -5726,12 +5726,12 @@ if (needstype || needsscript) if (!needschar) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); } else { OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3); - OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); + OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); typereg = RETURN_ADDR; } } @@ -6127,47 +6127,9 @@ switch(type) check_partial(common, FALSE); return cc; - case OP_CIRC: - OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); - add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0)); - OP2(SLJIT_IAND | SLJIT_SET_E, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); - add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); - return cc; - - case OP_CIRCM: - OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); - jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0); - OP2(SLJIT_IAND | SLJIT_SET_E, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); - add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); - jump[0] = JUMP(SLJIT_JUMP); - JUMPHERE(jump[1]); - - if (!common->alt_circumflex) - add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); - - if (common->nltype == NLTYPE_FIXED && common->newline > 255) - { - OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); - add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, TMP1, 0)); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); - OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); - } - else - { - skip_char_back(common); - read_char_range(common, common->nlmin, common->nlmax, TRUE); - check_newlinechar(common, common->nltype, backtracks, FALSE); - } - JUMPHERE(jump[0]); - return cc; - case OP_DOLL: OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); - OP2(SLJIT_IAND | SLJIT_SET_E, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); + OP2(SLJIT_AND32 | SLJIT_SET_E, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); if (!common->endonly) @@ -6182,7 +6144,7 @@ switch(type) case OP_DOLLM: jump[1] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); - OP2(SLJIT_IAND | SLJIT_SET_E, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); + OP2(SLJIT_AND32 | SLJIT_SET_E, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); check_partial(common, FALSE); jump[0] = JUMP(SLJIT_JUMP); @@ -6216,6 +6178,44 @@ switch(type) JUMPHERE(jump[0]); return cc; + case OP_CIRC: + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); + add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0)); + OP2(SLJIT_AND32 | SLJIT_SET_E, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); + add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); + return cc; + + case OP_CIRCM: + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); + jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0); + OP2(SLJIT_AND32 | SLJIT_SET_E, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); + add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); + jump[0] = JUMP(SLJIT_JUMP); + JUMPHERE(jump[1]); + + if (!common->alt_circumflex) + add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + + if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, TMP1, 0)); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); + } + else + { + skip_char_back(common); + read_char_range(common, common->nlmin, common->nlmax, TRUE); + check_newlinechar(common, common->nltype, backtracks, FALSE); + } + JUMPHERE(jump[0]); + return cc; + case OP_REVERSE: length = GET(cc, 0); if (length == 0) @@ -6267,7 +6267,7 @@ switch(type) if (check_str_ptr) detect_partial_match(common, backtracks); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - if (common->utf && is_char7_bitset((const sljit_ub*)common->ctypes - cbit_length + cbit_digit, FALSE)) + if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_digit, FALSE)) read_char7_type(common, type == OP_NOT_DIGIT); else #endif @@ -6282,7 +6282,7 @@ switch(type) if (check_str_ptr) detect_partial_match(common, backtracks); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - if (common->utf && is_char7_bitset((const sljit_ub*)common->ctypes - cbit_length + cbit_space, FALSE)) + if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_space, FALSE)) read_char7_type(common, type == OP_NOT_WHITESPACE); else #endif @@ -6296,7 +6296,7 @@ switch(type) if (check_str_ptr) detect_partial_match(common, backtracks); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - if (common->utf && is_char7_bitset((const sljit_ub*)common->ctypes - cbit_length + cbit_word, FALSE)) + if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_word, FALSE)) read_char7_type(common, type == OP_NOT_WORDCHAR); else #endif @@ -6338,7 +6338,7 @@ switch(type) #if PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16 #if PCRE2_CODE_UNIT_WIDTH == 8 jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); #elif PCRE2_CODE_UNIT_WIDTH == 16 jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800); @@ -6425,7 +6425,7 @@ switch(type) OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop)); /* Optimize register allocation: use a real register. */ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0); - OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3); + OP1(SLJIT_MOV_U8, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3); label = LABEL(); jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); @@ -6433,10 +6433,10 @@ switch(type) read_char(common); add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop)); - OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM2(TMP1, TMP2), 3); + OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM2(TMP1, TMP2), 3); OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2); - OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_sw)PRIV(ucp_gbtable)); + OP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_sw)PRIV(ucp_gbtable)); OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0); OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); @@ -6520,7 +6520,7 @@ switch(type) c = *cc; if (c < 128) { - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); if (type == OP_NOT || !char_has_othercase(common, cc)) add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c)); else @@ -6576,13 +6576,13 @@ switch(type) detect_partial_match(common, backtracks); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - bit = (common->utf && is_char7_bitset((const sljit_ub *)cc, type == OP_NCLASS)) ? 127 : 255; + bit = (common->utf && is_char7_bitset((const sljit_u8 *)cc, type == OP_NCLASS)) ? 127 : 255; read_char_range(common, 0, bit, type == OP_NCLASS); #else read_char_range(common, 0, 255, type == OP_NCLASS); #endif - if (check_class_ranges(common, (const sljit_ub *)cc, type == OP_NCLASS, FALSE, backtracks)) + if (check_class_ranges(common, (const sljit_u8 *)cc, type == OP_NCLASS, FALSE, backtracks)) return cc + 32 / sizeof(PCRE2_UCHAR); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 @@ -6607,7 +6607,7 @@ switch(type) OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); add_jump(compiler, backtracks, JUMP(SLJIT_ZERO)); @@ -7134,8 +7134,8 @@ static int SLJIT_CALL do_callout(struct jit_arguments *arguments, pcre2_callout_ { PCRE2_SPTR begin = arguments->begin; PCRE2_SIZE *ovector = arguments->match_data->ovector; -uint32_t oveccount = arguments->oveccount; -uint32_t i; +sljit_u32 oveccount = arguments->oveccount; +sljit_u32 i; if (arguments->callout == NULL) return 0; @@ -7176,7 +7176,7 @@ static SLJIT_INLINE PCRE2_SPTR compile_callout_matchingpath(compiler_common *com { DEFINE_COMPILER; backtrack_common *backtrack; -sljit_si mov_opcode; +sljit_s32 mov_opcode; unsigned int callout_length = (*cc == OP_CALLOUT) ? PRIV(OP_lengths)[OP_CALLOUT] : GET(cc, 1 + 2 * LINK_SIZE); sljit_sw value1; @@ -7191,8 +7191,8 @@ SLJIT_ASSERT(common->capture_last_ptr != 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr); OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); value1 = (*cc == OP_CALLOUT) ? cc[1 + 2 * LINK_SIZE] : 0; -OP1(SLJIT_MOV_UI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, value1); -OP1(SLJIT_MOV_UI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0); +OP1(SLJIT_MOV_U32, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, value1); +OP1(SLJIT_MOV_U32, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0); /* These pointer sized fields temporarly stores internal variables. */ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)); @@ -7201,7 +7201,7 @@ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(subject), TMP2, 0); if (common->mark_ptr != 0) OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr)); -mov_opcode = (sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_UI : SLJIT_MOV; +mov_opcode = (sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_U32 : SLJIT_MOV; OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 1)); OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 1 + LINK_SIZE)); @@ -7228,7 +7228,7 @@ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0); OP2(SLJIT_SUB, SLJIT_R1, 0, STACK_TOP, 0, SLJIT_IMM, CALLOUT_ARG_SIZE); GET_LOCAL_BASE(SLJIT_R2, 0, OVECTOR_START); sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout)); -OP1(SLJIT_MOV_SI, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0); +OP1(SLJIT_MOV_S32, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0); OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); free_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw)); @@ -7257,6 +7257,10 @@ while (TRUE) case OP_NOT_WORD_BOUNDARY: case OP_WORD_BOUNDARY: + case OP_CIRC: + case OP_CIRCM: + case OP_DOLL: + case OP_DOLLM: case OP_CALLOUT: case OP_ALT: cc += PRIV(OP_lengths)[*cc]; @@ -8650,7 +8654,7 @@ count_match(common); return cc + 1 + LINK_SIZE; } -static SLJIT_INLINE PCRE2_SPTR get_iterator_parameters(compiler_common *common, PCRE2_SPTR cc, PCRE2_UCHAR *opcode, PCRE2_UCHAR *type, sljit_ui *max, sljit_ui *exact, PCRE2_SPTR *end) +static SLJIT_INLINE PCRE2_SPTR get_iterator_parameters(compiler_common *common, PCRE2_SPTR cc, PCRE2_UCHAR *opcode, PCRE2_UCHAR *type, sljit_u32 *max, sljit_u32 *exact, PCRE2_SPTR *end) { int class_len; @@ -8801,9 +8805,9 @@ DEFINE_COMPILER; backtrack_common *backtrack; PCRE2_UCHAR opcode; PCRE2_UCHAR type; -sljit_ui max = 0, exact; +sljit_u32 max = 0, exact; BOOL fast_fail; -sljit_si fast_str_ptr; +sljit_s32 fast_str_ptr; BOOL charpos_enabled; PCRE2_UCHAR charpos_char; unsigned int charpos_othercasebit; @@ -8943,9 +8947,7 @@ switch(opcode) #elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 SLJIT_ASSERT((charpos_othercasebit >> 9) == 0); if ((charpos_othercasebit & 0x100) != 0) - { charpos_othercasebit = (charpos_othercasebit & 0xff) << 8; - } #endif if (charpos_othercasebit != 0) charpos_char |= charpos_othercasebit; @@ -9220,7 +9222,7 @@ if (common->accept_label == NULL) else CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), common->accept_label); OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); -OP1(SLJIT_MOV_UI, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options)); +OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options)); OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY); add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_NOT_ZERO)); OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART); @@ -9347,10 +9349,10 @@ while (cc < ccend) case OP_WORD_BOUNDARY: case OP_EODN: case OP_EOD: - case OP_CIRC: - case OP_CIRCM: case OP_DOLL: case OP_DOLLM: + case OP_CIRC: + case OP_CIRCM: case OP_REVERSE: cc = compile_simple_assertion_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); break; @@ -9652,7 +9654,7 @@ DEFINE_COMPILER; PCRE2_SPTR cc = current->cc; PCRE2_UCHAR opcode; PCRE2_UCHAR type; -sljit_ui max = 0, exact; +sljit_u32 max = 0, exact; struct sljit_label *label = NULL; struct sljit_jump *jump = NULL; jump_list *jumplist = NULL; @@ -9771,7 +9773,7 @@ switch(opcode) break; } - set_jumps(current->topbacktracks, LABEL()); +set_jumps(current->topbacktracks, LABEL()); } static SLJIT_INLINE void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current) @@ -10826,14 +10828,14 @@ sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0); #undef COMPILE_BACKTRACKINGPATH #undef CURRENT_AS -static int jit_compile(pcre2_code *code, uint32_t mode) +static int jit_compile(pcre2_code *code, sljit_u32 mode) { pcre2_real_code *re = (pcre2_real_code *)code; struct sljit_compiler *compiler; backtrack_common rootbacktrack; compiler_common common_data; compiler_common *common = &common_data; -const sljit_ub *tables = re->tables; +const sljit_u8 *tables = re->tables; void *allocator_data = &re->memctl; int private_data_size; PCRE2_SPTR ccend; @@ -10930,7 +10932,7 @@ ccend = bracketend(common->start); /* Calculate the local space size on the stack. */ common->ovector_start = LIMIT_MATCH + sizeof(sljit_sw); -common->optimized_cbracket = (sljit_ub *)SLJIT_MALLOC(re->top_bracket + 1, allocator_data); +common->optimized_cbracket = (sljit_u8 *)SLJIT_MALLOC(re->top_bracket + 1, allocator_data); if (!common->optimized_cbracket) return PCRE2_ERROR_NOMEMORY; #if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 1 @@ -11001,13 +11003,13 @@ SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0)); common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw); total_length = ccend - common->start; -common->private_data_ptrs = (sljit_si *)SLJIT_MALLOC(total_length * (sizeof(sljit_si) + (common->has_then ? 1 : 0)), allocator_data); +common->private_data_ptrs = (sljit_s32 *)SLJIT_MALLOC(total_length * (sizeof(sljit_s32) + (common->has_then ? 1 : 0)), allocator_data); if (!common->private_data_ptrs) { SLJIT_FREE(common->optimized_cbracket, allocator_data); return PCRE2_ERROR_NOMEMORY; } -memset(common->private_data_ptrs, 0, total_length * sizeof(sljit_si)); +memset(common->private_data_ptrs, 0, total_length * sizeof(sljit_s32)); private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw); set_private_data_ptrs(common, &private_data_size, ccend); @@ -11028,7 +11030,7 @@ if (private_data_size > SLJIT_MAX_LOCAL_SIZE) if (common->has_then) { - common->then_offsets = (sljit_ub *)(common->private_data_ptrs + total_length); + common->then_offsets = (sljit_u8 *)(common->private_data_ptrs + total_length); memset(common->then_offsets, 0, total_length); set_then_offsets(common, common->start, NULL); } @@ -11055,7 +11057,7 @@ OP1(SLJIT_MOV, TMP1, 0, SLJIT_S0, 0); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end)); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); -OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match)); +OP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match)); OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base)); OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit)); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); @@ -11192,10 +11194,8 @@ if ((re->overall_options & PCRE2_ANCHORED) == 0 && common->match_end_ptr != 0) OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); } -if (common->fast_forward_bc_ptr != NULL) - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), PRIVATE_DATA(common->fast_forward_bc_ptr + 1)); -else - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr); +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), + (common->fast_forward_bc_ptr != NULL) ? (PRIVATE_DATA(common->fast_forward_bc_ptr + 1)) : common->start_ptr); if ((re->overall_options & PCRE2_ANCHORED) == 0) { @@ -11216,9 +11216,7 @@ if ((re->overall_options & PCRE2_ANCHORED) == 0) } } else - { CMPTO(SLJIT_LESS, STR_PTR, 0, (common->match_end_ptr == 0) ? STR_END : TMP1, 0, mainloop_label); - } } /* No more remaining characters. */ @@ -11237,7 +11235,7 @@ if (common->might_be_empty) { JUMPHERE(empty_match); OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV_UI, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options)); + OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options)); OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY); JUMPTO(SLJIT_NOT_ZERO, empty_match_backtrack_label); OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART); diff --git a/pcre2-10.21/src/pcre2_jit_match.c b/pcre2-10.22/src/pcre2_jit_match.c similarity index 99% rename from pcre2-10.21/src/pcre2_jit_match.c rename to pcre2-10.22/src/pcre2_jit_match.c index d804cfea4..a323971ff 100644 --- a/pcre2-10.21/src/pcre2_jit_match.c +++ b/pcre2-10.22/src/pcre2_jit_match.c @@ -46,7 +46,7 @@ POSSIBILITY OF SUCH DAMAGE. static SLJIT_NOINLINE int jit_machine_stack_exec(jit_arguments *arguments, jit_function executable_func) { -sljit_ub local_space[MACHINE_STACK_SIZE]; +sljit_u8 local_space[MACHINE_STACK_SIZE]; struct sljit_stack local_stack; local_stack.top = (sljit_sw)&local_space; diff --git a/pcre2-10.21/src/pcre2_jit_misc.c b/pcre2-10.22/src/pcre2_jit_misc.c similarity index 100% rename from pcre2-10.21/src/pcre2_jit_misc.c rename to pcre2-10.22/src/pcre2_jit_misc.c diff --git a/pcre2-10.21/src/pcre2_jit_test.c b/pcre2-10.22/src/pcre2_jit_test.c similarity index 99% rename from pcre2-10.21/src/pcre2_jit_test.c rename to pcre2-10.22/src/pcre2_jit_test.c index 78837cf56..705ba181e 100644 --- a/pcre2-10.21/src/pcre2_jit_test.c +++ b/pcre2-10.22/src/pcre2_jit_test.c @@ -140,7 +140,6 @@ int main(void) #define F_DIFF 0x080000 #define F_FORCECONV 0x100000 #define F_PROPERTY 0x200000 -#define F_STUDY 0x400000 struct regression_test_case { int compile_options; @@ -693,6 +692,7 @@ static struct regression_test_case regression_test_cases[] = { { PCRE2_FIRSTLINE | PCRE2_DOTALL, PCRE2_NEWLINE_LF, 0, 0 | F_NOMATCH, "ab.", "ab" }, { MU | PCRE2_FIRSTLINE, A, 0, 1 | F_NOMATCH, "^[a-d0-9]", "\nxx\nd" }, { PCRE2_FIRSTLINE | PCRE2_DOTALL, PCRE2_NEWLINE_ANY, 0, 0, "....a", "012\n0a" }, + { MU | PCRE2_FIRSTLINE, A, 0, 0, "[aC]", "a" }, /* Recurse. */ { MU, A, 0, 0, "(a)(?1)", "aa" }, @@ -779,11 +779,11 @@ static struct regression_test_case regression_test_cases[] = { { MU, A, 0, 0, "(?(DEFINE)(a(*:aa)))a(?1)b|aac", "aac" }, { MU, A, 0, 0, "(a(*:aa)){0}(?:b(?1)b|c)+c", "babbab cc" }, { MU, A, 0, 0, "(a(*:aa)){0}(?:b(?1)b)+", "babba" }, - { MU, A, 0, 0 | F_NOMATCH | F_STUDY, "(a(*:aa)){0}(?:b(?1)b)+", "ba" }, + { MU, A, 0, 0 | F_NOMATCH, "(a(*:aa)){0}(?:b(?1)b)+", "ba" }, { MU, A, 0, 0, "(a\\K(*:aa)){0}(?:b(?1)b|c)+c", "babbab cc" }, { MU, A, 0, 0, "(a\\K(*:aa)){0}(?:b(?1)b)+", "babba" }, - { MU, A, 0, 0 | F_NOMATCH | F_STUDY, "(a\\K(*:aa)){0}(?:b(?1)b)+", "ba" }, - { MU, A, 0, 0 | F_NOMATCH | F_STUDY, "(*:mark)m", "a" }, + { MU, A, 0, 0 | F_NOMATCH, "(a\\K(*:aa)){0}(?:b(?1)b)+", "ba" }, + { MU, A, 0, 0 | F_NOMATCH, "(*:mark)m", "a" }, /* (*COMMIT) verb. */ { MU, A, 0, 0 | F_NOMATCH, "a(*COMMIT)b", "ac" }, @@ -1533,10 +1533,10 @@ static int regression_tests(void) is_successful = 0; } #endif -#if defined SUPPORT_PCRE2_16 && defined SUPPORT_PCRE2_16 - if (ovector16_1[i] != ovector16_2[i] || ovector16_1[i] != ovector16_1[i] || ovector16_1[i] != ovector16_2[i]) { - printf("\n16 and 16 bit: Ovector[%d] value differs(J16:%d,I16:%d,J32:%d,I32:%d): [%d] '%s' @ '%s' \n", - i, ovector16_1[i], ovector16_2[i], ovector16_1[i], ovector16_2[i], +#if defined SUPPORT_PCRE2_16 && defined SUPPORT_PCRE2_32 + if (ovector16_1[i] != ovector16_2[i] || ovector16_1[i] != ovector32_1[i] || ovector16_1[i] != ovector32_2[i]) { + printf("\n16 and 32 bit: Ovector[%d] value differs(J16:%d,I16:%d,J32:%d,I32:%d): [%d] '%s' @ '%s' \n", + i, ovector16_1[i], ovector16_2[i], ovector32_1[i], ovector32_2[i], total, current->pattern, current->input); is_successful = 0; } diff --git a/pcre2-10.21/src/pcre2_maketables.c b/pcre2-10.22/src/pcre2_maketables.c similarity index 100% rename from pcre2-10.21/src/pcre2_maketables.c rename to pcre2-10.22/src/pcre2_maketables.c diff --git a/pcre2-10.21/src/pcre2_match.c b/pcre2-10.22/src/pcre2_match.c similarity index 99% rename from pcre2-10.21/src/pcre2_match.c rename to pcre2-10.22/src/pcre2_match.c index f5275c7c4..0763a239e 100644 --- a/pcre2-10.21/src/pcre2_match.c +++ b/pcre2-10.22/src/pcre2_match.c @@ -55,7 +55,7 @@ POSSIBILITY OF SUCH DAMAGE. #define PUBLIC_MATCH_OPTIONS \ (PCRE2_ANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \ PCRE2_NOTEMPTY_ATSTART|PCRE2_NO_UTF_CHECK|PCRE2_PARTIAL_HARD| \ - PCRE2_PARTIAL_SOFT) + PCRE2_PARTIAL_SOFT|PCRE2_NO_JIT) #define PUBLIC_JIT_MATCH_OPTIONS \ (PCRE2_NO_UTF_CHECK|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY|\ @@ -465,7 +465,7 @@ Returns: a match() return code */ static int -#ifdef __GNUC__ +#if defined(__GNUC__) && !defined(__INTEL_COMPILER) __attribute__ ((noinline)) #endif op_recurse_ovecsave(REGISTER PCRE2_SPTR eptr, PCRE2_SPTR callpat, diff --git a/pcre2-10.21/src/pcre2_match_data.c b/pcre2-10.22/src/pcre2_match_data.c similarity index 100% rename from pcre2-10.21/src/pcre2_match_data.c rename to pcre2-10.22/src/pcre2_match_data.c diff --git a/pcre2-10.21/src/pcre2_newline.c b/pcre2-10.22/src/pcre2_newline.c similarity index 100% rename from pcre2-10.21/src/pcre2_newline.c rename to pcre2-10.22/src/pcre2_newline.c diff --git a/pcre2-10.21/src/pcre2_ord2utf.c b/pcre2-10.22/src/pcre2_ord2utf.c similarity index 100% rename from pcre2-10.21/src/pcre2_ord2utf.c rename to pcre2-10.22/src/pcre2_ord2utf.c diff --git a/pcre2-10.21/src/pcre2_pattern_info.c b/pcre2-10.22/src/pcre2_pattern_info.c similarity index 100% rename from pcre2-10.21/src/pcre2_pattern_info.c rename to pcre2-10.22/src/pcre2_pattern_info.c diff --git a/pcre2-10.21/src/pcre2_printint.c b/pcre2-10.22/src/pcre2_printint.c similarity index 99% rename from pcre2-10.21/src/pcre2_printint.c rename to pcre2-10.22/src/pcre2_printint.c index 40a633cfd..2d30926a7 100644 --- a/pcre2-10.21/src/pcre2_printint.c +++ b/pcre2-10.22/src/pcre2_printint.c @@ -214,7 +214,7 @@ while (*ptr != '\0') static void print_custring_bylen(FILE *f, PCRE2_SPTR ptr, PCRE2_UCHAR len) { -while (len-- > 0) +for (; len > 0; len--) { register uint32_t c = *ptr++; if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x{%x}", c); diff --git a/pcre2-10.21/src/pcre2_serialize.c b/pcre2-10.22/src/pcre2_serialize.c similarity index 96% rename from pcre2-10.21/src/pcre2_serialize.c rename to pcre2-10.22/src/pcre2_serialize.c index 8c44acfdc..0af26d8fc 100644 --- a/pcre2-10.21/src/pcre2_serialize.c +++ b/pcre2-10.22/src/pcre2_serialize.c @@ -158,6 +158,7 @@ int32_t i, j; if (data == NULL || codes == NULL) return PCRE2_ERROR_NULL; if (number_of_codes <= 0) return PCRE2_ERROR_BADDATA; +if (data->number_of_codes <= 0) return PCRE2_ERROR_BADSERIALIZEDDATA; if (data->magic != SERIALIZED_DATA_MAGIC) return PCRE2_ERROR_BADMAGIC; if (data->version != SERIALIZED_DATA_VERSION) return PCRE2_ERROR_BADMODE; if (data->config != SERIALIZED_DATA_CONFIG) return PCRE2_ERROR_BADMODE; @@ -188,6 +189,8 @@ for (i = 0; i < number_of_codes; i++) CODE_BLOCKSIZE_TYPE blocksize; memcpy(&blocksize, src_bytes + offsetof(pcre2_real_code, blocksize), sizeof(CODE_BLOCKSIZE_TYPE)); + if (blocksize <= sizeof(pcre2_real_code)) + return PCRE2_ERROR_BADSERIALIZEDDATA; /* The allocator provided by gcontext replaces the original one. */ @@ -208,6 +211,10 @@ for (i = 0; i < number_of_codes; i++) memcpy(((uint8_t *)dst_re) + sizeof(pcre2_memctl), src_bytes + sizeof(pcre2_memctl), blocksize - sizeof(pcre2_memctl)); + if (dst_re->magic_number != MAGIC_NUMBER || + dst_re->name_entry_size > MAX_NAME_SIZE + IMM2_SIZE + 1 || + dst_re->name_count > MAX_NAME_COUNT) + return PCRE2_ERROR_BADSERIALIZEDDATA; /* At the moment only one table is supported. */ diff --git a/pcre2-10.21/src/pcre2_string_utils.c b/pcre2-10.22/src/pcre2_string_utils.c similarity index 100% rename from pcre2-10.21/src/pcre2_string_utils.c rename to pcre2-10.22/src/pcre2_string_utils.c diff --git a/pcre2-10.21/src/pcre2_study.c b/pcre2-10.22/src/pcre2_study.c similarity index 99% rename from pcre2-10.21/src/pcre2_study.c rename to pcre2-10.22/src/pcre2_study.c index 18932adef..db0826674 100644 --- a/pcre2-10.21/src/pcre2_study.c +++ b/pcre2-10.22/src/pcre2_study.c @@ -1452,7 +1452,7 @@ do for (c = 0; c < 16; c++) re->start_bitmap[c] |= classmap[c]; for (c = 128; c < 256; c++) { - if ((classmap[c/8] && (1 << (c&7))) != 0) + if ((classmap[c/8] & (1 << (c&7))) != 0) { int d = (c >> 6) | 0xc0; /* Set bit for this starter */ re->start_bitmap[d/8] |= (1 << (d&7)); /* and then skip on to the */ diff --git a/pcre2-10.21/src/pcre2_substitute.c b/pcre2-10.22/src/pcre2_substitute.c similarity index 100% rename from pcre2-10.21/src/pcre2_substitute.c rename to pcre2-10.22/src/pcre2_substitute.c diff --git a/pcre2-10.21/src/pcre2_substring.c b/pcre2-10.22/src/pcre2_substring.c similarity index 98% rename from pcre2-10.21/src/pcre2_substring.c rename to pcre2-10.22/src/pcre2_substring.c index 58b504d5c..f6d7c3972 100644 --- a/pcre2-10.21/src/pcre2_substring.c +++ b/pcre2-10.22/src/pcre2_substring.c @@ -240,8 +240,11 @@ Returns: nothing PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION pcre2_substring_free(PCRE2_UCHAR *string) { -pcre2_memctl *memctl = (pcre2_memctl *)((char *)string - sizeof(pcre2_memctl)); -memctl->free(memctl, memctl->memory_data); +if (string != NULL) + { + pcre2_memctl *memctl = (pcre2_memctl *)((char *)string - sizeof(pcre2_memctl)); + memctl->free(memctl, memctl->memory_data); + } } @@ -436,8 +439,11 @@ Returns: nothing PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION pcre2_substring_list_free(PCRE2_SPTR *list) { -pcre2_memctl *memctl = (pcre2_memctl *)((char *)list - sizeof(pcre2_memctl)); -memctl->free(memctl, memctl->memory_data); +if (list != NULL) + { + pcre2_memctl *memctl = (pcre2_memctl *)((char *)list - sizeof(pcre2_memctl)); + memctl->free(memctl, memctl->memory_data); + } } diff --git a/pcre2-10.21/src/pcre2_tables.c b/pcre2-10.22/src/pcre2_tables.c similarity index 100% rename from pcre2-10.21/src/pcre2_tables.c rename to pcre2-10.22/src/pcre2_tables.c diff --git a/pcre2-10.21/src/pcre2_ucd.c b/pcre2-10.22/src/pcre2_ucd.c similarity index 100% rename from pcre2-10.21/src/pcre2_ucd.c rename to pcre2-10.22/src/pcre2_ucd.c diff --git a/pcre2-10.21/src/pcre2_ucp.h b/pcre2-10.22/src/pcre2_ucp.h similarity index 100% rename from pcre2-10.21/src/pcre2_ucp.h rename to pcre2-10.22/src/pcre2_ucp.h diff --git a/pcre2-10.21/src/pcre2_valid_utf.c b/pcre2-10.22/src/pcre2_valid_utf.c similarity index 100% rename from pcre2-10.21/src/pcre2_valid_utf.c rename to pcre2-10.22/src/pcre2_valid_utf.c diff --git a/pcre2-10.21/src/pcre2_xclass.c b/pcre2-10.22/src/pcre2_xclass.c similarity index 100% rename from pcre2-10.21/src/pcre2_xclass.c rename to pcre2-10.22/src/pcre2_xclass.c diff --git a/pcre2-10.21/src/pcre2demo.c b/pcre2-10.22/src/pcre2demo.c similarity index 88% rename from pcre2-10.21/src/pcre2demo.c rename to pcre2-10.22/src/pcre2demo.c index ec51cf11c..8ae49f100 100644 --- a/pcre2-10.21/src/pcre2demo.c +++ b/pcre2-10.22/src/pcre2demo.c @@ -3,28 +3,31 @@ *************************************************/ /* This is a demonstration program to illustrate a straightforward way of -calling the PCRE2 regular expression library from a C program. See the +using the PCRE2 regular expression library from a C program. See the pcre2sample documentation for a short discussion ("man pcre2sample" if you have the PCRE2 man pages installed). PCRE2 is a revised API for the library, and is incompatible with the original PCRE API. There are actually three libraries, each supporting a different code unit -width. This demonstration program uses the 8-bit library. +width. This demonstration program uses the 8-bit library. The default is to +process each code unit as a separate character, but if the pattern begins with +"(*UTF)", both it and the subject are treated as UTF-8 strings, where +characters may occupy multiple code units. In Unix-like environments, if PCRE2 is installed in your standard system libraries, you should be able to compile this program using this command: -gcc -Wall pcre2demo.c -lpcre2-8 -o pcre2demo +cc -Wall pcre2demo.c -lpcre2-8 -o pcre2demo If PCRE2 is not installed in a standard place, it is likely to be installed with support for the pkg-config mechanism. If you have pkg-config, you can compile this program using this command: -gcc -Wall pcre2demo.c `pkg-config --cflags --libs libpcre2-8` -o pcre2demo +cc -Wall pcre2demo.c `pkg-config --cflags --libs libpcre2-8` -o pcre2demo -If you do not have pkg-config, you may have to use this: +If you do not have pkg-config, you may have to use something like this: -gcc -Wall pcre2demo.c -I/usr/local/include -L/usr/local/lib \ +cc -Wall pcre2demo.c -I/usr/local/include -L/usr/local/lib \ -R/usr/local/lib -lpcre2-8 -o pcre2demo Replace "/usr/local/include" and "/usr/local/lib" with wherever the include and @@ -39,9 +42,14 @@ the following line. */ /* #define PCRE2_STATIC */ -/* This macro must be defined before including pcre2.h. For a program that uses -only one code unit width, it makes it possible to use generic function names -such as pcre2_compile(). */ +/* The PCRE2_CODE_UNIT_WIDTH macro must be defined before including pcre2.h. +For a program that uses only one code unit width, setting it to 8, 16, or 32 +makes it possible to use generic function names such as pcre2_compile(). Note +that just changing 8 to 16 (for example) is not sufficient to convert this +program to process 16-bit characters. Even in a fully 16-bit environment, where +string-handling functions such as strcmp() and printf() work with 16-bit +characters, the code for handling the table of named substrings will still need +to be modified. */ #define PCRE2_CODE_UNIT_WIDTH 8 @@ -62,19 +70,19 @@ int main(int argc, char **argv) { pcre2_code *re; PCRE2_SPTR pattern; /* PCRE2_SPTR is a pointer to unsigned code units of */ -PCRE2_SPTR subject; /* the appropriate width (8, 16, or 32 bits). */ +PCRE2_SPTR subject; /* the appropriate width (in this case, 8 bits). */ PCRE2_SPTR name_table; int crlf_is_newline; int errornumber; int find_all; int i; -int namecount; -int name_entry_size; int rc; int utf8; uint32_t option_bits; +uint32_t namecount; +uint32_t name_entry_size; uint32_t newline; PCRE2_SIZE erroroffset; @@ -89,15 +97,19 @@ pcre2_match_data *match_data; * First, sort out the command line. There is only one possible option at * * the moment, "-g" to request repeated matching to find all occurrences, * * like Perl's /g option. We set the variable find_all to a non-zero value * -* if the -g option is present. Apart from that, there must be exactly two * -* arguments. * +* if the -g option is present. * **************************************************************************/ find_all = 0; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-g") == 0) find_all = 1; - else break; + else if (argv[i][0] == '-') + { + printf("Unrecognised option %s\n", argv[i]); + return 1; + } + else break; } /* After the options, we require exactly two arguments, which are the pattern, @@ -105,7 +117,7 @@ and the subject string. */ if (argc - i != 2) { - printf("Two arguments required: a regex and a subject string\n"); + printf("Exactly two arguments required: a regex and a subject string\n"); return 1; } @@ -184,7 +196,7 @@ if (rc < 0) stored. */ ovector = pcre2_get_ovector_pointer(match_data); -printf("\nMatch succeeded at offset %d\n", (int)ovector[0]); +printf("Match succeeded at offset %d\n", (int)ovector[0]); /************************************************************************* @@ -225,7 +237,7 @@ we have to extract the count of named parentheses from the pattern. */ PCRE2_INFO_NAMECOUNT, /* get the number of named substrings */ &namecount); /* where to put the answer */ -if (namecount <= 0) printf("No named substrings\n"); else +if (namecount == 0) printf("No named substrings\n"); else { PCRE2_SPTR tabptr; printf("Named substrings\n"); @@ -313,8 +325,8 @@ crlf_is_newline = newline == PCRE2_NEWLINE_ANY || for (;;) { - uint32_t options = 0; /* Normally no options */ - PCRE2_SIZE start_offset = ovector[1]; /* Start at end of previous match */ + uint32_t options = 0; /* Normally no options */ + PCRE2_SIZE start_offset = ovector[1]; /* Start at end of previous match */ /* If the previous match was for an empty string, we are finished if we are at the end of the subject. Otherwise, arrange to run another match at the @@ -354,7 +366,7 @@ for (;;) { if (options == 0) break; /* All matches found */ ovector[1] = start_offset + 1; /* Advance one code unit */ - if (crlf_is_newline && /* If CRLF is newline & */ + if (crlf_is_newline && /* If CRLF is a newline & */ start_offset < subject_length - 1 && /* we are at CRLF, */ subject[start_offset] == '\r' && subject[start_offset + 1] == '\n') @@ -400,7 +412,7 @@ for (;;) printf("%2d: %.*s\n", i, (int)substring_length, (char *)substring_start); } - if (namecount <= 0) printf("No named substrings\n"); else + if (namecount == 0) printf("No named substrings\n"); else { PCRE2_SPTR tabptr = name_table; printf("Named substrings\n"); diff --git a/pcre2-10.21/src/pcre2grep.c b/pcre2-10.22/src/pcre2grep.c similarity index 89% rename from pcre2-10.21/src/pcre2grep.c rename to pcre2-10.22/src/pcre2grep.c index aadb22a57..49747c0c3 100644 --- a/pcre2-10.21/src/pcre2grep.c +++ b/pcre2-10.22/src/pcre2grep.c @@ -58,6 +58,15 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#if defined(_WIN32) || defined(WIN32) +#include /* For _setmode() */ +#include /* For _O_BINARY */ +#endif + +#ifdef SUPPORT_PCRE2GREP_CALLOUT +#include +#endif + #ifdef HAVE_UNISTD_H #include #endif @@ -121,6 +130,17 @@ apply to fprintf(). */ #define FWRITE(a,b,c,d) if (fwrite(a,b,c,d)) {} +/* Under Windows, we have to set stdout to be binary, so that it does not +convert \r\n at the ends of output lines to \r\r\n. However, that means that +any messages written to stdout must have \r\n as their line terminator. This is +handled by using STDOUT_NL as the newline string. */ + +#if defined(_WIN32) || defined(WIN32) +#define STDOUT_NL "\r\n" +#else +#define STDOUT_NL "\n" +#endif + /************************************************* @@ -885,27 +905,34 @@ help(void) { option_item *op; -printf("Usage: pcre2grep [OPTION]... [PATTERN] [FILE1 FILE2 ...]\n"); -printf("Search for PATTERN in each FILE or standard input.\n"); -printf("PATTERN must be present if neither -e nor -f is used.\n"); -printf("\"-\" can be used as a file name to mean STDIN.\n"); +printf("Usage: pcre2grep [OPTION]... [PATTERN] [FILE1 FILE2 ...]" STDOUT_NL); +printf("Search for PATTERN in each FILE or standard input." STDOUT_NL); +printf("PATTERN must be present if neither -e nor -f is used." STDOUT_NL); + +#ifdef SUPPORT_PCRE2GREP_CALLOUT +printf("Callout scripts in patterns are supported." STDOUT_NL); +#else +printf("Callout scripts are not supported in this pcre2grep." STDOUT_NL); +#endif + +printf("\"-\" can be used as a file name to mean STDIN." STDOUT_NL); #ifdef SUPPORT_LIBZ -printf("Files whose names end in .gz are read using zlib.\n"); +printf("Files whose names end in .gz are read using zlib." STDOUT_NL); #endif #ifdef SUPPORT_LIBBZ2 -printf("Files whose names end in .bz2 are read using bzlib2.\n"); +printf("Files whose names end in .bz2 are read using bzlib2." STDOUT_NL); #endif #if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2 -printf("Other files and the standard input are read as plain files.\n\n"); +printf("Other files and the standard input are read as plain files." STDOUT_NL STDOUT_NL); #else -printf("All files are read as plain files, without any interpretation.\n\n"); +printf("All files are read as plain files, without any interpretation." STDOUT_NL STDOUT_NL); #endif -printf("Example: pcre2grep -i 'hello.*world' menu.h main.c\n\n"); -printf("Options:\n"); +printf("Example: pcre2grep -i 'hello.*world' menu.h main.c" STDOUT_NL STDOUT_NL); +printf("Options:" STDOUT_NL); for (op = optionlist; op->one_char != 0; op++) { @@ -922,17 +949,17 @@ for (op = optionlist; op->one_char != 0; op++) } if (n < 1) n = 1; - printf("%.*s%s\n", n, " ", op->help_text); + printf("%.*s%s" STDOUT_NL, n, " ", op->help_text); } -printf("\nNumbers may be followed by K or M, e.g. --buffer-size=100K.\n"); -printf("The default value for --buffer-size is %d.\n", PCRE2GREP_BUFSIZE); -printf("When reading patterns or file names from a file, trailing white\n"); -printf("space is removed and blank lines are ignored.\n"); -printf("The maximum size of any pattern is %d bytes.\n", MAXPATLEN); +printf(STDOUT_NL "Numbers may be followed by K or M, e.g. --buffer-size=100K." STDOUT_NL); +printf("The default value for --buffer-size is %d." STDOUT_NL, PCRE2GREP_BUFSIZE); +printf("When reading patterns or file names from a file, trailing white" STDOUT_NL); +printf("space is removed and blank lines are ignored." STDOUT_NL); +printf("The maximum size of any pattern is %d bytes." STDOUT_NL, MAXPATLEN); -printf("\nWith no FILEs, read standard input. If fewer than two FILEs given, assume -h.\n"); -printf("Exit status is 0 if any matches, 1 if no matches, and 2 if trouble.\n"); +printf(STDOUT_NL "With no FILEs, read standard input. If fewer than two FILEs given, assume -h." STDOUT_NL); +printf("Exit status is 0 if any matches, 1 if no matches, and 2 if trouble." STDOUT_NL); } @@ -1473,6 +1500,274 @@ return FALSE; /* No match, no errors */ } +#ifdef SUPPORT_PCRE2GREP_CALLOUT + +/************************************************* +* Parse and execute callout scripts * +*************************************************/ + +/* This function parses a callout string block and executes the +program specified by the string. The string is a list of substrings +separated by pipe characters. The first substring represents the +executable name, and the following substrings specify the arguments: + + program_name|param1|param2|... + +Any substirng (including the program name) can contain escape sequences +started by the dollar character. The escape sequences are substituted as +follows: + + $ or ${} is replaced by the captured substring of the given + decimal number, which must be greater than zero. If the number is greater + than the number of capturing substrings, or if the capture is unset, the + replacement is empty. + + Any other character is substituted by itself. E.g: $$ is replaced by a single + dollar or $| replaced by a pipe character. + +Example: + + echo -e "abcde\n12345" | pcre2grep \ + '(.)(..(.))(?C"/bin/echo|Arg1: [$1] [$2] [$3]|Arg2: $|${1}$| ($4)")()' - + + Output: + + Arg1: [a] [bcd] [d] Arg2: |a| () + abcde + Arg1: [1] [234] [4] Arg2: |1| () + 12345 + +Arguments: + blockptr the callout block + +Returns: currently it always returns with 0 +*/ + +static int +pcre2grep_callout(pcre2_callout_block *calloutptr, void *unused) +{ +PCRE2_SIZE length = calloutptr->callout_string_length; +PCRE2_SPTR string = calloutptr->callout_string; +PCRE2_SPTR subject = calloutptr->subject; +PCRE2_SIZE *ovector = calloutptr->offset_vector; +PCRE2_SIZE capture_top = calloutptr->capture_top; +PCRE2_SIZE argsvectorlen = 2; +PCRE2_SIZE argslen = 1; +char *args; +char *argsptr; +char **argsvector; +char **argsvectorptr; +pid_t pid; +int result = 0; + +(void)unused; /* Avoid compiler warning */ + +/* Only callout with strings are supported. */ +if (string == NULL || length == 0) return 0; + +/* Checking syntax and compute the number of string fragments. Callout strings +are ignored in case of a syntax error. */ + +while (length > 0) + { + if (*string == '|') + { + argsvectorlen++; + + /* Maximum 10000 arguments allowed. */ + if (argsvectorlen > 10000) return 0; + } + else if (*string == '$') + { + PCRE2_SIZE capture_id = 0; + + string++; + length--; + + /* Syntax error: a character must be present after $. */ + if (length == 0) return 0; + + if (*string >= '1' && *string <= '9') + { + do + { + /* Maximum capture id is 65535. */ + if (capture_id <= 65535) + capture_id = capture_id * 10 + (*string - '0'); + + string++; + length--; + } + while (length > 0 && *string >= '0' && *string <= '9'); + + /* To negate the effect of string++ below. */ + string--; + length++; + } + else if (*string == '{') + { + /* Must be a decimal number in parenthesis, e.g: (5) or (38) */ + string++; + length--; + + /* Syntax error: a decimal number required. */ + if (length == 0) return 0; + if (*string < '1' || *string > '9') return 0; + + do + { + /* Maximum capture id is 65535. */ + if (capture_id <= 65535) + capture_id = capture_id * 10 + (*string - '0'); + + string++; + length--; + + /* Syntax error: no more characters */ + if (length == 0) return 0; + } + while (*string >= '0' && *string <= '9'); + + /* Syntax error: close paren is missing. */ + if (*string != '}') return 0; + } + + if (capture_id > 0) + { + if (capture_id < capture_top) + { + capture_id *= 2; + argslen += ovector[capture_id + 1] - ovector[capture_id]; + } + + /* To negate the effect of argslen++ below. */ + argslen--; + } + } + + string++; + length--; + argslen++; + } + +args = (char*)malloc(argslen); +if (args == NULL) return 0; + +argsvector = (char**)malloc(argsvectorlen * sizeof(char*)); +if (argsvector == NULL) + { + free(args); + return 0; + } + +argsptr = args; +argsvectorptr = argsvector; + +*argsvectorptr++ = argsptr; + +length = calloutptr->callout_string_length; +string = calloutptr->callout_string; + +while (length > 0) + { + if (*string == '|') + { + *argsptr++ = '\0'; + *argsvectorptr++ = argsptr; + } + else if (*string == '$') + { + string++; + length--; + + if ((*string >= '1' && *string <= '9') || *string == '{') + { + PCRE2_SIZE capture_id = 0; + + if (*string != '{') + { + do + { + /* Maximum capture id is 65535. */ + if (capture_id <= 65535) + capture_id = capture_id * 10 + (*string - '0'); + + string++; + length--; + } + while (length > 0 && *string >= '0' && *string <= '9'); + + /* To negate the effect of string++ below. */ + string--; + length++; + } + else + { + string++; + length--; + + do + { + /* Maximum capture id is 65535. */ + if (capture_id <= 65535) + capture_id = capture_id * 10 + (*string - '0'); + + string++; + length--; + } + while (*string != '}'); + } + + if (capture_id < capture_top) + { + PCRE2_SIZE capturesize; + capture_id *= 2; + + capturesize = ovector[capture_id + 1] - ovector[capture_id]; + memcpy(argsptr, subject + ovector[capture_id], capturesize); + argsptr += capturesize; + } + } + else + { + *argsptr++ = *string; + } + } + else + { + *argsptr++ = *string; + } + + string++; + length--; + } + +*argsptr++ = '\0'; +*argsvectorptr = NULL; + +pid = fork(); + +if (pid == 0) + { + (void)execv(argsvector[0], argsvector); + /* Control gets here if there is an error, e.g. a non-existent program */ + exit(1); + } +else if (pid > 0) + (void)waitpid(pid, &result, 0); + +free(args); +free(argsvector); + +/* Currently negative return values are not supported, only zero (match +continues) or non-zero (match fails). */ + +return result != 0; +} + +#endif + + /************************************************* * Grep an individual file * @@ -1591,7 +1886,7 @@ while (ptr < endptr) size_t startoffset = 0; /* At this point, ptr is at the start of a line. We need to find the length - of the subject string to pass to pcre_exec(). In multiline mode, it is the + of the subject string to pass to pcre2_match(). In multiline mode, it is the length remainder of the data in the buffer. Otherwise, it is the length of the next line, excluding the terminating newline. After matching, we always advance by the length of the next line. In multiline mode the PCRE2_FIRSTLINE @@ -1609,10 +1904,12 @@ while (ptr < endptr) if (endlinelength == 0 && t == main_buffer + bufsize) { fprintf(stderr, "pcre2grep: line %d%s%s is too long for the internal buffer\n" - "pcre2grep: check the --buffer-size option\n", + "pcre2grep: the buffer size is %d\n" + "pcre2grep: use the --buffer-size option to change it\n", linenumber, (filename == NULL)? "" : " of file ", - (filename == NULL)? "" : filename); + (filename == NULL)? "" : filename, + bufthird); return 2; } @@ -1705,7 +2002,7 @@ while (ptr < endptr) else if (binary) { - fprintf(stdout, "Binary file %s matches\n", filename); + fprintf(stdout, "Binary file %s matches" STDOUT_NL, filename); return 0; } @@ -1714,7 +2011,7 @@ while (ptr < endptr) else if (filenames == FN_MATCH_ONLY) { - fprintf(stdout, "%s\n", printname); + fprintf(stdout, "%s" STDOUT_NL, printname); return 0; } @@ -1739,13 +2036,13 @@ while (ptr < endptr) /* Handle --line-offsets */ if (line_offsets) - fprintf(stdout, "%d,%d\n", (int)(matchptr + offsets[0] - ptr), + fprintf(stdout, "%d,%d" STDOUT_NL, (int)(matchptr + offsets[0] - ptr), (int)(offsets[1] - offsets[0])); /* Handle --file-offsets */ else if (file_offsets) - fprintf(stdout, "%d,%d\n", + fprintf(stdout, "%d,%d" STDOUT_NL, (int)(filepos + matchptr + offsets[0] - ptr), (int)(offsets[1] - offsets[0])); @@ -1773,17 +2070,26 @@ while (ptr < endptr) } } - if (printed || printname != NULL || number) fprintf(stdout, "\n"); + if (printed || printname != NULL || number) + fprintf(stdout, STDOUT_NL); } - /* Prepare to repeat to find the next match. If the pattern contained a - lookbehind that included \K, it is possible that the end of the match - might be at or before the actual starting offset we have just used. In - this case, start one character further on. */ + /* Prepare to repeat to find the next match in the line. */ match = FALSE; if (line_buffered) fflush(stdout); rc = 0; /* Had some success */ + + /* If the current match ended past the end of the line (only possible + in multiline mode), we are done with this line. */ + + if (offsets[1] > linelength) goto END_ONE_MATCH; + + /* If the pattern contained a lookbehind that included \K, it is + possible that the end of the match might be at or before the actual + starting offset we have just used. In this case, start one character + further on. */ + startoffset = offsets[1]; /* Restart after the match */ oldstartoffset = pcre2_get_startchar(match_data); if (startoffset <= oldstartoffset) @@ -1838,7 +2144,7 @@ while (ptr < endptr) if (hyphenpending) { - fprintf(stdout, "--\n"); + fprintf(stdout, "--" STDOUT_NL); hyphenpending = FALSE; hyphenprinted = TRUE; } @@ -1859,7 +2165,7 @@ while (ptr < endptr) } if (lastmatchnumber > 0 && p > lastmatchrestart && !hyphenprinted) - fprintf(stdout, "--\n"); + fprintf(stdout, "--" STDOUT_NL); while (p < ptr) { @@ -2063,7 +2369,7 @@ were none. If we found a match, we won't have got this far. */ if (filenames == FN_NOMATCH_ONLY) { - fprintf(stdout, "%s\n", printname); + fprintf(stdout, "%s" STDOUT_NL, printname); return 0; } @@ -2075,7 +2381,7 @@ if (count_only && !quiet) { if (printname != NULL && filenames != FN_NONE) fprintf(stdout, "%s:", printname); - fprintf(stdout, "%d\n", count); + fprintf(stdout, "%d" STDOUT_NL, count); } } @@ -2396,7 +2702,7 @@ switch(letter) { unsigned char buffer[128]; (void)pcre2_config(PCRE2_CONFIG_VERSION, buffer); - fprintf(stdout, "pcre2grep version %s\n", buffer); + fprintf(stdout, "pcre2grep version %s" STDOUT_NL, buffer); } pcre2grep_exit(0); break; @@ -2488,11 +2794,26 @@ if ((popts & PO_FIXED_STRINGS) != 0) } sprintf((char *)buffer, "%s%.*s%s", prefix[popts], patlen, ps, suffix[popts]); -p->compiled = pcre2_compile(buffer, -1, options, &errcode, &erroffset, - compile_context); -if (p->compiled != NULL) return TRUE; +p->compiled = pcre2_compile(buffer, PCRE2_ZERO_TERMINATED, options, &errcode, + &erroffset, compile_context); -/* Handle compile errors */ +/* Handle successful compile */ + +if (p->compiled != NULL) + { +#ifdef SUPPORT_PCRE2GREP_JIT + if (use_jit) + { + errcode = pcre2_jit_compile(p->compiled, PCRE2_JIT_COMPLETE); + if (errcode == 0) return TRUE; + erroffset = PCRE2_SIZE_MAX; /* Will get reduced to patlen below */ + } + else +#endif + return TRUE; + } + +/* Handle compile and JIT compile errors */ erroffset -= (int)strlen(prefix[popts]); if (erroffset > patlen) erroffset = patlen; @@ -2623,6 +2944,16 @@ const char *locale_from = "--locale"; pcre2_jit_stack *jit_stack = NULL; #endif +/* In Windows, stdout is set up as a text stream, which means that \n is +converted to \r\n. This causes output lines that are copied from the input to +change from ....\r\n to ....\r\r\n, which is not right. We therefore ensure +that stdout is a binary stream. Note that this means all other output to stdout +must use STDOUT_NL to terminate lines. */ + +#if defined(_WIN32) || defined(WIN32) +_setmode( _fileno(stdout), _O_BINARY); +#endif + /* Set up a default compile and match contexts and a match data block. */ compile_context = pcre2_compile_context_create(NULL); @@ -2630,6 +2961,13 @@ match_context = pcre2_match_context_create(NULL); match_data = pcre2_match_data_create(OFFSET_SIZE, NULL); offsets = pcre2_get_ovector_pointer(match_data); +/* If string (script) callouts are supported, set up the callout processing +function. */ + +#ifdef SUPPORT_PCRE2GREP_CALLOUT +pcre2_set_callout(match_context, pcre2grep_callout, NULL); +#endif + /* Process the options */ for (i = 1; i < argc; i++) diff --git a/pcre2-10.21/src/pcre2posix.c b/pcre2-10.22/src/pcre2posix.c similarity index 87% rename from pcre2-10.21/src/pcre2posix.c rename to pcre2-10.22/src/pcre2posix.c index 1d6e5b797..e7cf9c294 100644 --- a/pcre2-10.21/src/pcre2posix.c +++ b/pcre2-10.22/src/pcre2posix.c @@ -58,16 +58,49 @@ previously been set. */ # define PCRE2POSIX_EXP_DEFN __declspec(dllexport) #endif -/* We include pcre2.h before pcre2_internal.h so that the PCRE2 library -functions are declared as "import" for Windows by defining PCRE2_EXP_DECL as -"import". This is needed even though pcre2_internal.h itself includes pcre2.h, -because it does so after it has set PCRE2_EXP_DECL to "export" if it is not -already set. */ +/* Older versions of MSVC lack snprintf(). This define allows for +warning/error-free compilation and testing with MSVC compilers back to at least +MSVC 10/2010. Except for VC6 (which is missing some fundamentals and fails). */ + +#if defined(_MSC_VER) && (_MSC_VER < 1900) +#define snprintf _snprintf +#endif + + +/* Compile-time error numbers start at this value. It should probably never be +changed. This #define is a copy of the one in pcre2_internal.h. */ + +#define COMPILE_ERROR_BASE 100 + + +/* Standard C headers */ + +#include +#include +#include +#include +#include +#include + +/* PCRE2 headers */ #include "pcre2.h" -#include "pcre2_internal.h" #include "pcre2posix.h" +/* When compiling with the MSVC compiler, it is sometimes necessary to include +a "calling convention" before exported function names. (This is secondhand +information; I know nothing about MSVC myself). For example, something like + + void __cdecl function(....) + +might be needed. In order so make this easy, all the exported functions have +PCRE2_CALL_CONVENTION just before their names. It is rarely needed; if not +set, we ensure here that it has no effect. */ + +#ifndef PCRE2_CALL_CONVENTION +#define PCRE2_CALL_CONVENTION +#endif + /* Table to translate PCRE2 compile time error codes into POSIX error codes. Only a few PCRE2 errors with a value greater than 23 turn into special POSIX codes: most go to REG_BADPAT. The second table lists, in pairs, those that @@ -205,11 +238,11 @@ int re_nsub = 0; if ((cflags & REG_ICASE) != 0) options |= PCRE2_CASELESS; if ((cflags & REG_NEWLINE) != 0) options |= PCRE2_MULTILINE; if ((cflags & REG_DOTALL) != 0) options |= PCRE2_DOTALL; -if ((cflags & REG_NOSUB) != 0) options |= PCRE2_NO_AUTO_CAPTURE; if ((cflags & REG_UTF) != 0) options |= PCRE2_UTF; if ((cflags & REG_UCP) != 0) options |= PCRE2_UCP; if ((cflags & REG_UNGREEDY) != 0) options |= PCRE2_UNGREEDY; +preg->re_cflags = cflags; preg->re_pcre2_code = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, options, &errorcode, &erroffset, NULL); preg->re_erroffset = erroffset; @@ -234,7 +267,6 @@ if (preg->re_pcre2_code == NULL) (void)pcre2_pattern_info((const pcre2_code *)preg->re_pcre2_code, PCRE2_INFO_CAPTURECOUNT, &re_nsub); preg->re_nsub = (size_t)re_nsub; -if ((options & PCRE2_NO_AUTO_CAPTURE) != 0) re_nsub = -1; preg->re_match_data = pcre2_match_data_create(re_nsub + 1, NULL); if (preg->re_match_data == NULL) @@ -272,11 +304,11 @@ if ((eflags & REG_NOTEMPTY) != 0) options |= PCRE2_NOTEMPTY; ((regex_t *)preg)->re_erroffset = (size_t)(-1); /* Only has meaning after compile */ -/* When no string data is being returned, or no vector has been passed in which -to put it, ensure that nmatch is zero. */ +/* When REG_NOSUB was specified, or if no vector has been passed in which to +put captured strings, ensure that nmatch is zero. This will stop any attempt to +write to pmatch. */ -if ((((pcre2_real_code *)(preg->re_pcre2_code))->compile_options & - PCRE2_NO_AUTO_CAPTURE) != 0 || pmatch == NULL) nmatch = 0; +if ((preg->re_cflags & REG_NOSUB) != 0 || pmatch == NULL) nmatch = 0; /* REG_STARTEND is a BSD extension, to allow for non-NUL-terminated strings. The man page from OS X says "REG_STARTEND affects only the location of the @@ -303,11 +335,12 @@ rc = pcre2_match((const pcre2_code *)preg->re_pcre2_code, if (rc >= 0) { size_t i; + PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(md); if ((size_t)rc > nmatch) rc = (int)nmatch; for (i = 0; i < (size_t)rc; i++) { - pmatch[i].rm_so = md->ovector[i*2]; - pmatch[i].rm_eo = md->ovector[i*2+1]; + pmatch[i].rm_so = ovector[i*2]; + pmatch[i].rm_eo = ovector[i*2+1]; } for (; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1; return 0; diff --git a/pcre2-10.21/src/pcre2posix.h b/pcre2-10.22/src/pcre2posix.h similarity index 99% rename from pcre2-10.21/src/pcre2posix.h rename to pcre2-10.22/src/pcre2posix.h index 44a2fd8ad..5f2906a4f 100644 --- a/pcre2-10.21/src/pcre2posix.h +++ b/pcre2-10.22/src/pcre2posix.h @@ -98,6 +98,7 @@ typedef struct { void *re_match_data; size_t re_nsub; size_t re_erroffset; + int re_cflags; } regex_t; /* The structure in which a captured offset is returned. */ diff --git a/pcre2-10.21/src/pcre2test.c b/pcre2-10.22/src/pcre2test.c similarity index 95% rename from pcre2-10.21/src/pcre2test.c rename to pcre2-10.22/src/pcre2test.c index 0a5879e47..a8dffa372 100644 --- a/pcre2-10.21/src/pcre2test.c +++ b/pcre2-10.22/src/pcre2test.c @@ -353,7 +353,7 @@ typedef struct cmdstruct { } cmdstruct; enum { CMD_FORBID_UTF, CMD_LOAD, CMD_NEWLINE_DEFAULT, CMD_PATTERN, - CMD_PERLTEST, CMD_POP, CMD_SAVE, CMD_SUBJECT, CMD_UNKNOWN }; + CMD_PERLTEST, CMD_POP, CMD_POPCOPY, CMD_SAVE, CMD_SUBJECT, CMD_UNKNOWN }; static cmdstruct cmdlist[] = { { "forbid_utf", CMD_FORBID_UTF }, @@ -362,6 +362,7 @@ static cmdstruct cmdlist[] = { { "pattern", CMD_PATTERN }, { "perltest", CMD_PERLTEST }, { "pop", CMD_POP }, + { "popcopy", CMD_POPCOPY }, { "save", CMD_SAVE }, { "subject", CMD_SUBJECT }}; @@ -425,11 +426,11 @@ so many of them that they are split into two fields. */ #define CTL_MEMORY 0x00100000u #define CTL_NULLCONTEXT 0x00200000u #define CTL_POSIX 0x00400000u -#define CTL_PUSH 0x00800000u -#define CTL_STARTCHAR 0x01000000u -#define CTL_ZERO_TERMINATE 0x02000000u -/* Spare 0x04000000u */ -/* Spare 0x08000000u */ +#define CTL_POSIX_NOSUB 0x00800000u +#define CTL_PUSH 0x01000000u +#define CTL_PUSHCOPY 0x02000000u +#define CTL_STARTCHAR 0x04000000u +#define CTL_ZERO_TERMINATE 0x08000000u /* Spare 0x10000000u */ /* Spare 0x20000000u */ #define CTL_NL_SET 0x40000000u /* Informational */ @@ -585,6 +586,7 @@ static modstruct modlist[] = { { "no_auto_capture", MOD_PAT, MOD_OPT, PCRE2_NO_AUTO_CAPTURE, PO(options) }, { "no_auto_possess", MOD_PATP, MOD_OPT, PCRE2_NO_AUTO_POSSESS, PO(options) }, { "no_dotstar_anchor", MOD_PAT, MOD_OPT, PCRE2_NO_DOTSTAR_ANCHOR, PO(options) }, + { "no_jit", MOD_DAT, MOD_OPT, PCRE2_NO_JIT, DO(options) }, { "no_start_optimize", MOD_PATP, MOD_OPT, PCRE2_NO_START_OPTIMIZE, PO(options) }, { "no_utf_check", MOD_PD, MOD_OPT, PCRE2_NO_UTF_CHECK, PD(options) }, { "notbol", MOD_DAT, MOD_OPT, PCRE2_NOTBOL, DO(options) }, @@ -600,8 +602,10 @@ static modstruct modlist[] = { { "partial_soft", MOD_DAT, MOD_OPT, PCRE2_PARTIAL_SOFT, DO(options) }, { "ph", MOD_DAT, MOD_OPT, PCRE2_PARTIAL_HARD, DO(options) }, { "posix", MOD_PAT, MOD_CTL, CTL_POSIX, PO(control) }, + { "posix_nosub", MOD_PAT, MOD_CTL, CTL_POSIX|CTL_POSIX_NOSUB, PO(control) }, { "ps", MOD_DAT, MOD_OPT, PCRE2_PARTIAL_SOFT, DO(options) }, { "push", MOD_PAT, MOD_CTL, CTL_PUSH, PO(control) }, + { "pushcopy", MOD_PAT, MOD_CTL, CTL_PUSHCOPY, PO(control) }, { "recursion_limit", MOD_CTM, MOD_INT, 0, MO(recursion_limit) }, { "regerror_buffsize", MOD_PAT, MOD_INT, 0, PO(regerror_buffsize) }, { "replace", MOD_PND, MOD_STR, REPLACE_MODSIZE, PO(replacement) }, @@ -625,11 +629,11 @@ static modstruct modlist[] = { /* Controls and options that are supported for use with the POSIX interface. */ #define POSIX_SUPPORTED_COMPILE_OPTIONS ( \ - PCRE2_CASELESS|PCRE2_DOTALL|PCRE2_MULTILINE|PCRE2_NO_AUTO_CAPTURE| \ - PCRE2_UCP|PCRE2_UTF|PCRE2_UNGREEDY) + PCRE2_CASELESS|PCRE2_DOTALL|PCRE2_MULTILINE|PCRE2_UCP|PCRE2_UTF| \ + PCRE2_UNGREEDY) #define POSIX_SUPPORTED_COMPILE_CONTROLS ( \ - CTL_AFTERTEXT|CTL_ALLAFTERTEXT|CTL_EXPAND|CTL_POSIX) + CTL_AFTERTEXT|CTL_ALLAFTERTEXT|CTL_EXPAND|CTL_POSIX|CTL_POSIX_NOSUB) #define POSIX_SUPPORTED_COMPILE_CONTROLS2 (0) @@ -643,7 +647,7 @@ static modstruct modlist[] = { #define PUSH_SUPPORTED_COMPILE_CONTROLS ( \ CTL_BINCODE|CTL_CALLOUT_INFO|CTL_FULLBINCODE|CTL_HEXPAT|CTL_INFO| \ - CTL_JITVERIFY|CTL_MEMORY|CTL_PUSH|CTL_BSR_SET|CTL_NL_SET) + CTL_JITVERIFY|CTL_MEMORY|CTL_PUSH|CTL_PUSHCOPY|CTL_BSR_SET|CTL_NL_SET) #define PUSH_SUPPORTED_COMPILE_CONTROLS2 (0) @@ -652,16 +656,19 @@ static modstruct modlist[] = { #define PUSH_COMPILE_ONLY_CONTROLS CTL_JITVERIFY #define PUSH_COMPILE_ONLY_CONTROLS2 (0) -/* Controls that are forbidden with #pop. */ +/* Controls that are forbidden with #pop or #popcopy. */ -#define NOTPOP_CONTROLS (CTL_HEXPAT|CTL_POSIX|CTL_PUSH) +#define NOTPOP_CONTROLS (CTL_HEXPAT|CTL_POSIX|CTL_POSIX_NOSUB|CTL_PUSH| \ + CTL_PUSHCOPY) /* Pattern controls that are mutually exclusive. At present these are all in -the first control word. */ +the first control word. Note that CTL_POSIX_NOSUB is always accompanied by +CTL_POSIX, so it doesn't need its own entries. */ static uint32_t exclusive_pat_controls[] = { CTL_POSIX | CTL_HEXPAT, CTL_POSIX | CTL_PUSH, + CTL_POSIX | CTL_PUSHCOPY, CTL_EXPAND | CTL_HEXPAT }; /* Data controls that are mutually exclusive. At present these are all in the @@ -811,7 +818,7 @@ static void *patstack[PATSTACKSIZE]; static int patstacknext = 0; #ifdef SUPPORT_PCRE2_8 -static regex_t preg = { NULL, NULL, 0, 0 }; +static regex_t preg = { NULL, NULL, 0, 0, 0 }; #endif static int *dfa_workspace = NULL; @@ -943,6 +950,22 @@ are supported. */ a = pcre2_callout_enumerate_32(compiled_code32, \ (int (*)(struct pcre2_callout_enumerate_block_32 *, void *))b,c) +#define PCRE2_CODE_COPY_FROM_VOID(a,b) \ + if (test_mode == PCRE8_MODE) \ + G(a,8) = pcre2_code_copy_8(b); \ + else if (test_mode == PCRE16_MODE) \ + G(a,16) = pcre2_code_copy_16(b); \ + else \ + G(a,32) = pcre2_code_copy_32(b) + +#define PCRE2_CODE_COPY_TO_VOID(a,b) \ + if (test_mode == PCRE8_MODE) \ + a = (void *)pcre2_code_copy_8(G(b,8)); \ + else if (test_mode == PCRE16_MODE) \ + a = (void *)pcre2_code_copy_16(G(b,16)); \ + else \ + a = (void *)pcre2_code_copy_32(G(b,32)) + #define PCRE2_COMPILE(a,b,c,d,e,f,g) \ if (test_mode == PCRE8_MODE) \ G(a,8) = pcre2_compile_8(G(b,8),c,d,e,f,g); \ @@ -1394,6 +1417,18 @@ the three different cases. */ a = G(pcre2_callout_enumerate,BITTWO)(G(compiled_code,BITTWO), \ (int (*)(struct G(pcre2_callout_enumerate_block_,BITTWO) *, void *))b,c) +#define PCRE2_CODE_COPY_FROM_VOID(a,b) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + G(a,BITONE) = G(pcre2_code_copy_,BITONE)(b); \ + else \ + G(a,BITTWO) = G(pcre2_code_copy_,BITTWO)(b) + +#define PCRE2_CODE_COPY_TO_VOID(a,b) \ + if (test_mode == G(G(PCRE,BITONE),_MODE)) \ + a = (void *)G(pcre2_code_copy_,BITONE)(G(b,BITONE)); \ + else \ + a = (void *)G(pcre2_code_copy_,BITTWO)(G(b,BITTWO)) + #define PCRE2_COMPILE(a,b,c,d,e,f,g) \ if (test_mode == G(G(PCRE,BITONE),_MODE)) \ G(a,BITONE) = G(pcre2_compile_,BITONE)(G(b,BITONE),c,d,e,f,g); \ @@ -1729,6 +1764,8 @@ the three different cases. */ #define PCRE2_CALLOUT_ENUMERATE(a,b,c) \ a = pcre2_callout_enumerate_8(compiled_code8, \ (int (*)(struct pcre2_callout_enumerate_block_8 *, void *))b,c) +#define PCRE2_CODE_COPY_FROM_VOID(a,b) G(a,8) = pcre2_code_copy_8(b) +#define PCRE2_CODE_COPY_TO_VOID(a,b) a = (void *)pcre2_code_copy_8(G(b,8)) #define PCRE2_COMPILE(a,b,c,d,e,f,g) \ G(a,8) = pcre2_compile_8(G(b,8),c,d,e,f,g) #define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \ @@ -1822,6 +1859,8 @@ the three different cases. */ #define PCRE2_CALLOUT_ENUMERATE(a,b,c) \ a = pcre2_callout_enumerate_16(compiled_code16, \ (int (*)(struct pcre2_callout_enumerate_block_16 *, void *))b,c) +#define PCRE2_CODE_COPY_FROM_VOID(a,b) G(a,16) = pcre2_code_copy_16(b) +#define PCRE2_CODE_COPY_TO_VOID(a,b) a = (void *)pcre2_code_copy_16(G(b,16)) #define PCRE2_COMPILE(a,b,c,d,e,f,g) \ G(a,16) = pcre2_compile_16(G(b,16),c,d,e,f,g) #define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \ @@ -1915,6 +1954,8 @@ the three different cases. */ #define PCRE2_CALLOUT_ENUMERATE(a,b,c) \ a = pcre2_callout_enumerate_32(compiled_code32, \ (int (*)(struct pcre2_callout_enumerate_block_32 *, void *))b,c) +#define PCRE2_CODE_COPY_FROM_VOID(a,b) G(a,32) = pcre2_code_copy_32(b) +#define PCRE2_CODE_COPY_TO_VOID(a,b) a = (void *)pcre2_code_copy_32(G(b,32)) #define PCRE2_COMPILE(a,b,c,d,e,f,g) \ G(a,32) = pcre2_compile_32(G(b,32),c,d,e,f,g) #define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \ @@ -2546,12 +2587,13 @@ return (int)(pp - p); /* Must handle UTF-8 strings in utf8 mode. Yields number of characters printed. For printing *MARK strings, a negative length is given. If handed a NULL file, -just counts chars without printing. */ +just counts chars without printing (because pchar() does that). */ static int pchars8(PCRE2_SPTR8 p, int length, BOOL utf, FILE *f) { uint32_t c = 0; int yield = 0; + if (length < 0) length = p[-1]; while (length-- > 0) { @@ -2569,6 +2611,7 @@ while (length-- > 0) c = *p++; yield += pchar(c, utf, f); } + return yield; } #endif @@ -2913,10 +2956,11 @@ pbuffer8 = new_pbuffer8; /* Input lines are read into buffer, but both patterns and data lines can be continued over multiple input lines. In addition, if the buffer fills up, we want to automatically expand it so as to be able to handle extremely large -lines that are needed for certain stress tests. When the input buffer is -expanded, the other two buffers must also be expanded likewise, and the -contents of pbuffer, which are a copy of the input for callouts, must be -preserved (for when expansion happens for a data line). This is not the most +lines that are needed for certain stress tests, although this is less likely +now that there are repetition features for both patterns and data. When the +input buffer is expanded, the other two buffers must also be expanded likewise, +and the contents of pbuffer, which are a copy of the input for callouts, must +be preserved (for when expansion happens for a data line). This is not the most optimal way of handling this, but hey, this is just a test program! Arguments: @@ -2940,7 +2984,7 @@ for (;;) if (rlen > 1000) { - int dlen; + size_t dlen; /* If libreadline or libedit support is required, use readline() to read a line if the input is a terminal. Note that readline() removes the trailing @@ -2971,9 +3015,27 @@ for (;;) return (here == start)? NULL : start; } - dlen = (int)strlen((char *)here); - if (dlen > 0 && here[dlen - 1] == '\n') return start; + dlen = strlen((char *)here); here += dlen; + + /* Check for end of line reached. Take care not to read data from before + start (dlen will be zero for a file starting with a binary zero). */ + + if (here > start && here[-1] == '\n') return start; + + /* If we have not read a newline when reading a file, we have either filled + the buffer or reached the end of the file. We can detect the former by + checking that the string fills the buffer, and the latter by feof(). If + neither of these is true, it means we read a binary zero which has caused + strlen() to give a short length. This is a hard error because pcre2test + expects to work with C strings. */ + + if (!INTERACTIVE(f) && dlen < rlen - 1 && !feof(f)) + { + fprintf(outfile, "** Binary zero encountered in input\n"); + fprintf(outfile, "** pcre2test run abandoned\n"); + exit(1); + } } else @@ -3565,7 +3627,7 @@ Returns: nothing static void show_controls(uint32_t controls, uint32_t controls2, const char *before) { -fprintf(outfile, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", +fprintf(outfile, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", before, ((controls & CTL_AFTERTEXT) != 0)? " aftertext" : "", ((controls & CTL_ALLAFTERTEXT) != 0)? " allaftertext" : "", @@ -3592,7 +3654,9 @@ fprintf(outfile, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s ((controls & CTL_NL_SET) != 0)? " newline" : "", ((controls & CTL_NULLCONTEXT) != 0)? " null_context" : "", ((controls & CTL_POSIX) != 0)? " posix" : "", + ((controls & CTL_POSIX_NOSUB) != 0)? " posix_nosub" : "", ((controls & CTL_PUSH) != 0)? " push" : "", + ((controls & CTL_PUSHCOPY) != 0)? " pushcopy" : "", ((controls & CTL_STARTCHAR) != 0)? " startchar" : "", ((controls2 & CTL2_SUBSTITUTE_EXTENDED) != 0)? " substitute_extended" : "", ((controls2 & CTL2_SUBSTITUTE_OVERFLOW_LENGTH) != 0)? " substitute_overflow_length" : "", @@ -3690,6 +3754,10 @@ show_memory_info(void) uint32_t name_count, name_entry_size; size_t size, cblock_size; +/* One of the test_mode values will always be true, but to stop a compiler +warning we must initialize cblock_size. */ + +cblock_size = 0; #ifdef SUPPORT_PCRE2_8 if (test_mode == 8) cblock_size = sizeof(pcre2_real_code_8); #endif @@ -3791,8 +3859,8 @@ if ((pat_patctl.control & (CTL_BINCODE|CTL_FULLBINCODE)) != 0) if ((pat_patctl.control & CTL_INFO) != 0) { - const void *nametable; - const uint8_t *start_bits; + void *nametable; + uint8_t *start_bits; BOOL match_limit_set, recursion_limit_set; uint32_t backrefmax, bsr_convention, capture_count, first_ctype, first_cunit, hasbackslashc, hascrorlf, jchanged, last_ctype, last_cunit, match_empty, @@ -4240,11 +4308,12 @@ switch(cmd) local_newline_default = first_listed_newline; break; - /* Pop a compiled pattern off the stack. Modifiers that do not affect the - compiled pattern (e.g. to give information) are permitted. The default + /* Pop or copy a compiled pattern off the stack. Modifiers that do not affect + the compiled pattern (e.g. to give information) are permitted. The default pattern modifiers are ignored. */ case CMD_POP: + case CMD_POPCOPY: if (patstacknext <= 0) { fprintf(outfile, "** Can't pop off an empty stack\n"); @@ -4253,7 +4322,16 @@ switch(cmd) memset(&pat_patctl, 0, sizeof(patctl)); /* Completely unset */ if (!decode_modifiers(argptr, CTX_POPPAT, &pat_patctl, NULL)) return PR_SKIP; - SET(compiled_code, patstack[--patstacknext]); + + if (cmd == CMD_POP) + { + SET(compiled_code, patstack[--patstacknext]); + } + else + { + PCRE2_CODE_COPY_FROM_VOID(compiled_code, patstack[patstacknext - 1]); + } + if (pat_patctl.jit != 0) { PCRE2_JIT_COMPILE(jitrc, compiled_code, pat_patctl.jit); @@ -4451,9 +4529,9 @@ if (pat_patctl.jit == 0 && pat_patctl.jit = 7; /* Now copy the pattern to pbuffer8 for use in 8-bit testing and for reflecting -in callouts. Convert from hex if required; this must necessarily be fewer -characters so will always fit in pbuffer8. Alternatively, process for -repetition if requested. */ +in callouts. Convert from hex if requested (literal strings in quotes may be +present within the hexadecimal pairs). The result must necessarily be fewer +characters so will always fit in pbuffer8. */ if ((pat_patctl.control & CTL_HEXPAT) != 0) { @@ -4464,25 +4542,59 @@ if ((pat_patctl.control & CTL_HEXPAT) != 0) for (pp = buffer + 1; *pp != 0; pp++) { if (isspace(*pp)) continue; - c = toupper(*pp++); - if (*pp == 0) + c = *pp++; + + /* Handle a literal substring */ + + if (c == '\'' || c == '"') { - fprintf(outfile, "** Odd number of digits in hex pattern.\n"); - return PR_SKIP; + for (;; pp++) + { + d = *pp; + if (d == 0) + { + fprintf(outfile, "** Missing closing quote in hex pattern\n"); + return PR_SKIP; + } + if (d == c) break; + *pt++ = d; + } } - d = toupper(*pp); - if (!isxdigit(c) || !isxdigit(d)) + + /* Expect a hex pair */ + + else { - fprintf(outfile, "** Non-hex-digit in hex pattern.\n"); - return PR_SKIP; + if (!isxdigit(c)) + { + fprintf(outfile, "** Unexpected non-hex-digit '%c' in hex pattern: " + "quote missing?\n", c); + return PR_SKIP; + } + if (*pp == 0) + { + fprintf(outfile, "** Odd number of digits in hex pattern\n"); + return PR_SKIP; + } + d = *pp; + if (!isxdigit(d)) + { + fprintf(outfile, "** Unexpected non-hex-digit '%c' in hex pattern: " + "quote missing?\n", d); + return PR_SKIP; + } + c = toupper(c); + d = toupper(d); + *pt++ = ((isdigit(c)? (c - '0') : (c - 'A' + 10)) << 4) + + (isdigit(d)? (d - '0') : (d - 'A' + 10)); } - *pt++ = ((isdigit(c)? (c - '0') : (c - 'A' + 10)) << 4) + - (isdigit(d)? (d - '0') : (d - 'A' + 10)); } *pt = 0; patlen = pt - pbuffer8; } +/* If not a hex string, process for repetition expansion if requested. */ + else if ((pat_patctl.control & CTL_EXPAND) != 0) { uint8_t *pp, *pt; @@ -4506,8 +4618,19 @@ else if ((pat_patctl.control & CTL_EXPAND) != 0) { uint32_t clen = pe - pc - 2; uint32_t i = 0; + unsigned long uli; + char *endptr; + pe += 2; - while (isdigit(*pe)) i = i * 10 + *pe++ - '0'; + uli = strtoul((const char *)pe, &endptr, 10); + if (U32OVERFLOW(uli)) + { + fprintf(outfile, "** Pattern repeat count too large\n"); + return PR_SKIP; + } + + i = (uint32_t)uli; + pe = (uint8_t *)endptr; if (*pe == '}') { if (i == 0) @@ -4540,7 +4663,7 @@ else if ((pat_patctl.control & CTL_EXPAND) != 0) pt = pbuffer8 + pt_offset; } - while (count-- > 0) + for (; count > 0; count--) { memcpy(pt, pc, length); pt += length; @@ -4567,7 +4690,7 @@ if (pat_patctl.locale[0] != 0) { if (pat_patctl.tables_id != 0) { - fprintf(outfile, "** 'Locale' and 'tables' must not both be set.\n"); + fprintf(outfile, "** 'Locale' and 'tables' must not both be set\n"); return PR_SKIP; } if (setlocale(LC_CTYPE, (const char *)pat_patctl.locale) == NULL) @@ -4649,21 +4772,24 @@ if ((pat_patctl.control & CTL_POSIX) != 0) if (msg[0] == 0) fprintf(outfile, "\n"); - /* Translate PCRE2 options to POSIX options and then compile. On success, set - up a match_data block to be used for all matches. */ + /* Translate PCRE2 options to POSIX options and then compile. */ if (utf) cflags |= REG_UTF; + if ((pat_patctl.control & CTL_POSIX_NOSUB) != 0) cflags |= REG_NOSUB; if ((pat_patctl.options & PCRE2_UCP) != 0) cflags |= REG_UCP; if ((pat_patctl.options & PCRE2_CASELESS) != 0) cflags |= REG_ICASE; if ((pat_patctl.options & PCRE2_MULTILINE) != 0) cflags |= REG_NEWLINE; if ((pat_patctl.options & PCRE2_DOTALL) != 0) cflags |= REG_DOTALL; - if ((pat_patctl.options & PCRE2_NO_AUTO_CAPTURE) != 0) cflags |= REG_NOSUB; if ((pat_patctl.options & PCRE2_UNGREEDY) != 0) cflags |= REG_UNGREEDY; rc = regcomp(&preg, (char *)pbuffer8, cflags); - if (rc != 0) /* Failure */ + + /* Compiling failed */ + + if (rc != 0) { size_t bsize, usize; + int psize; preg.re_pcre2_code = NULL; /* In case something was left in there */ preg.re_match_data = NULL; @@ -4674,7 +4800,12 @@ if ((pat_patctl.control & CTL_POSIX) != 0) memcpy(pbuffer8 + bsize, "DEADBEEF", 8); usize = regerror(rc, &preg, (char *)pbuffer8, bsize); - fprintf(outfile, "Failed: POSIX code %d: %s\n", rc, pbuffer8); + /* Inside regerror(), snprintf() is used. If the buffer is too small, some + versions of snprintf() put a zero byte at the end, but others do not. + Therefore, we print a maximum of one less than the size of the buffer. */ + + psize = (int)bsize - 1; + fprintf(outfile, "Failed: POSIX code %d: %.*s\n", rc, psize, pbuffer8); if (usize > bsize) { fprintf(outfile, "** regerror() message truncated\n"); @@ -4683,6 +4814,29 @@ if ((pat_patctl.control & CTL_POSIX) != 0) } return PR_SKIP; } + + /* Compiling succeeded. Check that the values in the preg block are sensible. + It can happen that pcre2test is accidentally linked with a different POSIX + library which succeeds, but of course puts different things into preg. In + this situation, calling regfree() may cause a segfault (or invalid free() in + valgrind), so ensure that preg.re_pcre2_code is NULL, which suppresses the + calling of regfree() on exit. */ + + if (preg.re_pcre2_code == NULL || + ((pcre2_real_code_8 *)preg.re_pcre2_code)->magic_number != MAGIC_NUMBER || + ((pcre2_real_code_8 *)preg.re_pcre2_code)->top_bracket != preg.re_nsub || + preg.re_match_data == NULL || + preg.re_cflags != cflags) + { + fprintf(outfile, + "** The regcomp() function returned zero (success), but the values set\n" + "** in the preg block are not valid for PCRE2. Check that pcre2test is\n" + "** linked with PCRE2's pcre2posix module (-lpcre2-posix) and not with\n" + "** some other POSIX regex library.\n**\n"); + preg.re_pcre2_code = NULL; + return PR_ABEND; + } + return PR_OK; #endif /* SUPPORT_PCRE2_8 */ } @@ -4690,7 +4844,7 @@ if ((pat_patctl.control & CTL_POSIX) != 0) /* Handle compiling via the native interface. Controls that act later are ignored with "push". Replacements are locked out. */ -if ((pat_patctl.control & CTL_PUSH) != 0) +if ((pat_patctl.control & (CTL_PUSH|CTL_PUSHCOPY)) != 0) { if (pat_patctl.replacement[0] != 0) { @@ -4717,9 +4871,7 @@ if ((pat_patctl.control & CTL_PUSH) != 0) /* Convert the input in non-8-bit modes. */ -#ifdef SUPPORT_PCRE2_8 -if (test_mode == PCRE8_MODE) errorcode = 0; -#endif +errorcode = 0; #ifdef SUPPORT_PCRE2_16 if (test_mode == PCRE16_MODE) errorcode = to16(pbuffer8, utf, &patlen); @@ -4893,6 +5045,19 @@ if ((pat_patctl.control & CTL_PUSH) != 0) SET(compiled_code, NULL); } +/* The "pushcopy" control is similar, but pushes a copy of the pattern. This +tests the pcre2_code_copy() function. */ + +if ((pat_patctl.control & CTL_PUSHCOPY) != 0) + { + if (patstacknext >= PATSTACKSIZE) + { + fprintf(outfile, "** Too many pushed patterns (max %d)\n", PATSTACKSIZE); + return PR_ABEND; + } + PCRE2_CODE_COPY_TO_VOID(patstack[patstacknext++], compiled_code); + } + return PR_OK; } @@ -4975,6 +5140,7 @@ static int callout_function(pcre2_callout_block_8 *cb, void *callout_data_ptr) { uint32_t i, pre_start, post_start, subject_length; +PCRE2_SIZE current_position; BOOL utf = (FLD(compiled_code, overall_options) & PCRE2_UTF) != 0; BOOL callout_capture = (dat_datctl.control & CTL_CALLOUT_CAPTURE) != 0; @@ -5025,22 +5191,37 @@ if (callout_capture) } } -/* Re-print the subject in canonical form, the first time or if giving full -datails. On subsequent calls in the same match, we use pchars just to find the -printed lengths of the substrings. */ +/* Re-print the subject in canonical form (with escapes for non-printing +characters), the first time, or if giving full details. On subsequent calls in +the same match, we use PCHARS() just to find the printed lengths of the +substrings. */ if (f != NULL) fprintf(f, "--->"); +/* The subject before the match start. */ + PCHARS(pre_start, cb->subject, 0, cb->start_match, utf, f); +/* If a lookbehind is involved, the current position may be earlier than the +match start. If so, use the match start instead. */ + +current_position = (cb->current_position >= cb->start_match)? + cb->current_position : cb->start_match; + +/* The subject between the match start and the current position. */ + PCHARS(post_start, cb->subject, cb->start_match, - cb->current_position - cb->start_match, utf, f); + current_position - cb->start_match, utf, f); + +/* Print from the current position to the end. */ + +PCHARSV(cb->subject, current_position, cb->subject_length - current_position, + utf, f); + +/* Calculate the total subject printed length (no print). */ PCHARS(subject_length, cb->subject, 0, cb->subject_length, utf, NULL); -PCHARSV(cb->subject, cb->current_position, - cb->subject_length - cb->current_position, utf, f); - if (f != NULL) fprintf(f, "\n"); /* For automatic callouts, show the pattern offset. Otherwise, for a numerical @@ -5445,13 +5626,15 @@ buffer of the appropriate width. In UTF mode, input can be UTF-8. */ while ((c = *p++) != 0) { - int i = 0; + int32_t i = 0; size_t replen; /* ] may mark the end of a replicated sequence */ if (c == ']' && start_rep != NULL) { + long li; + char *endptr; size_t qoffset = CAST8VAR(q) - dbuffer; size_t rep_offset = start_rep - dbuffer; @@ -5460,12 +5643,22 @@ while ((c = *p++) != 0) fprintf(outfile, "** Expected '{' after \\[....]\n"); return PR_OK; } - while (isdigit(*p)) i = i * 10 + *p++ - '0'; + + li = strtol((const char *)p, &endptr, 10); + if (S32OVERFLOW(li)) + { + fprintf(outfile, "** Repeat count too large\n"); + return PR_OK; + } + + p = (uint8_t *)endptr; if (*p++ != '}') { fprintf(outfile, "** Expected '}' after \\[...]{...\n"); return PR_OK; } + + i = (int32_t)li; if (i-- == 0) { fprintf(outfile, "** Zero repeat not allowed\n"); @@ -5780,7 +5973,7 @@ if ((pat_patctl.control & CTL_POSIX) != 0) (void)regerror(rc, &preg, (char *)pbuffer8, pbuffer8_size); fprintf(outfile, "No match: POSIX code %d: %s\n", rc, pbuffer8); } - else if ((pat_patctl.options & PCRE2_NO_AUTO_CAPTURE) != 0) + else if ((pat_patctl.control & CTL_POSIX_NOSUB) != 0) fprintf(outfile, "Matched with REG_NOSUB\n"); else if (dat_datctl.oveccount == 0) fprintf(outfile, "Matched without capture\n"); @@ -6243,15 +6436,23 @@ else for (gmatched = 0;; gmatched++) /* "allcaptures" requests showing of all captures in the pattern, to check unset ones at the end. It may be set on the pattern or the data. Implement - by setting capcount to the maximum. */ + by setting capcount to the maximum. This is not relevant for DFA matching, + so ignore it. */ if ((dat_datctl.control & CTL_ALLCAPTURES) != 0) { uint32_t maxcapcount; - if (pattern_info(PCRE2_INFO_CAPTURECOUNT, &maxcapcount, FALSE) < 0) - return PR_SKIP; - capcount = maxcapcount + 1; /* Allow for full match */ - if (capcount > (int)oveccount) capcount = oveccount; + if ((dat_datctl.control & CTL_DFA) != 0) + { + fprintf(outfile, "** Ignored after DFA matching: allcaptures\n"); + } + else + { + if (pattern_info(PCRE2_INFO_CAPTURECOUNT, &maxcapcount, FALSE) < 0) + return PR_SKIP; + capcount = maxcapcount + 1; /* Allow for full match */ + if (capcount > (int)oveccount) capcount = oveccount; + } } /* Output the captured substrings. Note that, for the matched string, @@ -6717,6 +6918,7 @@ printf(" pcre2-32 32 bit library support enabled [0, 1]\n"); printf(" unicode Unicode and UTF support enabled [0, 1]\n"); printf(" -d set default pattern control 'debug'\n"); printf(" -dfa set default subject control 'dfa'\n"); +printf(" -error show messages for error numbers, then exit\n"); printf(" -help show usage information\n"); printf(" -i set default pattern control 'info'\n"); printf(" -jit set default pattern control 'jit'\n"); @@ -6894,6 +7096,7 @@ BOOL showtotaltimes = FALSE; BOOL skipping = FALSE; char *arg_subject = NULL; char *arg_pattern = NULL; +char *arg_error = NULL; /* The offsets to the options and control bits fields of the pattern and data control blocks must be the same so that common options and controls such as @@ -7021,7 +7224,7 @@ while (argc > 1 && argv[op][0] == '-' && argv[op][1] != 0) struct rlimit rlim; if (U32OVERFLOW(uli)) { - fprintf(stderr, "+++ Argument for -S is too big\n"); + fprintf(stderr, "** Argument for -S is too big\n"); exit(1); } stack_size = (uint32_t)uli; @@ -7073,7 +7276,7 @@ while (argc > 1 && argv[op][0] == '-' && argv[op][1] != 0) { if (U32OVERFLOW(uli)) { - fprintf(stderr, "+++ Argument for %s is too big\n", arg); + fprintf(stderr, "** Argument for %s is too big\n", arg); exit(1); } timeitm = (int)uli; @@ -7105,6 +7308,12 @@ while (argc > 1 && argv[op][0] == '-' && argv[op][1] != 0) /* The following options save their data for processing once we know what the running mode is. */ + else if (strcmp(arg, "-error") == 0) + { + arg_error = argv[op+1]; + goto CHECK_VALUE_EXISTS; + } + else if (strcmp(arg, "-subject") == 0) { arg_subject = argv[op+1]; @@ -7138,6 +7347,88 @@ while (argc > 1 && argv[op][0] == '-' && argv[op][1] != 0) argc--; } +/* If -error was present, get the error numbers, show the messages, and exit. +We wait to do this until we know which mode we are in. */ + +if (arg_error != NULL) + { + int len; + int errcode; + char *endptr; + +/* Ensure the relevant non-8-bit buffer is available. */ + +#ifdef SUPPORT_PCRE2_16 + if (test_mode == PCRE16_MODE) + { + pbuffer16_size = 256; + pbuffer16 = (uint16_t *)malloc(pbuffer16_size); + if (pbuffer16 == NULL) + { + fprintf(stderr, "pcre2test: malloc(%lu) failed for pbuffer16\n", + (unsigned long int)pbuffer16_size); + yield = 1; + goto EXIT; + } + } +#endif + +#ifdef SUPPORT_PCRE2_32 + if (test_mode == PCRE32_MODE) + { + pbuffer32_size = 256; + pbuffer32 = (uint32_t *)malloc(pbuffer32_size); + if (pbuffer32 == NULL) + { + fprintf(stderr, "pcre2test: malloc(%lu) failed for pbuffer32\n", + (unsigned long int)pbuffer32_size); + yield = 1; + goto EXIT; + } + } +#endif + + /* Loop along a list of error numbers. */ + + for (;;) + { + errcode = strtol(arg_error, &endptr, 10); + if (*endptr != 0 && *endptr != CHAR_COMMA) + { + fprintf(stderr, "** '%s' is not a valid error number list\n", arg_error); + yield = 1; + goto EXIT; + } + printf("Error %d: ", errcode); + PCRE2_GET_ERROR_MESSAGE(len, errcode, pbuffer); + if (len < 0) + { + switch (len) + { + case PCRE2_ERROR_BADDATA: + printf("PCRE2_ERROR_BADDATA (unknown error number)"); + break; + + case PCRE2_ERROR_NOMEMORY: + printf("PCRE2_ERROR_NOMEMORY (buffer too small)"); + break; + + default: + printf("Unexpected return (%d) from pcre2_get_error_message()", len); + break; + } + } + else + { + PCHARSV(CASTVAR(void *, pbuffer), 0, len, FALSE, stdout); + } + printf("\n"); + if (*endptr == 0) goto EXIT; + arg_error = endptr + 1; + } + /* Control never reaches here */ + } /* End of -error handling */ + /* Initialize things that cannot be done until we know which test mode we are running in. When HEAP_MATCH_RECURSE is undefined, calling pcre2_set_recursion_ memory_management() is a no-op, but we call it in order to exercise it. Also @@ -7398,7 +7689,7 @@ if (jit_stack != NULL) #ifdef SUPPORT_PCRE2_8 #undef BITS #define BITS 8 -regfree(&preg); +if (preg.re_pcre2_code != NULL) regfree(&preg); FREECONTEXTS; #endif diff --git a/pcre2-10.21/src/sljit/sljitConfig.h b/pcre2-10.22/src/sljit/sljitConfig.h similarity index 98% rename from pcre2-10.21/src/sljit/sljitConfig.h rename to pcre2-10.22/src/sljit/sljitConfig.h index 1c8a521aa..a548c37ab 100644 --- a/pcre2-10.21/src/sljit/sljitConfig.h +++ b/pcre2-10.22/src/sljit/sljitConfig.h @@ -82,7 +82,7 @@ /* --------------------------------------------------------------------- */ /* If SLJIT_STD_MACROS_DEFINED is not defined, the application should - define SLJIT_MALLOC, SLJIT_FREE, SLJIT_MEMMOVE, and NULL. */ + define SLJIT_MALLOC, SLJIT_FREE, SLJIT_MEMCPY, and NULL. */ #ifndef SLJIT_STD_MACROS_DEFINED /* Disabled by default. */ #define SLJIT_STD_MACROS_DEFINED 0 diff --git a/pcre2-10.21/src/sljit/sljitConfigInternal.h b/pcre2-10.22/src/sljit/sljitConfigInternal.h similarity index 92% rename from pcre2-10.21/src/sljit/sljitConfigInternal.h rename to pcre2-10.22/src/sljit/sljitConfigInternal.h index 16e3547c9..566c36806 100644 --- a/pcre2-10.21/src/sljit/sljitConfigInternal.h +++ b/pcre2-10.22/src/sljit/sljitConfigInternal.h @@ -31,14 +31,14 @@ SLJIT defines the following architecture dependent types and macros: Types: - sljit_sb, sljit_ub : signed and unsigned 8 bit byte - sljit_sh, sljit_uh : signed and unsigned 16 bit half-word (short) type - sljit_si, sljit_ui : signed and unsigned 32 bit integer type - sljit_sw, sljit_uw : signed and unsigned machine word, enough to store a pointer - sljit_p : unsgined pointer value (usually the same as sljit_uw, but - some 64 bit ABIs may use 32 bit pointers) - sljit_s : single precision floating point value - sljit_d : double precision floating point value + sljit_s8, sljit_u8 : signed and unsigned 8 bit integer type + sljit_s16, sljit_u16 : signed and unsigned 16 bit integer type + sljit_s32, sljit_u32 : signed and unsigned 32 bit integer type + sljit_sw, sljit_uw : signed and unsigned machine word, enough to store a pointer + sljit_p : unsgined pointer value (usually the same as sljit_uw, but + some 64 bit ABIs may use 32 bit pointers) + sljit_f32 : 32 bit single precision floating point value + sljit_f64 : 64 bit double precision floating point value Macros for feature detection (boolean): SLJIT_32BIT_ARCHITECTURE : 32 bit architecture @@ -56,10 +56,10 @@ SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS : number of available floating point scratch registers SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS : number of available floating point saved registers SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_sw/sljit_uw array by index - SLJIT_DOUBLE_SHIFT : the shift required to apply when accessing - a double precision floating point array by index - SLJIT_SINGLE_SHIFT : the shift required to apply when accessing - a single precision floating point array by index + SLJIT_F32_SHIFT : the shift required to apply when accessing + a single precision floating point array by index + SLJIT_F64_SHIFT : the shift required to apply when accessing + a double precision floating point array by index SLJIT_LOCALS_OFFSET : local space starting offset (SLJIT_SP + SLJIT_LOCALS_OFFSET) SLJIT_RETURN_ADDRESS_OFFSET : a return instruction always adds this offset to the return address @@ -210,8 +210,8 @@ #define SLJIT_FREE(ptr, allocator_data) free(ptr) #endif -#ifndef SLJIT_MEMMOVE -#define SLJIT_MEMMOVE(dest, src, len) memmove(dest, src, len) +#ifndef SLJIT_MEMCPY +#define SLJIT_MEMCPY(dest, src, len) memcpy(dest, src, len) #endif #ifndef SLJIT_ZEROMEM @@ -252,11 +252,6 @@ #endif #endif /* !SLJIT_INLINE */ -#ifndef SLJIT_CONST -/* Const variables. */ -#define SLJIT_CONST const -#endif - #ifndef SLJIT_UNUSED_ARG /* Unused arguments. */ #define SLJIT_UNUSED_ARG(arg) (void)arg @@ -284,6 +279,15 @@ /* Instruction cache flush. */ /****************************/ +#if (!defined SLJIT_CACHE_FLUSH && defined __has_builtin) +#if __has_builtin(__builtin___clear_cache) + +#define SLJIT_CACHE_FLUSH(from, to) \ + __builtin___clear_cache((char*)from, (char*)to) + +#endif /* __has_builtin(__builtin___clear_cache) */ +#endif /* (!defined SLJIT_CACHE_FLUSH && defined __has_builtin) */ + #ifndef SLJIT_CACHE_FLUSH #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) @@ -300,6 +304,11 @@ #define SLJIT_CACHE_FLUSH(from, to) \ sys_icache_invalidate((char*)(from), (char*)(to) - (char*)(from)) +#elif (defined(__GNUC__) && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) + +#define SLJIT_CACHE_FLUSH(from, to) \ + __builtin___clear_cache((char*)from, (char*)to) + #elif defined __ANDROID__ /* Android lacks __clear_cache; instead, cacheflush should be used. */ @@ -312,12 +321,14 @@ /* The __clear_cache() implementation of GCC is a dummy function on PowerPC. */ #define SLJIT_CACHE_FLUSH(from, to) \ ppc_cache_flush((from), (to)) +#define SLJIT_CACHE_FLUSH_OWN_IMPL 1 #elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) /* The __clear_cache() implementation of GCC is a dummy function on Sparc. */ #define SLJIT_CACHE_FLUSH(from, to) \ sparc_cache_flush((from), (to)) +#define SLJIT_CACHE_FLUSH_OWN_IMPL 1 #else @@ -330,20 +341,20 @@ #endif /* !SLJIT_CACHE_FLUSH */ /******************************************************/ -/* Byte/half/int/word/single/double type definitions. */ +/* Integer and floating point type definitions. */ /******************************************************/ /* 8 bit byte type. */ -typedef unsigned char sljit_ub; -typedef signed char sljit_sb; +typedef unsigned char sljit_u8; +typedef signed char sljit_s8; /* 16 bit half-word type. */ -typedef unsigned short int sljit_uh; -typedef signed short int sljit_sh; +typedef unsigned short int sljit_u16; +typedef signed short int sljit_s16; /* 32 bit integer type. */ -typedef unsigned int sljit_ui; -typedef signed int sljit_si; +typedef unsigned int sljit_u32; +typedef signed int sljit_s32; /* Machine word type. Enough for storing a pointer. 32 bit for 32 bit machines. @@ -377,15 +388,15 @@ typedef long int sljit_sw; typedef sljit_uw sljit_p; /* Floating point types. */ -typedef float sljit_s; -typedef double sljit_d; +typedef float sljit_f32; +typedef double sljit_f64; /* Shift for pointer sized data. */ #define SLJIT_POINTER_SHIFT SLJIT_WORD_SHIFT /* Shift for double precision sized data. */ -#define SLJIT_DOUBLE_SHIFT 3 -#define SLJIT_SINGLE_SHIFT 2 +#define SLJIT_F32_SHIFT 2 +#define SLJIT_F64_SHIFT 3 #ifndef SLJIT_W diff --git a/pcre2-10.21/src/sljit/sljitExecAllocator.c b/pcre2-10.22/src/sljit/sljitExecAllocator.c similarity index 98% rename from pcre2-10.21/src/sljit/sljitExecAllocator.c rename to pcre2-10.22/src/sljit/sljitExecAllocator.c index f24ed3379..54f05f5dd 100644 --- a/pcre2-10.21/src/sljit/sljitExecAllocator.c +++ b/pcre2-10.22/src/sljit/sljitExecAllocator.c @@ -137,10 +137,10 @@ struct free_block { }; #define AS_BLOCK_HEADER(base, offset) \ - ((struct block_header*)(((sljit_ub*)base) + offset)) + ((struct block_header*)(((sljit_u8*)base) + offset)) #define AS_FREE_BLOCK(base, offset) \ - ((struct free_block*)(((sljit_ub*)base) + offset)) -#define MEM_START(base) ((void*)(((sljit_ub*)base) + sizeof(struct block_header))) + ((struct free_block*)(((sljit_u8*)base) + offset)) +#define MEM_START(base) ((void*)(((sljit_u8*)base) + sizeof(struct block_header))) #define ALIGN_SIZE(size) (((size) + sizeof(struct block_header) + 7) & ~7) static struct free_block* free_blocks; @@ -153,7 +153,7 @@ static SLJIT_INLINE void sljit_insert_free_block(struct free_block *free_block, free_block->size = size; free_block->next = free_blocks; - free_block->prev = 0; + free_block->prev = NULL; if (free_blocks) free_blocks->prev = free_block; free_blocks = free_block; diff --git a/pcre2-10.21/src/sljit/sljitLir.c b/pcre2-10.22/src/sljit/sljitLir.c similarity index 81% rename from pcre2-10.21/src/sljit/sljitLir.c rename to pcre2-10.22/src/sljit/sljitLir.c index 0f1b1c9cc..ec1781e4c 100644 --- a/pcre2-10.21/src/sljit/sljitLir.c +++ b/pcre2-10.22/src/sljit/sljitLir.c @@ -77,16 +77,16 @@ #if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) #define GET_OPCODE(op) \ - ((op) & ~(SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS)) + ((op) & ~(SLJIT_I32_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS)) #define GET_FLAGS(op) \ ((op) & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C)) #define GET_ALL_FLAGS(op) \ - ((op) & (SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS)) + ((op) & (SLJIT_I32_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS)) #define TYPE_CAST_NEEDED(op) \ - (((op) >= SLJIT_MOV_UB && (op) <= SLJIT_MOV_SH) || ((op) >= SLJIT_MOVU_UB && (op) <= SLJIT_MOVU_SH)) + (((op) >= SLJIT_MOV_U8 && (op) <= SLJIT_MOV_S16) || ((op) >= SLJIT_MOVU_U8 && (op) <= SLJIT_MOVU_S16)) #define BUF_SIZE 4096 @@ -257,7 +257,7 @@ return 1; \ } while (0) -#define CHECK_RETURN_TYPE sljit_si +#define CHECK_RETURN_TYPE sljit_s32 #define CHECK_RETURN_OK return 0 #define CHECK(x) \ @@ -320,7 +320,7 @@ #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) #define SLJIT_NEEDS_COMPILER_INIT 1 -static sljit_si compiler_initialized = 0; +static sljit_s32 compiler_initialized = 0; /* A thread safe initialization. */ static void init_compiler(void); #endif @@ -333,17 +333,17 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allo SLJIT_ZEROMEM(compiler, sizeof(struct sljit_compiler)); SLJIT_COMPILE_ASSERT( - sizeof(sljit_sb) == 1 && sizeof(sljit_ub) == 1 - && sizeof(sljit_sh) == 2 && sizeof(sljit_uh) == 2 - && sizeof(sljit_si) == 4 && sizeof(sljit_ui) == 4 + sizeof(sljit_s8) == 1 && sizeof(sljit_u8) == 1 + && sizeof(sljit_s16) == 2 && sizeof(sljit_u16) == 2 + && sizeof(sljit_s32) == 4 && sizeof(sljit_u32) == 4 && (sizeof(sljit_p) == 4 || sizeof(sljit_p) == 8) && sizeof(sljit_p) <= sizeof(sljit_sw) && (sizeof(sljit_sw) == 4 || sizeof(sljit_sw) == 8) && (sizeof(sljit_uw) == 4 || sizeof(sljit_uw) == 8), invalid_integer_types); - SLJIT_COMPILE_ASSERT(SLJIT_INT_OP == SLJIT_SINGLE_OP, + SLJIT_COMPILE_ASSERT(SLJIT_I32_OP == SLJIT_F32_OP, int_op_and_single_op_must_be_the_same); - SLJIT_COMPILE_ASSERT(SLJIT_REWRITABLE_JUMP != SLJIT_SINGLE_OP, + SLJIT_COMPILE_ASSERT(SLJIT_REWRITABLE_JUMP != SLJIT_F32_OP, rewritable_jump_and_single_op_must_not_be_the_same); /* Only the non-zero members must be set. */ @@ -379,14 +379,14 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allo #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) compiler->cpool = (sljit_uw*)SLJIT_MALLOC(CPOOL_SIZE * sizeof(sljit_uw) - + CPOOL_SIZE * sizeof(sljit_ub), allocator_data); + + CPOOL_SIZE * sizeof(sljit_u8), allocator_data); if (!compiler->cpool) { SLJIT_FREE(compiler->buf, allocator_data); SLJIT_FREE(compiler->abuf, allocator_data); SLJIT_FREE(compiler, allocator_data); return NULL; } - compiler->cpool_unique = (sljit_ub*)(compiler->cpool + CPOOL_SIZE); + compiler->cpool_unique = (sljit_u8*)(compiler->cpool + CPOOL_SIZE); compiler->cpool_diff = 0xffffffff; #endif @@ -485,7 +485,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw static void* ensure_buf(struct sljit_compiler *compiler, sljit_uw size) { - sljit_ub *ret; + sljit_u8 *ret; struct sljit_memory_fragment *new_frag; SLJIT_ASSERT(size <= 256); @@ -504,7 +504,7 @@ static void* ensure_buf(struct sljit_compiler *compiler, sljit_uw size) static void* ensure_abuf(struct sljit_compiler *compiler, sljit_uw size) { - sljit_ub *ret; + sljit_u8 *ret; struct sljit_memory_fragment *new_frag; SLJIT_ASSERT(size <= 256); @@ -521,7 +521,7 @@ static void* ensure_abuf(struct sljit_compiler *compiler, sljit_uw size) return new_frag->memory; } -SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size) { CHECK_ERROR_PTR(); @@ -554,8 +554,8 @@ static SLJIT_INLINE void reverse_buf(struct sljit_compiler *compiler) } static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { SLJIT_UNUSED_ARG(args); SLJIT_UNUSED_ARG(local_size); @@ -571,8 +571,8 @@ static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler, } static SLJIT_INLINE void set_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { SLJIT_UNUSED_ARG(args); SLJIT_UNUSED_ARG(local_size); @@ -598,7 +598,7 @@ static SLJIT_INLINE void set_label(struct sljit_label *label, struct sljit_compi compiler->last_label = label; } -static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, sljit_si flags) +static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, sljit_s32 flags) { jump->next = NULL; jump->flags = flags; @@ -654,19 +654,19 @@ static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_comp break; \ case SLJIT_BREAKPOINT: \ case SLJIT_NOP: \ - case SLJIT_LUMUL: \ - case SLJIT_LSMUL: \ + case SLJIT_LMUL_UW: \ + case SLJIT_LMUL_SW: \ case SLJIT_MOV: \ - case SLJIT_MOV_UI: \ + case SLJIT_MOV_U32: \ case SLJIT_MOV_P: \ case SLJIT_MOVU: \ - case SLJIT_MOVU_UI: \ + case SLJIT_MOVU_U32: \ case SLJIT_MOVU_P: \ /* Nothing allowed */ \ - CHECK_ARGUMENT(!(op & (SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ + CHECK_ARGUMENT(!(op & (SLJIT_I32_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ break; \ default: \ - /* Only SLJIT_INT_OP or SLJIT_SINGLE_OP is allowed. */ \ + /* Only SLJIT_I32_OP or SLJIT_F32_OP is allowed. */ \ CHECK_ARGUMENT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ break; \ } @@ -674,12 +674,12 @@ static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_comp #define FUNCTION_CHECK_FOP() \ CHECK_ARGUMENT(!GET_FLAGS(op) || !(op & SLJIT_KEEP_FLAGS)); \ switch (GET_OPCODE(op)) { \ - case SLJIT_DCMP: \ + case SLJIT_CMP_F64: \ CHECK_ARGUMENT(!(op & (SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ CHECK_ARGUMENT((op & (SLJIT_SET_E | SLJIT_SET_S))); \ break; \ default: \ - /* Only SLJIT_INT_OP or SLJIT_SINGLE_OP is allowed. */ \ + /* Only SLJIT_I32_OP or SLJIT_F32_OP is allowed. */ \ CHECK_ARGUMENT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ break; \ } @@ -844,38 +844,38 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *comp fprintf(compiler->verbose, "fs%d", SLJIT_NUMBER_OF_FLOAT_REGISTERS - (p)); \ } -static SLJIT_CONST char* op0_names[] = { - (char*)"breakpoint", (char*)"nop", (char*)"lumul", (char*)"lsmul", - (char*)"udivmod", (char*)"sdivmod", (char*)"udivi", (char*)"sdivi" +static const char* op0_names[] = { + (char*)"breakpoint", (char*)"nop", (char*)"lmul.uw", (char*)"lmul.sw", + (char*)"divmod.u", (char*)"divmod.s", (char*)"div.u", (char*)"div.s" }; -static SLJIT_CONST char* op1_names[] = { - (char*)"mov", (char*)"mov_ub", (char*)"mov_sb", (char*)"mov_uh", - (char*)"mov_sh", (char*)"mov_ui", (char*)"mov_si", (char*)"mov_p", - (char*)"movu", (char*)"movu_ub", (char*)"movu_sb", (char*)"movu_uh", - (char*)"movu_sh", (char*)"movu_ui", (char*)"movu_si", (char*)"movu_p", +static const char* op1_names[] = { + (char*)"", (char*)".u8", (char*)".s8", (char*)".u16", + (char*)".s16", (char*)".u32", (char*)".s32", (char*)".p", + (char*)"", (char*)".u8", (char*)".s8", (char*)".u16", + (char*)".s16", (char*)".u32", (char*)".s32", (char*)".p", (char*)"not", (char*)"neg", (char*)"clz", }; -static SLJIT_CONST char* op2_names[] = { +static const char* op2_names[] = { (char*)"add", (char*)"addc", (char*)"sub", (char*)"subc", (char*)"mul", (char*)"and", (char*)"or", (char*)"xor", (char*)"shl", (char*)"lshr", (char*)"ashr", }; -static SLJIT_CONST char* fop1_names[] = { +static const char* fop1_names[] = { (char*)"mov", (char*)"conv", (char*)"conv", (char*)"conv", (char*)"conv", (char*)"conv", (char*)"cmp", (char*)"neg", (char*)"abs", }; -static SLJIT_CONST char* fop2_names[] = { +static const char* fop2_names[] = { (char*)"add", (char*)"sub", (char*)"mul", (char*)"div" }; -#define JUMP_PREFIX(type) \ - ((type & 0xff) <= SLJIT_MUL_NOT_OVERFLOW ? ((type & SLJIT_INT_OP) ? "i_" : "") \ - : ((type & 0xff) <= SLJIT_D_ORDERED ? ((type & SLJIT_SINGLE_OP) ? "s_" : "d_") : "")) +#define JUMP_POSTFIX(type) \ + ((type & 0xff) <= SLJIT_MUL_NOT_OVERFLOW ? ((type & SLJIT_I32_OP) ? "32" : "") \ + : ((type & 0xff) <= SLJIT_ORDERED_F64 ? ((type & SLJIT_F32_OP) ? ".f32" : ".f64") : "")) static char* jump_names[] = { (char*)"equal", (char*)"not_equal", @@ -923,8 +923,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_generate_code(struct sljit_com } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { SLJIT_UNUSED_ARG(compiler); @@ -949,8 +949,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compil } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; @@ -977,7 +977,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compi CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(compiler->scratches >= 0); @@ -993,7 +993,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compi if (op == SLJIT_UNUSED) fprintf(compiler->verbose, " return\n"); else { - fprintf(compiler->verbose, " return.%s ", op1_names[op - SLJIT_OP1_BASE]); + fprintf(compiler->verbose, " return%s ", op1_names[op - SLJIT_OP1_BASE]); sljit_verbose_param(compiler, src, srcw); fprintf(compiler->verbose, "\n"); } @@ -1002,7 +1002,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compi CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) FUNCTION_CHECK_DST(dst, dstw); @@ -1017,7 +1017,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_enter(struct sljit_c CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) FUNCTION_CHECK_SRC(src, srcw); @@ -1032,23 +1032,29 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_return(struct sljit_ CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LSMUL) - || ((op & ~SLJIT_INT_OP) >= SLJIT_UDIVMOD && (op & ~SLJIT_INT_OP) <= SLJIT_SDIVI)); - CHECK_ARGUMENT(op < SLJIT_LUMUL || compiler->scratches >= 2); + CHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LMUL_SW) + || ((op & ~SLJIT_I32_OP) >= SLJIT_DIVMOD_UW && (op & ~SLJIT_I32_OP) <= SLJIT_DIV_SW)); + CHECK_ARGUMENT(op < SLJIT_LMUL_UW || compiler->scratches >= 2); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) - fprintf(compiler->verbose, " %s%s\n", !(op & SLJIT_INT_OP) ? "" : "i", op0_names[GET_OPCODE(op) - SLJIT_OP0_BASE]); + { + fprintf(compiler->verbose, " %s", op0_names[GET_OPCODE(op) - SLJIT_OP0_BASE]); + if (GET_OPCODE(op) >= SLJIT_DIVMOD_UW) { + fprintf(compiler->verbose, (op & SLJIT_I32_OP) ? "32" : "w"); + } + fprintf(compiler->verbose, "\n"); + } #endif CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; @@ -1064,9 +1070,18 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE], - !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_U) ? "" : ".u", !(op & SLJIT_SET_S) ? "" : ".s", - !(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); + if (GET_OPCODE(op) <= SLJIT_MOVU_P) + { + fprintf(compiler->verbose, " mov%s%s%s ", (GET_OPCODE(op) >= SLJIT_MOVU) ? "u" : "", + !(op & SLJIT_I32_OP) ? "" : "32", (op != SLJIT_MOV32 && op != SLJIT_MOVU32) ? op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE] : ""); + } + else + { + fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE], !(op & SLJIT_I32_OP) ? "" : "32", + !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_U) ? "" : ".u", !(op & SLJIT_SET_S) ? "" : ".s", + !(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); + } + sljit_verbose_param(compiler, dst, dstw); fprintf(compiler->verbose, ", "); sljit_verbose_param(compiler, src, srcw); @@ -1076,10 +1091,10 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; @@ -1095,7 +1110,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], + fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_I32_OP) ? "" : "32", !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_U) ? "" : ".u", !(op & SLJIT_SET_S) ? "" : ".s", !(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); sljit_verbose_param(compiler, dst, dstw); @@ -1109,7 +1124,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_si reg) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_s32 reg) { SLJIT_UNUSED_ARG(reg); #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -1118,7 +1133,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_si re CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_float_register_index(sljit_si reg) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_float_register_index(sljit_s32 reg) { SLJIT_UNUSED_ARG(reg); #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -1128,7 +1143,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_float_register_index(sljit } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) + void *instruction, sljit_s32 size) { #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) int i; @@ -1152,16 +1167,16 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_co if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " op_custom"); for (i = 0; i < size; i++) - fprintf(compiler->verbose, " 0x%x", ((sljit_ub*)instruction)[i]); + fprintf(compiler->verbose, " 0x%x", ((sljit_u8*)instruction)[i]); fprintf(compiler->verbose, "\n"); } #endif CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; @@ -1170,19 +1185,19 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compile #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_is_fpu_available()); - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_DMOV && GET_OPCODE(op) <= SLJIT_DABS); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV_F64 && GET_OPCODE(op) <= SLJIT_ABS_F64); FUNCTION_CHECK_FOP(); FUNCTION_FCHECK(src, srcw); FUNCTION_FCHECK(dst, dstw); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - if (GET_OPCODE(op) == SLJIT_CONVD_FROMS) - fprintf(compiler->verbose, " %s%s ", fop1_names[SLJIT_CONVD_FROMS - SLJIT_FOP1_BASE], - (op & SLJIT_SINGLE_OP) ? "s.fromd" : "d.froms"); + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) + fprintf(compiler->verbose, " %s%s ", fop1_names[SLJIT_CONV_F64_FROM_F32 - SLJIT_FOP1_BASE], + (op & SLJIT_F32_OP) ? ".f32.from.f64" : ".f64.from.f32"); else - fprintf(compiler->verbose, " %s%s ", (op & SLJIT_SINGLE_OP) ? "s" : "d", - fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE]); + fprintf(compiler->verbose, " %s%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE], + (op & SLJIT_F32_OP) ? ".f32" : ".f64"); sljit_verbose_fparam(compiler, dst, dstw); fprintf(compiler->verbose, ", "); @@ -1193,9 +1208,9 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compile CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; @@ -1204,14 +1219,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_com #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_is_fpu_available()); - CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_DCMP); + CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_CMP_F64); FUNCTION_CHECK_FOP(); FUNCTION_FCHECK(src1, src1w); FUNCTION_FCHECK(src2, src2w); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %s%s%s%s ", (op & SLJIT_SINGLE_OP) ? "s" : "d", fop1_names[SLJIT_DCMP - SLJIT_FOP1_BASE], + fprintf(compiler->verbose, " %s%s%s%s ", fop1_names[SLJIT_CMP_F64 - SLJIT_FOP1_BASE], (op & SLJIT_F32_OP) ? ".f32" : ".f64", (op & SLJIT_SET_E) ? ".e" : "", (op & SLJIT_SET_S) ? ".s" : ""); sljit_verbose_fparam(compiler, src1, src1w); fprintf(compiler->verbose, ", "); @@ -1222,9 +1237,9 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_com CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; @@ -1233,7 +1248,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_convw_fromd(struct s #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_is_fpu_available()); - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONVW_FROMD && GET_OPCODE(op) <= SLJIT_CONVI_FROMD); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONV_SW_FROM_F64 && GET_OPCODE(op) <= SLJIT_CONV_S32_FROM_F64); FUNCTION_CHECK_FOP(); FUNCTION_FCHECK(src, srcw); FUNCTION_CHECK_DST(dst, dstw); @@ -1241,8 +1256,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_convw_fromd(struct s #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE], - (GET_OPCODE(op) == SLJIT_CONVI_FROMD) ? "i" : "w", - (op & SLJIT_SINGLE_OP) ? "s" : "d"); + (GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64) ? ".s32" : ".sw", + (op & SLJIT_F32_OP) ? ".f32" : ".f64"); sljit_verbose_param(compiler, dst, dstw); fprintf(compiler->verbose, ", "); sljit_verbose_fparam(compiler, src, srcw); @@ -1252,9 +1267,9 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_convw_fromd(struct s CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; @@ -1263,7 +1278,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_convd_fromw(struct s #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_is_fpu_available()); - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONVD_FROMW && GET_OPCODE(op) <= SLJIT_CONVD_FROMI); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONV_F64_FROM_SW && GET_OPCODE(op) <= SLJIT_CONV_F64_FROM_S32); FUNCTION_CHECK_FOP(); FUNCTION_CHECK_SRC(src, srcw); FUNCTION_FCHECK(dst, dstw); @@ -1271,8 +1286,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_convd_fromw(struct s #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE], - (op & SLJIT_SINGLE_OP) ? "s" : "d", - (GET_OPCODE(op) == SLJIT_CONVD_FROMI) ? "i" : "w"); + (op & SLJIT_F32_OP) ? ".f32" : ".f64", + (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) ? ".s32" : ".sw"); sljit_verbose_fparam(compiler, dst, dstw); fprintf(compiler->verbose, ", "); sljit_verbose_param(compiler, src, srcw); @@ -1282,14 +1297,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_convd_fromw(struct s CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_is_fpu_available()); - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_DADD && GET_OPCODE(op) <= SLJIT_DDIV); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD_F64 && GET_OPCODE(op) <= SLJIT_DIV_F64); FUNCTION_CHECK_FOP(); FUNCTION_FCHECK(src1, src1w); FUNCTION_FCHECK(src2, src2w); @@ -1297,7 +1312,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compile #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %s%s ", (op & SLJIT_SINGLE_OP) ? "s" : "d", fop2_names[GET_OPCODE(op) - SLJIT_FOP2_BASE]); + fprintf(compiler->verbose, " %s%s ", fop2_names[GET_OPCODE(op) - SLJIT_FOP2_BASE], (op & SLJIT_F32_OP) ? ".f32" : ".f64"); sljit_verbose_fparam(compiler, dst, dstw); fprintf(compiler->verbose, ", "); sljit_verbose_fparam(compiler, src1, src1w); @@ -1320,7 +1335,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_label(struct sljit_compil CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; @@ -1328,33 +1343,33 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compile } #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_INT_OP))); + CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_I32_OP))); CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_CALL3); - CHECK_ARGUMENT((type & 0xff) < SLJIT_JUMP || !(type & SLJIT_INT_OP)); + CHECK_ARGUMENT((type & 0xff) < SLJIT_JUMP || !(type & SLJIT_I32_OP)); CHECK_ARGUMENT((type & 0xff) <= SLJIT_CALL0 || ((type & 0xff) - SLJIT_CALL0) <= compiler->scratches); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) - fprintf(compiler->verbose, " jump%s.%s%s\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", - JUMP_PREFIX(type), jump_names[type & 0xff]); + fprintf(compiler->verbose, " jump%s %s%s\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", + jump_names[type & 0xff], JUMP_POSTFIX(type)); #endif CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_INT_OP))); + CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_I32_OP))); CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_SIG_LESS_EQUAL); FUNCTION_CHECK_SRC(src1, src1w); FUNCTION_CHECK_SRC(src2, src2w); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " cmp%s.%s%s ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", - (type & SLJIT_INT_OP) ? "i_" : "", jump_names[type & 0xff]); + fprintf(compiler->verbose, " cmp%s %s%s, ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", + jump_names[type & 0xff], (type & SLJIT_I32_OP) ? "32" : ""); sljit_verbose_param(compiler, src1, src1w); fprintf(compiler->verbose, ", "); sljit_verbose_param(compiler, src2, src2w); @@ -1364,21 +1379,21 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmp(struct sljit_compiler CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_is_fpu_available()); - CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_SINGLE_OP))); - CHECK_ARGUMENT((type & 0xff) >= SLJIT_D_EQUAL && (type & 0xff) <= SLJIT_D_ORDERED); + CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_F32_OP))); + CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL_F64 && (type & 0xff) <= SLJIT_ORDERED_F64); FUNCTION_FCHECK(src1, src1w); FUNCTION_FCHECK(src2, src2w); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " fcmp%s.%s%s ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", - (type & SLJIT_SINGLE_OP) ? "s_" : "d_", jump_names[type & 0xff]); + fprintf(compiler->verbose, " fcmp%s %s%s, ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", + jump_names[type & 0xff], (type & SLJIT_F32_OP) ? ".f32" : ".f64"); sljit_verbose_fparam(compiler, src1, src1w); fprintf(compiler->verbose, ", "); sljit_verbose_fparam(compiler, src2, src2w); @@ -1388,7 +1403,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compile CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) { if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; @@ -1410,15 +1425,15 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_ijump(struct sljit_compil CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw, + sljit_s32 type) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_INT_OP))); - CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_D_ORDERED); - CHECK_ARGUMENT(op == SLJIT_MOV || GET_OPCODE(op) == SLJIT_MOV_UI || GET_OPCODE(op) == SLJIT_MOV_SI + CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_I32_OP))); + CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_ORDERED_F64); + CHECK_ARGUMENT(op == SLJIT_MOV || GET_OPCODE(op) == SLJIT_MOV_U32 || GET_OPCODE(op) == SLJIT_MOV_S32 || (GET_OPCODE(op) >= SLJIT_AND && GET_OPCODE(op) <= SLJIT_XOR)); CHECK_ARGUMENT((op & (SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C)) == 0); CHECK_ARGUMENT((op & (SLJIT_SET_E | SLJIT_KEEP_FLAGS)) != (SLJIT_SET_E | SLJIT_KEEP_FLAGS)); @@ -1431,21 +1446,22 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_com #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " flags.%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", - GET_OPCODE(op) >= SLJIT_OP2_BASE ? op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE] : op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE], - !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); + fprintf(compiler->verbose, " flags %s%s%s%s, ", + !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k", + GET_OPCODE(op) < SLJIT_OP2_BASE ? "mov" : op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], + GET_OPCODE(op) < SLJIT_OP2_BASE ? op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE] : ((op & SLJIT_I32_OP) ? "32" : "")); sljit_verbose_param(compiler, dst, dstw); if (src != SLJIT_UNUSED) { fprintf(compiler->verbose, ", "); sljit_verbose_param(compiler, src, srcw); } - fprintf(compiler->verbose, ", %s%s\n", JUMP_PREFIX(type), jump_names[type & 0xff]); + fprintf(compiler->verbose, ", %s%s\n", jump_names[type & 0xff], JUMP_POSTFIX(type)); } #endif CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset) { SLJIT_UNUSED_ARG(offset); @@ -1462,7 +1478,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_co CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { SLJIT_UNUSED_ARG(init_value); @@ -1482,31 +1498,31 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compil #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */ #define SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw) \ - SLJIT_COMPILE_ASSERT(!(SLJIT_CONVW_FROMD & 0x1) && !(SLJIT_CONVD_FROMW & 0x1), \ + SLJIT_COMPILE_ASSERT(!(SLJIT_CONV_SW_FROM_F64 & 0x1) && !(SLJIT_CONV_F64_FROM_SW & 0x1), \ invalid_float_opcodes); \ - if (GET_OPCODE(op) >= SLJIT_CONVW_FROMD && GET_OPCODE(op) <= SLJIT_DCMP) { \ - if (GET_OPCODE(op) == SLJIT_DCMP) { \ + if (GET_OPCODE(op) >= SLJIT_CONV_SW_FROM_F64 && GET_OPCODE(op) <= SLJIT_CMP_F64) { \ + if (GET_OPCODE(op) == SLJIT_CMP_F64) { \ CHECK(check_sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw)); \ ADJUST_LOCAL_OFFSET(dst, dstw); \ ADJUST_LOCAL_OFFSET(src, srcw); \ return sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw); \ } \ - if ((GET_OPCODE(op) | 0x1) == SLJIT_CONVI_FROMD) { \ - CHECK(check_sljit_emit_fop1_convw_fromd(compiler, op, dst, dstw, src, srcw)); \ + if ((GET_OPCODE(op) | 0x1) == SLJIT_CONV_S32_FROM_F64) { \ + CHECK(check_sljit_emit_fop1_conv_sw_from_f64(compiler, op, dst, dstw, src, srcw)); \ ADJUST_LOCAL_OFFSET(dst, dstw); \ ADJUST_LOCAL_OFFSET(src, srcw); \ - return sljit_emit_fop1_convw_fromd(compiler, op, dst, dstw, src, srcw); \ + return sljit_emit_fop1_conv_sw_from_f64(compiler, op, dst, dstw, src, srcw); \ } \ - CHECK(check_sljit_emit_fop1_convd_fromw(compiler, op, dst, dstw, src, srcw)); \ + CHECK(check_sljit_emit_fop1_conv_f64_from_sw(compiler, op, dst, dstw, src, srcw)); \ ADJUST_LOCAL_OFFSET(dst, dstw); \ ADJUST_LOCAL_OFFSET(src, srcw); \ - return sljit_emit_fop1_convd_fromw(compiler, op, dst, dstw, src, srcw); \ + return sljit_emit_fop1_conv_f64_from_sw(compiler, op, dst, dstw, src, srcw); \ } \ CHECK(check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw)); \ ADJUST_LOCAL_OFFSET(dst, dstw); \ ADJUST_LOCAL_OFFSET(src, srcw); -static SLJIT_INLINE sljit_si emit_mov_before_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 emit_mov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { /* Return if don't need to do anything. */ if (op == SLJIT_UNUSED) @@ -1517,7 +1533,7 @@ static SLJIT_INLINE sljit_si emit_mov_before_return(struct sljit_compiler *compi if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_P)) return SLJIT_SUCCESS; #else - if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI || op == SLJIT_MOV_P)) + if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_U32 || op == SLJIT_MOV_S32 || op == SLJIT_MOV_P)) return SLJIT_SUCCESS; #endif @@ -1576,12 +1592,12 @@ static SLJIT_INLINE sljit_si emit_mov_before_return(struct sljit_compiler *compi #if !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { /* Default compare for most architectures. */ - sljit_si flags, tmp_src, condition; + sljit_s32 flags, tmp_src, condition; sljit_sw tmp_srcw; CHECK_ERROR_PTR(); @@ -1629,7 +1645,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler condition = SLJIT_SIG_GREATER_EQUAL; break; } - type = condition | (type & (SLJIT_INT_OP | SLJIT_REWRITABLE_JUMP)); + type = condition | (type & (SLJIT_I32_OP | SLJIT_REWRITABLE_JUMP)); tmp_src = src1; src1 = src2; src2 = tmp_src; @@ -1649,7 +1665,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) compiler->skip_checks = 1; #endif - PTR_FAIL_IF(sljit_emit_op2(compiler, SLJIT_SUB | flags | (type & SLJIT_INT_OP), + PTR_FAIL_IF(sljit_emit_op2(compiler, SLJIT_SUB | flags | (type & SLJIT_I32_OP), SLJIT_UNUSED, 0, src1, src1w, src2, src2w)); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -1658,25 +1674,25 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP)); } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si flags, condition; + sljit_s32 flags, condition; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w)); condition = type & 0xff; - flags = (condition <= SLJIT_D_NOT_EQUAL) ? SLJIT_SET_E : SLJIT_SET_S; - if (type & SLJIT_SINGLE_OP) - flags |= SLJIT_SINGLE_OP; + flags = (condition <= SLJIT_NOT_EQUAL_F64) ? SLJIT_SET_E : SLJIT_SET_S; + if (type & SLJIT_F32_OP) + flags |= SLJIT_F32_OP; #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) compiler->skip_checks = 1; #endif - sljit_emit_fop1(compiler, SLJIT_DCMP | flags, src1, src1w, src2, src2w); + sljit_emit_fop1(compiler, SLJIT_CMP_F64 | flags, src1, src1w, src2, src2w); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -1689,7 +1705,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compile #if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset) { CHECK_ERROR(); CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset)); @@ -1710,7 +1726,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *co /* Empty function bodies for those machines, which are not (yet) supported. */ -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) { return "unsupported"; } @@ -1727,7 +1743,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compile SLJIT_ASSERT_STOP(); } -SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(size); @@ -1757,9 +1773,9 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) SLJIT_ASSERT_STOP(); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(options); @@ -1773,9 +1789,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(options); @@ -1789,7 +1805,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); @@ -1799,7 +1815,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(dst); @@ -1808,7 +1824,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(src); @@ -1817,7 +1833,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); @@ -1825,9 +1841,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); @@ -1839,10 +1855,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); @@ -1856,14 +1872,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { SLJIT_ASSERT_STOP(); return reg; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_s32 size) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(instruction); @@ -1872,15 +1888,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void) { SLJIT_ASSERT_STOP(); return 0; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); @@ -1892,10 +1908,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); @@ -1916,7 +1932,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi return NULL; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); @@ -1924,9 +1940,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile return NULL; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); @@ -1938,9 +1954,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler return NULL; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); @@ -1966,7 +1982,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw SLJIT_ASSERT_STOP(); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); @@ -1976,10 +1992,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw, + sljit_s32 type) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); @@ -1992,7 +2008,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(dst); @@ -2002,7 +2018,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *co return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw initval) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw initval) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(dst); diff --git a/pcre2-10.21/src/sljit/sljitLir.h b/pcre2-10.22/src/sljit/sljitLir.h similarity index 79% rename from pcre2-10.21/src/sljit/sljitLir.h rename to pcre2-10.22/src/sljit/sljitLir.h index 2e2e9ac09..df69b8656 100644 --- a/pcre2-10.21/src/sljit/sljitLir.h +++ b/pcre2-10.22/src/sljit/sljitLir.h @@ -226,7 +226,7 @@ of sljitConfigInternal.h */ /* Floating point registers */ /* --------------------------------------------------------------------- */ -/* Each floating point register can store a double or single precision +/* Each floating point register can store a 32 or a 64 bit precision value. The FR and FS register sets are overlap in the same way as R and S register sets. See above. */ @@ -271,7 +271,7 @@ struct sljit_memory_fragment { struct sljit_memory_fragment *next; sljit_uw used_size; /* Must be aligned to sljit_sw. */ - sljit_ub memory[1]; + sljit_u8 memory[1]; }; struct sljit_label { @@ -297,8 +297,8 @@ struct sljit_const { }; struct sljit_compiler { - sljit_si error; - sljit_si options; + sljit_s32 error; + sljit_s32 options; struct sljit_label *labels; struct sljit_jump *jumps; @@ -312,36 +312,36 @@ struct sljit_compiler { struct sljit_memory_fragment *abuf; /* Used scratch registers. */ - sljit_si scratches; + sljit_s32 scratches; /* Used saved registers. */ - sljit_si saveds; + sljit_s32 saveds; /* Used float scratch registers. */ - sljit_si fscratches; + sljit_s32 fscratches; /* Used float saved registers. */ - sljit_si fsaveds; + sljit_s32 fsaveds; /* Local stack size. */ - sljit_si local_size; + sljit_s32 local_size; /* Code size. */ sljit_uw size; /* For statistical purposes. */ sljit_uw executable_size; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - sljit_si args; + sljit_s32 args; #endif #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - sljit_si mode32; + sljit_s32 mode32; #endif #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) - sljit_si flags_saved; + sljit_s32 flags_saved; #endif #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) /* Constant pool handling. */ sljit_uw *cpool; - sljit_ub *cpool_unique; + sljit_u8 *cpool_unique; sljit_uw cpool_diff; sljit_uw cpool_fill; /* Other members. */ @@ -352,40 +352,40 @@ struct sljit_compiler { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) /* Temporary fields. */ sljit_uw shift_imm; - sljit_si cache_arg; + sljit_s32 cache_arg; sljit_sw cache_argw; #endif #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) - sljit_si cache_arg; + sljit_s32 cache_arg; sljit_sw cache_argw; #endif #if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) - sljit_si cache_arg; + sljit_s32 cache_arg; sljit_sw cache_argw; #endif #if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) sljit_sw imm; - sljit_si cache_arg; + sljit_s32 cache_arg; sljit_sw cache_argw; #endif #if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) - sljit_si delay_slot; - sljit_si cache_arg; + sljit_s32 delay_slot; + sljit_s32 cache_arg; sljit_sw cache_argw; #endif #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - sljit_si delay_slot; - sljit_si cache_arg; + sljit_s32 delay_slot; + sljit_s32 cache_arg; sljit_sw cache_argw; #endif #if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) - sljit_si cache_arg; + sljit_s32 cache_arg; sljit_sw cache_argw; #endif @@ -396,13 +396,13 @@ struct sljit_compiler { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ || (defined SLJIT_DEBUG && SLJIT_DEBUG) /* Local size passed to the functions. */ - sljit_si logical_local_size; + sljit_s32 logical_local_size; #endif #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ || (defined SLJIT_DEBUG && SLJIT_DEBUG) \ || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - sljit_si skip_checks; + sljit_s32 skip_checks; #endif }; @@ -427,7 +427,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compile error code. Thus there is no need for checking the error after every call, it is enough to do it before the code is compiled. Removing these checks increases the performance of the compiling process. */ -static SLJIT_INLINE sljit_si sljit_get_compiler_error(struct sljit_compiler *compiler) { return compiler->error; } +static SLJIT_INLINE sljit_s32 sljit_get_compiler_error(struct sljit_compiler *compiler) { return compiler->error; } /* Sets the compiler error code to SLJIT_ERR_ALLOC_FAILED except if an error was detected before. After the error code is set @@ -448,7 +448,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compi indicate that there is no more memory (does not set the current error code of the compiler to out-of-memory status). */ -SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_si size); +SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) /* Passing NULL disables verbose. */ @@ -518,9 +518,9 @@ offset 0 is aligned to sljit_d. Otherwise it is aligned to sljit_uw. */ /* The local_size must be >= 0 and <= SLJIT_MAX_LOCAL_SIZE. */ #define SLJIT_MAX_LOCAL_SIZE 65536 -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size); /* The machine code has a context (which contains the local stack space size, number of used registers, etc.) which initialized by sljit_emit_enter. Several @@ -532,9 +532,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil Note: every call of sljit_emit_enter and sljit_set_context overwrites the previous context. */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size); /* Return from machine code. The op argument can be SLJIT_UNUSED which means the function does not return with anything or any opcode between SLJIT_MOV and @@ -542,8 +542,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi is SLJIT_UNUSED, otherwise see below the description about source and destination arguments. */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, - sljit_si src, sljit_sw srcw); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src, sljit_sw srcw); /* Fast calling mechanism for utility functions (see SLJIT_FAST_CALL). All registers and even the stack frame is passed to the callee. The return address is preserved in @@ -560,8 +560,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi /* Note: although sljit_emit_fast_return could be replaced by an ijump, it is not suggested, since many architectures do clever branch prediction on call / return instruction pairs. */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw); -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw); /* Source and destination values for arithmetical instructions @@ -624,31 +624,29 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * #define SLJIT_MEM2(r1, r2) (SLJIT_MEM | (r1) | ((r2) << 8)) #define SLJIT_IMM 0x40 -/* Set 32 bit operation mode (I) on 64 bit CPUs. The flag is totally ignored on - 32 bit CPUs. If this flag is set for an arithmetic operation, it uses only the - lower 32 bit of the input register(s), and set the CPU status flags according - to the 32 bit result. The higher 32 bits are undefined for both the input and - output. However, the CPU might not ignore those higher 32 bits, like MIPS, which - expects it to be the sign extension of the lower 32 bit. All 32 bit operations - are undefined, if this condition is not fulfilled. Therefore, when SLJIT_INT_OP - is specified, all register arguments must be the result of other operations with - the same SLJIT_INT_OP flag. In other words, although a register can hold either - a 64 or 32 bit value, these values cannot be mixed. The only exceptions are - SLJIT_IMOV and SLJIT_IMOVU (SLJIT_MOV_SI/SLJIT_MOVU_SI with SLJIT_INT_OP flag) - which can convert any source argument to SLJIT_INT_OP compatible result. This - conversion might be unnecessary on some CPUs like x86-64, since the upper 32 - bit is always ignored. In this case SLJIT is clever enough to not generate any - instructions if the source and destination operands are the same registers. - Affects sljit_emit_op0, sljit_emit_op1 and sljit_emit_op2. */ -#define SLJIT_INT_OP 0x100 +/* Set 32 bit operation mode (I) on 64 bit CPUs. This flag is ignored on 32 + bit CPUs. When this flag is set for an arithmetic operation, only the + lower 32 bit of the input register(s) are used, and the CPU status flags + are set according to the 32 bit result. Although the higher 32 bit of + the input and the result registers are not defined by SLJIT, it might be + defined by the CPU architecture (e.g. MIPS). To satisfy these requirements + all source registers must be computed by operations where this flag is + also set. In other words 32 and 64 bit arithmetic operations cannot be + mixed. The only exception is SLJIT_IMOV and SLJIT_IMOVU whose source + register can hold any 32 or 64 bit value. This source register is + converted to a 32 bit compatible format. SLJIT does not generate any + instructions on certain CPUs (e.g. on x86 and ARM) if the source and + destination operands are the same registers. Affects sljit_emit_op0, + sljit_emit_op1 and sljit_emit_op2. */ +#define SLJIT_I32_OP 0x100 -/* Single precision mode (SP). This flag is similar to SLJIT_INT_OP, just +/* F32 precision mode (SP). This flag is similar to SLJIT_I32_OP, just it applies to floating point registers (it is even the same bit). When - this flag is passed, the CPU performs single precision floating point - operations. Similar to SLJIT_INT_OP, all register arguments must be the - result of other floating point operations with this flag. Affects + this flag is passed, the CPU performs 32 bit floating point operations. + Similar to SLJIT_I32_OP, all register arguments must be computed by + floating point operations where this flag is also set. Affects sljit_emit_fop1, sljit_emit_fop2 and sljit_emit_fcmp. */ -#define SLJIT_SINGLE_OP 0x100 +#define SLJIT_F32_OP 0x100 /* Common CPU status flags for all architectures (x86, ARM, PPC) - carry flag @@ -697,43 +695,41 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * /* Flags: - (may destroy flags) Unsigned multiplication of SLJIT_R0 and SLJIT_R1. Result is placed into SLJIT_R1:SLJIT_R0 (high:low) word */ -#define SLJIT_LUMUL (SLJIT_OP0_BASE + 2) +#define SLJIT_LMUL_UW (SLJIT_OP0_BASE + 2) /* Flags: - (may destroy flags) Signed multiplication of SLJIT_R0 and SLJIT_R1. Result is placed into SLJIT_R1:SLJIT_R0 (high:low) word */ -#define SLJIT_LSMUL (SLJIT_OP0_BASE + 3) +#define SLJIT_LMUL_SW (SLJIT_OP0_BASE + 3) /* Flags: I - (may destroy flags) Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1. The result is placed into SLJIT_R0 and the remainder into SLJIT_R1. Note: if SLJIT_R1 is 0, the behaviour is undefined. */ -#define SLJIT_UDIVMOD (SLJIT_OP0_BASE + 4) -#define SLJIT_IUDIVMOD (SLJIT_UDIVMOD | SLJIT_INT_OP) +#define SLJIT_DIVMOD_UW (SLJIT_OP0_BASE + 4) +#define SLJIT_DIVMOD_U32 (SLJIT_DIVMOD_UW | SLJIT_I32_OP) /* Flags: I - (may destroy flags) Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1. The result is placed into SLJIT_R0 and the remainder into SLJIT_R1. Note: if SLJIT_R1 is 0, the behaviour is undefined. Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00), the behaviour is undefined. */ -#define SLJIT_SDIVMOD (SLJIT_OP0_BASE + 5) -#define SLJIT_ISDIVMOD (SLJIT_SDIVMOD | SLJIT_INT_OP) +#define SLJIT_DIVMOD_SW (SLJIT_OP0_BASE + 5) +#define SLJIT_DIVMOD_S32 (SLJIT_DIVMOD_SW | SLJIT_I32_OP) /* Flags: I - (may destroy flags) Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1. The result is placed into SLJIT_R0. SLJIT_R1 preserves its value. - Note: if SLJIT_R1 is 0, the behaviour is undefined. - Note: SLJIT_SDIV is single precision divide. */ -#define SLJIT_UDIVI (SLJIT_OP0_BASE + 6) -#define SLJIT_IUDIVI (SLJIT_UDIVI | SLJIT_INT_OP) + Note: if SLJIT_R1 is 0, the behaviour is undefined. */ +#define SLJIT_DIV_UW (SLJIT_OP0_BASE + 6) +#define SLJIT_DIV_U32 (SLJIT_DIV_UW | SLJIT_I32_OP) /* Flags: I - (may destroy flags) Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1. The result is placed into SLJIT_R0. SLJIT_R1 preserves its value. Note: if SLJIT_R1 is 0, the behaviour is undefined. Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00), - the behaviour is undefined. - Note: SLJIT_SDIV is single precision divide. */ -#define SLJIT_SDIVI (SLJIT_OP0_BASE + 7) -#define SLJIT_ISDIVI (SLJIT_SDIVI | SLJIT_INT_OP) + the behaviour is undefined. */ +#define SLJIT_DIV_SW (SLJIT_OP0_BASE + 7) +#define SLJIT_DIV_S32 (SLJIT_DIV_SW | SLJIT_I32_OP) -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op); /* Starting index of opcodes for sljit_emit_op1. */ #define SLJIT_OP1_BASE 32 @@ -752,188 +748,188 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler /* Flags: - (never set any flags) */ #define SLJIT_MOV (SLJIT_OP1_BASE + 0) /* Flags: I - (never set any flags) */ -#define SLJIT_MOV_UB (SLJIT_OP1_BASE + 1) -#define SLJIT_IMOV_UB (SLJIT_MOV_UB | SLJIT_INT_OP) +#define SLJIT_MOV_U8 (SLJIT_OP1_BASE + 1) +#define SLJIT_MOV32_U8 (SLJIT_MOV_U8 | SLJIT_I32_OP) /* Flags: I - (never set any flags) */ -#define SLJIT_MOV_SB (SLJIT_OP1_BASE + 2) -#define SLJIT_IMOV_SB (SLJIT_MOV_SB | SLJIT_INT_OP) +#define SLJIT_MOV_S8 (SLJIT_OP1_BASE + 2) +#define SLJIT_MOV32_S8 (SLJIT_MOV_S8 | SLJIT_I32_OP) /* Flags: I - (never set any flags) */ -#define SLJIT_MOV_UH (SLJIT_OP1_BASE + 3) -#define SLJIT_IMOV_UH (SLJIT_MOV_UH | SLJIT_INT_OP) +#define SLJIT_MOV_U16 (SLJIT_OP1_BASE + 3) +#define SLJIT_MOV32_U16 (SLJIT_MOV_U16 | SLJIT_I32_OP) /* Flags: I - (never set any flags) */ -#define SLJIT_MOV_SH (SLJIT_OP1_BASE + 4) -#define SLJIT_IMOV_SH (SLJIT_MOV_SH | SLJIT_INT_OP) +#define SLJIT_MOV_S16 (SLJIT_OP1_BASE + 4) +#define SLJIT_MOV32_S16 (SLJIT_MOV_S16 | SLJIT_I32_OP) /* Flags: I - (never set any flags) - Note: see SLJIT_INT_OP for further details. */ -#define SLJIT_MOV_UI (SLJIT_OP1_BASE + 5) -/* No SLJIT_INT_OP form, since it is the same as SLJIT_IMOV. */ + Note: no SLJIT_MOV32_U32 form, since it is the same as SLJIT_MOV32 */ +#define SLJIT_MOV_U32 (SLJIT_OP1_BASE + 5) /* Flags: I - (never set any flags) - Note: see SLJIT_INT_OP for further details. */ -#define SLJIT_MOV_SI (SLJIT_OP1_BASE + 6) -#define SLJIT_IMOV (SLJIT_MOV_SI | SLJIT_INT_OP) + Note: no SLJIT_MOV32_S32 form, since it is the same as SLJIT_MOV32 */ +#define SLJIT_MOV_S32 (SLJIT_OP1_BASE + 6) +/* Flags: I - (never set any flags) */ +#define SLJIT_MOV32 (SLJIT_MOV_S32 | SLJIT_I32_OP) /* Flags: - (never set any flags) */ #define SLJIT_MOV_P (SLJIT_OP1_BASE + 7) /* Flags: - (never set any flags) */ #define SLJIT_MOVU (SLJIT_OP1_BASE + 8) /* Flags: I - (never set any flags) */ -#define SLJIT_MOVU_UB (SLJIT_OP1_BASE + 9) -#define SLJIT_IMOVU_UB (SLJIT_MOVU_UB | SLJIT_INT_OP) +#define SLJIT_MOVU_U8 (SLJIT_OP1_BASE + 9) +#define SLJIT_MOVU32_U8 (SLJIT_MOVU_U8 | SLJIT_I32_OP) /* Flags: I - (never set any flags) */ -#define SLJIT_MOVU_SB (SLJIT_OP1_BASE + 10) -#define SLJIT_IMOVU_SB (SLJIT_MOVU_SB | SLJIT_INT_OP) +#define SLJIT_MOVU_S8 (SLJIT_OP1_BASE + 10) +#define SLJIT_MOVU32_S8 (SLJIT_MOVU_S8 | SLJIT_I32_OP) /* Flags: I - (never set any flags) */ -#define SLJIT_MOVU_UH (SLJIT_OP1_BASE + 11) -#define SLJIT_IMOVU_UH (SLJIT_MOVU_UH | SLJIT_INT_OP) +#define SLJIT_MOVU_U16 (SLJIT_OP1_BASE + 11) +#define SLJIT_MOVU32_U16 (SLJIT_MOVU_U16 | SLJIT_I32_OP) /* Flags: I - (never set any flags) */ -#define SLJIT_MOVU_SH (SLJIT_OP1_BASE + 12) -#define SLJIT_IMOVU_SH (SLJIT_MOVU_SH | SLJIT_INT_OP) +#define SLJIT_MOVU_S16 (SLJIT_OP1_BASE + 12) +#define SLJIT_MOVU32_S16 (SLJIT_MOVU_S16 | SLJIT_I32_OP) /* Flags: I - (never set any flags) - Note: see SLJIT_INT_OP for further details. */ -#define SLJIT_MOVU_UI (SLJIT_OP1_BASE + 13) -/* No SLJIT_INT_OP form, since it is the same as SLJIT_IMOVU. */ + Note: no SLJIT_MOVU32_U32 form, since it is the same as SLJIT_MOVU32 */ +#define SLJIT_MOVU_U32 (SLJIT_OP1_BASE + 13) /* Flags: I - (never set any flags) - Note: see SLJIT_INT_OP for further details. */ -#define SLJIT_MOVU_SI (SLJIT_OP1_BASE + 14) -#define SLJIT_IMOVU (SLJIT_MOVU_SI | SLJIT_INT_OP) + Note: no SLJIT_MOVU32_S32 form, since it is the same as SLJIT_MOVU32 */ +#define SLJIT_MOVU_S32 (SLJIT_OP1_BASE + 14) +/* Flags: I - (never set any flags) */ +#define SLJIT_MOVU32 (SLJIT_MOVU_S32 | SLJIT_I32_OP) /* Flags: - (never set any flags) */ #define SLJIT_MOVU_P (SLJIT_OP1_BASE + 15) /* Flags: I | E | K */ #define SLJIT_NOT (SLJIT_OP1_BASE + 16) -#define SLJIT_INOT (SLJIT_NOT | SLJIT_INT_OP) +#define SLJIT_NOT32 (SLJIT_NOT | SLJIT_I32_OP) /* Flags: I | E | O | K */ #define SLJIT_NEG (SLJIT_OP1_BASE + 17) -#define SLJIT_INEG (SLJIT_NEG | SLJIT_INT_OP) +#define SLJIT_NEG32 (SLJIT_NEG | SLJIT_I32_OP) /* Count leading zeroes Flags: I | E | K Important note! Sparc 32 does not support K flag, since the required popc instruction is introduced only in sparc 64. */ #define SLJIT_CLZ (SLJIT_OP1_BASE + 18) -#define SLJIT_ICLZ (SLJIT_CLZ | SLJIT_INT_OP) +#define SLJIT_CLZ32 (SLJIT_CLZ | SLJIT_I32_OP) -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw); /* Starting index of opcodes for sljit_emit_op2. */ #define SLJIT_OP2_BASE 96 /* Flags: I | E | O | C | K */ #define SLJIT_ADD (SLJIT_OP2_BASE + 0) -#define SLJIT_IADD (SLJIT_ADD | SLJIT_INT_OP) +#define SLJIT_ADD32 (SLJIT_ADD | SLJIT_I32_OP) /* Flags: I | C | K */ #define SLJIT_ADDC (SLJIT_OP2_BASE + 1) -#define SLJIT_IADDC (SLJIT_ADDC | SLJIT_INT_OP) +#define SLJIT_ADDC32 (SLJIT_ADDC | SLJIT_I32_OP) /* Flags: I | E | U | S | O | C | K */ #define SLJIT_SUB (SLJIT_OP2_BASE + 2) -#define SLJIT_ISUB (SLJIT_SUB | SLJIT_INT_OP) +#define SLJIT_SUB32 (SLJIT_SUB | SLJIT_I32_OP) /* Flags: I | C | K */ #define SLJIT_SUBC (SLJIT_OP2_BASE + 3) -#define SLJIT_ISUBC (SLJIT_SUBC | SLJIT_INT_OP) +#define SLJIT_SUBC32 (SLJIT_SUBC | SLJIT_I32_OP) /* Note: integer mul Flags: I | O (see SLJIT_C_MUL_*) | K */ #define SLJIT_MUL (SLJIT_OP2_BASE + 4) -#define SLJIT_IMUL (SLJIT_MUL | SLJIT_INT_OP) +#define SLJIT_MUL32 (SLJIT_MUL | SLJIT_I32_OP) /* Flags: I | E | K */ #define SLJIT_AND (SLJIT_OP2_BASE + 5) -#define SLJIT_IAND (SLJIT_AND | SLJIT_INT_OP) +#define SLJIT_AND32 (SLJIT_AND | SLJIT_I32_OP) /* Flags: I | E | K */ #define SLJIT_OR (SLJIT_OP2_BASE + 6) -#define SLJIT_IOR (SLJIT_OR | SLJIT_INT_OP) +#define SLJIT_OR32 (SLJIT_OR | SLJIT_I32_OP) /* Flags: I | E | K */ #define SLJIT_XOR (SLJIT_OP2_BASE + 7) -#define SLJIT_IXOR (SLJIT_XOR | SLJIT_INT_OP) +#define SLJIT_XOR32 (SLJIT_XOR | SLJIT_I32_OP) /* Flags: I | E | K Let bit_length be the length of the shift operation: 32 or 64. If src2 is immediate, src2w is masked by (bit_length - 1). Otherwise, if the content of src2 is outside the range from 0 to bit_length - 1, the result is undefined. */ #define SLJIT_SHL (SLJIT_OP2_BASE + 8) -#define SLJIT_ISHL (SLJIT_SHL | SLJIT_INT_OP) +#define SLJIT_SHL32 (SLJIT_SHL | SLJIT_I32_OP) /* Flags: I | E | K Let bit_length be the length of the shift operation: 32 or 64. If src2 is immediate, src2w is masked by (bit_length - 1). Otherwise, if the content of src2 is outside the range from 0 to bit_length - 1, the result is undefined. */ #define SLJIT_LSHR (SLJIT_OP2_BASE + 9) -#define SLJIT_ILSHR (SLJIT_LSHR | SLJIT_INT_OP) +#define SLJIT_LSHR32 (SLJIT_LSHR | SLJIT_I32_OP) /* Flags: I | E | K Let bit_length be the length of the shift operation: 32 or 64. If src2 is immediate, src2w is masked by (bit_length - 1). Otherwise, if the content of src2 is outside the range from 0 to bit_length - 1, the result is undefined. */ #define SLJIT_ASHR (SLJIT_OP2_BASE + 10) -#define SLJIT_IASHR (SLJIT_ASHR | SLJIT_INT_OP) +#define SLJIT_ASHR32 (SLJIT_ASHR | SLJIT_I32_OP) -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w); /* Returns with non-zero if fpu is available. */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void); /* Starting index of opcodes for sljit_emit_fop1. */ #define SLJIT_FOP1_BASE 128 /* Flags: SP - (never set any flags) */ -#define SLJIT_DMOV (SLJIT_FOP1_BASE + 0) -#define SLJIT_SMOV (SLJIT_DMOV | SLJIT_SINGLE_OP) +#define SLJIT_MOV_F64 (SLJIT_FOP1_BASE + 0) +#define SLJIT_MOV_F32 (SLJIT_MOV_F64 | SLJIT_F32_OP) /* Convert opcodes: CONV[DST_TYPE].FROM[SRC_TYPE] SRC/DST TYPE can be: D - double, S - single, W - signed word, I - signed int Rounding mode when the destination is W or I: round towards zero. */ /* Flags: SP - (never set any flags) */ -#define SLJIT_CONVD_FROMS (SLJIT_FOP1_BASE + 1) -#define SLJIT_CONVS_FROMD (SLJIT_CONVD_FROMS | SLJIT_SINGLE_OP) +#define SLJIT_CONV_F64_FROM_F32 (SLJIT_FOP1_BASE + 1) +#define SLJIT_CONV_F32_FROM_F64 (SLJIT_CONV_F64_FROM_F32 | SLJIT_F32_OP) /* Flags: SP - (never set any flags) */ -#define SLJIT_CONVW_FROMD (SLJIT_FOP1_BASE + 2) -#define SLJIT_CONVW_FROMS (SLJIT_CONVW_FROMD | SLJIT_SINGLE_OP) +#define SLJIT_CONV_SW_FROM_F64 (SLJIT_FOP1_BASE + 2) +#define SLJIT_CONV_SW_FROM_F32 (SLJIT_CONV_SW_FROM_F64 | SLJIT_F32_OP) /* Flags: SP - (never set any flags) */ -#define SLJIT_CONVI_FROMD (SLJIT_FOP1_BASE + 3) -#define SLJIT_CONVI_FROMS (SLJIT_CONVI_FROMD | SLJIT_SINGLE_OP) +#define SLJIT_CONV_S32_FROM_F64 (SLJIT_FOP1_BASE + 3) +#define SLJIT_CONV_S32_FROM_F32 (SLJIT_CONV_S32_FROM_F64 | SLJIT_F32_OP) /* Flags: SP - (never set any flags) */ -#define SLJIT_CONVD_FROMW (SLJIT_FOP1_BASE + 4) -#define SLJIT_CONVS_FROMW (SLJIT_CONVD_FROMW | SLJIT_SINGLE_OP) +#define SLJIT_CONV_F64_FROM_SW (SLJIT_FOP1_BASE + 4) +#define SLJIT_CONV_F32_FROM_SW (SLJIT_CONV_F64_FROM_SW | SLJIT_F32_OP) /* Flags: SP - (never set any flags) */ -#define SLJIT_CONVD_FROMI (SLJIT_FOP1_BASE + 5) -#define SLJIT_CONVS_FROMI (SLJIT_CONVD_FROMI | SLJIT_SINGLE_OP) +#define SLJIT_CONV_F64_FROM_S32 (SLJIT_FOP1_BASE + 5) +#define SLJIT_CONV_F32_FROM_S32 (SLJIT_CONV_F64_FROM_S32 | SLJIT_F32_OP) /* Note: dst is the left and src is the right operand for SLJIT_CMPD. Note: NaN check is always performed. If SLJIT_C_FLOAT_UNORDERED flag is set, the comparison result is unpredictable. Flags: SP | E | S (see SLJIT_C_FLOAT_*) */ -#define SLJIT_DCMP (SLJIT_FOP1_BASE + 6) -#define SLJIT_SCMP (SLJIT_DCMP | SLJIT_SINGLE_OP) +#define SLJIT_CMP_F64 (SLJIT_FOP1_BASE + 6) +#define SLJIT_CMP_F32 (SLJIT_CMP_F64 | SLJIT_F32_OP) /* Flags: SP - (never set any flags) */ -#define SLJIT_DNEG (SLJIT_FOP1_BASE + 7) -#define SLJIT_SNEG (SLJIT_DNEG | SLJIT_SINGLE_OP) +#define SLJIT_NEG_F64 (SLJIT_FOP1_BASE + 7) +#define SLJIT_NEG_F32 (SLJIT_NEG_F64 | SLJIT_F32_OP) /* Flags: SP - (never set any flags) */ -#define SLJIT_DABS (SLJIT_FOP1_BASE + 8) -#define SLJIT_SABS (SLJIT_DABS | SLJIT_SINGLE_OP) +#define SLJIT_ABS_F64 (SLJIT_FOP1_BASE + 8) +#define SLJIT_ABS_F32 (SLJIT_ABS_F64 | SLJIT_F32_OP) -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw); /* Starting index of opcodes for sljit_emit_fop2. */ #define SLJIT_FOP2_BASE 160 /* Flags: SP - (never set any flags) */ -#define SLJIT_DADD (SLJIT_FOP2_BASE + 0) -#define SLJIT_SADD (SLJIT_DADD | SLJIT_SINGLE_OP) +#define SLJIT_ADD_F64 (SLJIT_FOP2_BASE + 0) +#define SLJIT_ADD_F32 (SLJIT_ADD_F64 | SLJIT_F32_OP) /* Flags: SP - (never set any flags) */ -#define SLJIT_DSUB (SLJIT_FOP2_BASE + 1) -#define SLJIT_SSUB (SLJIT_DSUB | SLJIT_SINGLE_OP) +#define SLJIT_SUB_F64 (SLJIT_FOP2_BASE + 1) +#define SLJIT_SUB_F32 (SLJIT_SUB_F64 | SLJIT_F32_OP) /* Flags: SP - (never set any flags) */ -#define SLJIT_DMUL (SLJIT_FOP2_BASE + 2) -#define SLJIT_SMUL (SLJIT_DMUL | SLJIT_SINGLE_OP) +#define SLJIT_MUL_F64 (SLJIT_FOP2_BASE + 2) +#define SLJIT_MUL_F32 (SLJIT_MUL_F64 | SLJIT_F32_OP) /* Flags: SP - (never set any flags) */ -#define SLJIT_DDIV (SLJIT_FOP2_BASE + 3) -#define SLJIT_SDIV (SLJIT_DDIV | SLJIT_SINGLE_OP) +#define SLJIT_DIV_F64 (SLJIT_FOP2_BASE + 3) +#define SLJIT_DIV_F32 (SLJIT_DIV_F64 | SLJIT_F32_OP) -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w); /* Label and jump instructions. */ @@ -943,58 +939,58 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi /* Integer comparison types. */ #define SLJIT_EQUAL 0 -#define SLJIT_I_EQUAL (SLJIT_EQUAL | SLJIT_INT_OP) +#define SLJIT_EQUAL32 (SLJIT_EQUAL | SLJIT_I32_OP) #define SLJIT_ZERO 0 -#define SLJIT_I_ZERO (SLJIT_ZERO | SLJIT_INT_OP) +#define SLJIT_ZERO32 (SLJIT_ZERO | SLJIT_I32_OP) #define SLJIT_NOT_EQUAL 1 -#define SLJIT_I_NOT_EQUAL (SLJIT_NOT_EQUAL | SLJIT_INT_OP) +#define SLJIT_NOT_EQUAL32 (SLJIT_NOT_EQUAL | SLJIT_I32_OP) #define SLJIT_NOT_ZERO 1 -#define SLJIT_I_NOT_ZERO (SLJIT_NOT_ZERO | SLJIT_INT_OP) +#define SLJIT_NOT_ZERO32 (SLJIT_NOT_ZERO | SLJIT_I32_OP) #define SLJIT_LESS 2 -#define SLJIT_I_LESS (SLJIT_LESS | SLJIT_INT_OP) +#define SLJIT_LESS32 (SLJIT_LESS | SLJIT_I32_OP) #define SLJIT_GREATER_EQUAL 3 -#define SLJIT_I_GREATER_EQUAL (SLJIT_GREATER_EQUAL | SLJIT_INT_OP) +#define SLJIT_GREATER_EQUAL32 (SLJIT_GREATER_EQUAL | SLJIT_I32_OP) #define SLJIT_GREATER 4 -#define SLJIT_I_GREATER (SLJIT_GREATER | SLJIT_INT_OP) +#define SLJIT_GREATER32 (SLJIT_GREATER | SLJIT_I32_OP) #define SLJIT_LESS_EQUAL 5 -#define SLJIT_I_LESS_EQUAL (SLJIT_LESS_EQUAL | SLJIT_INT_OP) +#define SLJIT_LESS_EQUAL32 (SLJIT_LESS_EQUAL | SLJIT_I32_OP) #define SLJIT_SIG_LESS 6 -#define SLJIT_I_SIG_LESS (SLJIT_SIG_LESS | SLJIT_INT_OP) +#define SLJIT_SIG_LESS32 (SLJIT_SIG_LESS | SLJIT_I32_OP) #define SLJIT_SIG_GREATER_EQUAL 7 -#define SLJIT_I_SIG_GREATER_EQUAL (SLJIT_SIG_GREATER_EQUAL | SLJIT_INT_OP) +#define SLJIT_SIG_GREATER_EQUAL32 (SLJIT_SIG_GREATER_EQUAL | SLJIT_I32_OP) #define SLJIT_SIG_GREATER 8 -#define SLJIT_I_SIG_GREATER (SLJIT_SIG_GREATER | SLJIT_INT_OP) +#define SLJIT_SIG_GREATER32 (SLJIT_SIG_GREATER | SLJIT_I32_OP) #define SLJIT_SIG_LESS_EQUAL 9 -#define SLJIT_I_SIG_LESS_EQUAL (SLJIT_SIG_LESS_EQUAL | SLJIT_INT_OP) +#define SLJIT_SIG_LESS_EQUAL32 (SLJIT_SIG_LESS_EQUAL | SLJIT_I32_OP) #define SLJIT_OVERFLOW 10 -#define SLJIT_I_OVERFLOW (SLJIT_OVERFLOW | SLJIT_INT_OP) +#define SLJIT_OVERFLOW32 (SLJIT_OVERFLOW | SLJIT_I32_OP) #define SLJIT_NOT_OVERFLOW 11 -#define SLJIT_I_NOT_OVERFLOW (SLJIT_NOT_OVERFLOW | SLJIT_INT_OP) +#define SLJIT_NOT_OVERFLOW32 (SLJIT_NOT_OVERFLOW | SLJIT_I32_OP) #define SLJIT_MUL_OVERFLOW 12 -#define SLJIT_I_MUL_OVERFLOW (SLJIT_MUL_OVERFLOW | SLJIT_INT_OP) +#define SLJIT_MUL_OVERFLOW32 (SLJIT_MUL_OVERFLOW | SLJIT_I32_OP) #define SLJIT_MUL_NOT_OVERFLOW 13 -#define SLJIT_I_MUL_NOT_OVERFLOW (SLJIT_MUL_NOT_OVERFLOW | SLJIT_INT_OP) +#define SLJIT_MUL_NOT_OVERFLOW32 (SLJIT_MUL_NOT_OVERFLOW | SLJIT_I32_OP) /* Floating point comparison types. */ -#define SLJIT_D_EQUAL 14 -#define SLJIT_S_EQUAL (SLJIT_D_EQUAL | SLJIT_SINGLE_OP) -#define SLJIT_D_NOT_EQUAL 15 -#define SLJIT_S_NOT_EQUAL (SLJIT_D_NOT_EQUAL | SLJIT_SINGLE_OP) -#define SLJIT_D_LESS 16 -#define SLJIT_S_LESS (SLJIT_D_LESS | SLJIT_SINGLE_OP) -#define SLJIT_D_GREATER_EQUAL 17 -#define SLJIT_S_GREATER_EQUAL (SLJIT_D_GREATER_EQUAL | SLJIT_SINGLE_OP) -#define SLJIT_D_GREATER 18 -#define SLJIT_S_GREATER (SLJIT_D_GREATER | SLJIT_SINGLE_OP) -#define SLJIT_D_LESS_EQUAL 19 -#define SLJIT_S_LESS_EQUAL (SLJIT_D_LESS_EQUAL | SLJIT_SINGLE_OP) -#define SLJIT_D_UNORDERED 20 -#define SLJIT_S_UNORDERED (SLJIT_D_UNORDERED | SLJIT_SINGLE_OP) -#define SLJIT_D_ORDERED 21 -#define SLJIT_S_ORDERED (SLJIT_D_ORDERED | SLJIT_SINGLE_OP) +#define SLJIT_EQUAL_F64 14 +#define SLJIT_EQUAL_F32 (SLJIT_EQUAL_F64 | SLJIT_F32_OP) +#define SLJIT_NOT_EQUAL_F64 15 +#define SLJIT_NOT_EQUAL_F32 (SLJIT_NOT_EQUAL_F64 | SLJIT_F32_OP) +#define SLJIT_LESS_F64 16 +#define SLJIT_LESS_F32 (SLJIT_LESS_F64 | SLJIT_F32_OP) +#define SLJIT_GREATER_EQUAL_F64 17 +#define SLJIT_GREATER_EQUAL_F32 (SLJIT_GREATER_EQUAL_F64 | SLJIT_F32_OP) +#define SLJIT_GREATER_F64 18 +#define SLJIT_GREATER_F32 (SLJIT_GREATER_F64 | SLJIT_F32_OP) +#define SLJIT_LESS_EQUAL_F64 19 +#define SLJIT_LESS_EQUAL_F32 (SLJIT_LESS_EQUAL_F64 | SLJIT_F32_OP) +#define SLJIT_UNORDERED_F64 20 +#define SLJIT_UNORDERED_F32 (SLJIT_UNORDERED_F64 | SLJIT_F32_OP) +#define SLJIT_ORDERED_F64 21 +#define SLJIT_ORDERED_F32 (SLJIT_ORDERED_F64 | SLJIT_F32_OP) /* Unconditional jump types. */ #define SLJIT_JUMP 22 @@ -1014,7 +1010,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP Flags: - (never set any flags) for both conditional and unconditional jumps. Flags: destroy all flags for calls. */ -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type); +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type); /* Basic arithmetic comparison. In most architectures it is implemented as an SLJIT_SUB operation (with SLJIT_UNUSED destination and setting @@ -1024,23 +1020,23 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile type must be between SLJIT_EQUAL and SLJIT_I_SIG_LESS_EQUAL type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP Flags: destroy flags. */ -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w); +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w); /* Basic floating point comparison. In most architectures it is implemented as an SLJIT_FCMP operation (setting appropriate flags) followed by a sljit_emit_jump. However some architectures (i.e: MIPS) may employ special optimizations here. It is suggested to use this comparison form when appropriate. - type must be between SLJIT_D_EQUAL and SLJIT_S_ORDERED + type must be between SLJIT_EQUAL_F64 and SLJIT_ORDERED_F32 type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP Flags: destroy flags. Note: if either operand is NaN, the behaviour is undefined for types up to SLJIT_S_LESS_EQUAL. */ -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w); +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w); /* Set the destination of the jump to this label. */ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label); @@ -1053,14 +1049,14 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw Indirect form: any other valid addressing mode Flags: - (never set any flags) for unconditional jumps. Flags: destroy all flags for calls. */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw); /* Perform the operation using the conditional flags as the second argument. Type must always be between SLJIT_EQUAL and SLJIT_S_ORDERED. The value represented by the type is 1, if the condition represented by the type is fulfilled, and 0 otherwise. - If op == SLJIT_MOV, SLJIT_MOV_SI, SLJIT_MOV_UI: + If op == SLJIT_MOV, SLJIT_MOV_S32, SLJIT_MOV_U32: Set dst to the value represented by the type (0 or 1). Src must be SLJIT_UNUSED, and srcw must be 0 Flags: - (never set any flags) @@ -1070,18 +1066,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil Important note: only dst=src and dstw=srcw is supported at the moment! Flags: I | E | K Note: sljit_emit_op_flags does nothing, if dst is SLJIT_UNUSED (regardless of op). */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw, + sljit_s32 type); /* Copies the base address of SLJIT_SP + offset to dst. Flags: - (never set any flags) */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset); /* The constant can be changed runtime (see: sljit_set_const) Flags: - (never set any flags) */ -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value); +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value); /* After the code generation the address for label, jump and const instructions are computed. Since these structures are freed by sljit_free_compiler, the @@ -1104,7 +1100,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta /* Get the human readable name of the platform. Can be useful on platforms like ARM, where ARM and Thumb2 functions can be mixed, and it is useful to know the type of the code generator. */ -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void); +SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void); /* Portable helper function to get an offset of a member. */ #define SLJIT_OFFSETOF(base, member) ((sljit_sw)(&((base*)0x10)->member) - 0x10) @@ -1196,14 +1192,14 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct Note: it returns with -1 for virtual registers (only on x86-32). */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg); /* The following function is a helper function for sljit_emit_op_custom. It returns with the real machine register index of any SLJIT_FLOAT register. Note: the index is always an even number on ARM (except ARM-64), MIPS, and SPARC. */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg); /* Any instruction can be inserted into the instruction stream by sljit_emit_op_custom. It has a similar purpose as inline assembly. @@ -1215,18 +1211,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg); if size == 4, the instruction argument must be 4 byte aligned. Otherwise: size must be 4 and instruction argument must be 4 byte aligned. */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_s32 size); #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) /* Returns with non-zero if sse2 is available. */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_sse2_available(void); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_is_sse2_available(void); /* Returns with non-zero if cmov instruction is available. */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_cmov_available(void); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_is_cmov_available(void); /* Emit a conditional mov instruction on x86 CPUs. This instruction moves src to destination, if the condition is satisfied. Unlike @@ -1235,14 +1231,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_cmov_available(void); checked by sljit_x86_is_cmov_available function. type must be between SLJIT_EQUAL and SLJIT_S_ORDERED dst_reg must be a valid register and it can be combined - with SLJIT_INT_OP to perform 32 bit arithmetic + with SLJIT_I32_OP to perform 32 bit arithmetic Flags: I - (never set any flags) */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_emit_cmov(struct sljit_compiler *compiler, - sljit_si type, - sljit_si dst_reg, - sljit_si src, sljit_sw srcw); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_emit_cmov(struct sljit_compiler *compiler, + sljit_s32 type, + sljit_s32 dst_reg, + sljit_s32 src, sljit_sw srcw); #endif diff --git a/pcre2-10.21/src/sljit/sljitNativeARM_32.c b/pcre2-10.22/src/sljit/sljitNativeARM_32.c similarity index 85% rename from pcre2-10.21/src/sljit/sljitNativeARM_32.c rename to pcre2-10.22/src/sljit/sljitNativeARM_32.c index 5cd4c71a2..b92808f52 100644 --- a/pcre2-10.21/src/sljit/sljitNativeARM_32.c +++ b/pcre2-10.22/src/sljit/sljitNativeARM_32.c @@ -24,7 +24,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) { #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) return "ARMv7" SLJIT_CPUINFO; @@ -52,10 +52,10 @@ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) #define ALIGN_INSTRUCTION(ptr) \ (sljit_uw*)(((sljit_uw)(ptr) + (CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1) & ~((CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1)) #define MAX_DIFFERENCE(max_diff) \ - (((max_diff) / (sljit_si)sizeof(sljit_uw)) - (CONST_POOL_ALIGNMENT - 1)) + (((max_diff) / (sljit_s32)sizeof(sljit_uw)) - (CONST_POOL_ALIGNMENT - 1)) /* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */ -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { +static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { 0, 0, 1, 2, 11, 10, 9, 8, 7, 6, 5, 4, 13, 3, 12, 14, 15 }; @@ -126,13 +126,13 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) -static sljit_si push_cpool(struct sljit_compiler *compiler) +static sljit_s32 push_cpool(struct sljit_compiler *compiler) { /* Pushing the constant pool into the instruction stream. */ sljit_uw* inst; sljit_uw* cpool_ptr; sljit_uw* cpool_end; - sljit_si i; + sljit_s32 i; /* The label could point the address after the constant pool. */ if (compiler->last_label && compiler->last_label->size == compiler->size) @@ -164,7 +164,7 @@ static sljit_si push_cpool(struct sljit_compiler *compiler) return SLJIT_SUCCESS; } -static sljit_si push_inst(struct sljit_compiler *compiler, sljit_uw inst) +static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_uw inst) { sljit_uw* ptr; @@ -178,13 +178,13 @@ static sljit_si push_inst(struct sljit_compiler *compiler, sljit_uw inst) return SLJIT_SUCCESS; } -static sljit_si push_inst_with_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal) +static sljit_s32 push_inst_with_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal) { sljit_uw* ptr; sljit_uw cpool_index = CPOOL_SIZE; sljit_uw* cpool_ptr; sljit_uw* cpool_end; - sljit_ub* cpool_unique_ptr; + sljit_u8* cpool_unique_ptr; if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092))) FAIL_IF(push_cpool(compiler)); @@ -228,7 +228,7 @@ static sljit_si push_inst_with_literal(struct sljit_compiler *compiler, sljit_uw return SLJIT_SUCCESS; } -static sljit_si push_inst_with_unique_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal) +static sljit_s32 push_inst_with_unique_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal) { sljit_uw* ptr; if (SLJIT_UNLIKELY((compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)) || compiler->cpool_fill >= CPOOL_SIZE)) @@ -248,7 +248,7 @@ static sljit_si push_inst_with_unique_literal(struct sljit_compiler *compiler, s return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si prepare_blx(struct sljit_compiler *compiler) +static SLJIT_INLINE sljit_s32 prepare_blx(struct sljit_compiler *compiler) { /* Place for at least two instruction (doesn't matter whether the first has a literal). */ if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4088))) @@ -256,7 +256,7 @@ static SLJIT_INLINE sljit_si prepare_blx(struct sljit_compiler *compiler) return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_blx(struct sljit_compiler *compiler) +static SLJIT_INLINE sljit_s32 emit_blx(struct sljit_compiler *compiler) { /* Must follow tightly the previous instruction (to be able to convert it to bl instruction). */ SLJIT_ASSERT(compiler->cpool_diff == CONST_POOL_EMPTY || compiler->size - compiler->cpool_diff < MAX_DIFFERENCE(4092)); @@ -286,7 +286,7 @@ static sljit_uw patch_pc_relative_loads(sljit_uw *last_pc_patch, sljit_uw *code_ /* Must be a load instruction with immediate offset. */ SLJIT_ASSERT(ind < cpool_size && !(*last_pc_patch & (1 << 25)) && (*last_pc_patch & (1 << 20))); - if ((sljit_si)const_pool[ind] < 0) { + if ((sljit_s32)const_pool[ind] < 0) { const_pool[ind] = counter; ind = counter; counter++; @@ -311,26 +311,26 @@ static sljit_uw patch_pc_relative_loads(sljit_uw *last_pc_patch, sljit_uw *code_ /* In some rare ocasions we may need future patches. The probability is close to 0 in practice. */ struct future_patch { struct future_patch* next; - sljit_si index; - sljit_si value; + sljit_s32 index; + sljit_s32 value; }; -static sljit_si resolve_const_pool_index(struct sljit_compiler *compiler, struct future_patch **first_patch, sljit_uw cpool_current_index, sljit_uw *cpool_start_address, sljit_uw *buf_ptr) +static sljit_s32 resolve_const_pool_index(struct sljit_compiler *compiler, struct future_patch **first_patch, sljit_uw cpool_current_index, sljit_uw *cpool_start_address, sljit_uw *buf_ptr) { - sljit_si value; + sljit_s32 value; struct future_patch *curr_patch, *prev_patch; SLJIT_UNUSED_ARG(compiler); /* Using the values generated by patch_pc_relative_loads. */ if (!*first_patch) - value = (sljit_si)cpool_start_address[cpool_current_index]; + value = (sljit_s32)cpool_start_address[cpool_current_index]; else { curr_patch = *first_patch; - prev_patch = 0; + prev_patch = NULL; while (1) { if (!curr_patch) { - value = (sljit_si)cpool_start_address[cpool_current_index]; + value = (sljit_s32)cpool_start_address[cpool_current_index]; break; } if ((sljit_uw)curr_patch->index == cpool_current_index) { @@ -370,7 +370,7 @@ static sljit_si resolve_const_pool_index(struct sljit_compiler *compiler, struct #else -static sljit_si push_inst(struct sljit_compiler *compiler, sljit_uw inst) +static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_uw inst) { sljit_uw* ptr; @@ -381,7 +381,7 @@ static sljit_si push_inst(struct sljit_compiler *compiler, sljit_uw inst) return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_imm(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm) +static SLJIT_INLINE sljit_s32 emit_imm(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm) { FAIL_IF(push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff))); return push_inst(compiler, MOVT | RD(reg) | ((imm >> 12) & 0xf0000) | ((imm >> 16) & 0xfff)); @@ -389,7 +389,7 @@ static SLJIT_INLINE sljit_si emit_imm(struct sljit_compiler *compiler, sljit_si #endif -static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code) +static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code) { sljit_sw diff; @@ -446,13 +446,13 @@ static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uw return 0; } -static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, sljit_si flush) +static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, sljit_s32 flush) { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) sljit_uw *ptr = (sljit_uw*)addr; sljit_uw *inst = (sljit_uw*)ptr[0]; sljit_uw mov_pc = ptr[1]; - sljit_si bl = (mov_pc & 0x0000f000) != RD(TMP_PC); + sljit_s32 bl = (mov_pc & 0x0000f000) != RD(TMP_PC); sljit_sw diff = (sljit_sw)(((sljit_sw)new_addr - (sljit_sw)(inst + 2)) >> 2); if (diff <= 0x7fffff && diff >= -0x800000) { @@ -504,7 +504,7 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, static sljit_uw get_imm(sljit_uw imm); -static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw new_constant, sljit_si flush) +static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw new_constant, sljit_s32 flush) { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) sljit_uw *ptr = (sljit_uw*)addr; @@ -789,7 +789,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } #endif - SLJIT_ASSERT(code_ptr - code <= (sljit_si)size); + SLJIT_ASSERT(code_ptr - code <= (sljit_s32)size); compiler->error = SLJIT_ERR_COMPILED; compiler->executable_size = (code_ptr - code) * sizeof(sljit_uw); @@ -820,16 +820,16 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #define EMIT_DATA_PROCESS_INS(opcode, set_flags, dst, src1, src2) \ (0xe0000000 | ((opcode) << 21) | (set_flags) | RD(dst) | RN(src1) | (src2)) -static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si inp_flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w); +static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 inp_flags, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w); -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_si size, i, tmp; + sljit_s32 size, i, tmp; sljit_uw push; CHECK_ERROR(); @@ -866,11 +866,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_si size; + sljit_s32 size; CHECK_ERROR(); CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -881,9 +881,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { - sljit_si i, tmp; + sljit_s32 i, tmp; sljit_uw pop; CHECK_ERROR(); @@ -983,8 +983,8 @@ static sljit_sw data_transfer_insts[16] = { } \ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (reg_map[(flags & ARGS_SWAPPED) ? src1 : src2] << 8) | (opcode << 5) | 0x10 | ((flags & ARGS_SWAPPED) ? reg_map[src2] : reg_map[src1]))); -static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_si src1, sljit_si src2) +static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, + sljit_s32 dst, sljit_s32 src1, sljit_s32 src2) { sljit_sw mul_inst; @@ -1001,17 +1001,17 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj } return SLJIT_SUCCESS; - case SLJIT_MOV_UB: - case SLJIT_MOV_SB: + case SLJIT_MOV_U8: + case SLJIT_MOV_S8: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); if ((flags & (REG_DEST | REG_SOURCE)) == (REG_DEST | REG_SOURCE)) { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - if (op == SLJIT_MOV_UB) + if (op == SLJIT_MOV_U8) return push_inst(compiler, EMIT_DATA_PROCESS_INS(AND_DP, 0, dst, src2, SRC2_IMM | 0xff)); FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | reg_map[src2]))); - return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | (op == SLJIT_MOV_UB ? 0x20 : 0x40) | reg_map[dst])); + return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | (op == SLJIT_MOV_U8 ? 0x20 : 0x40) | reg_map[dst])); #else - return push_inst(compiler, (op == SLJIT_MOV_UB ? UXTB : SXTB) | RD(dst) | RM(src2)); + return push_inst(compiler, (op == SLJIT_MOV_U8 ? UXTB : SXTB) | RD(dst) | RM(src2)); #endif } else if (dst != src2) { @@ -1022,15 +1022,15 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj } return SLJIT_SUCCESS; - case SLJIT_MOV_UH: - case SLJIT_MOV_SH: + case SLJIT_MOV_U16: + case SLJIT_MOV_S16: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); if ((flags & (REG_DEST | REG_SOURCE)) == (REG_DEST | REG_SOURCE)) { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | reg_map[src2]))); - return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | (op == SLJIT_MOV_UH ? 0x20 : 0x40) | reg_map[dst])); + return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | (op == SLJIT_MOV_U16 ? 0x20 : 0x40) | reg_map[dst])); #else - return push_inst(compiler, (op == SLJIT_MOV_UH ? UXTH : SXTH) | RD(dst) | RM(src2)); + return push_inst(compiler, (op == SLJIT_MOV_U16 ? UXTH : SXTH) | RD(dst) | RM(src2)); #endif } else if (dst != src2) { @@ -1139,7 +1139,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj Returns with 0 if not possible. */ static sljit_uw get_imm(sljit_uw imm) { - sljit_si rol; + sljit_s32 rol; if (imm <= 0xff) return SRC2_IMM | imm; @@ -1175,12 +1175,12 @@ static sljit_uw get_imm(sljit_uw imm) } #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) -static sljit_si generate_int(struct sljit_compiler *compiler, sljit_si reg, sljit_uw imm, sljit_si positive) +static sljit_s32 generate_int(struct sljit_compiler *compiler, sljit_s32 reg, sljit_uw imm, sljit_s32 positive) { sljit_uw mask; sljit_uw imm1; sljit_uw imm2; - sljit_si rol; + sljit_s32 rol; /* Step1: Search a zero byte (8 continous zero bit). */ mask = 0xff000000; @@ -1286,7 +1286,7 @@ static sljit_si generate_int(struct sljit_compiler *compiler, sljit_si reg, slji } #endif -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sljit_uw imm) +static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_uw imm) { sljit_uw tmp; @@ -1317,7 +1317,7 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sl } /* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */ -static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sljit_si reg, sljit_sw value) +static sljit_s32 emit_set_delta(struct sljit_compiler *compiler, sljit_s32 dst, sljit_s32 reg, sljit_sw value) { if (value >= 0) { value = get_imm(value); @@ -1333,7 +1333,7 @@ static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sl } /* Can perform an operation using at most 1 instruction. */ -static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { sljit_uw imm; @@ -1408,7 +1408,7 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_fl /* See getput_arg below. Note: can_cache is called only for binary operators. Those operators always uses word arguments without write back. */ -static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { /* Immediate caching is not supported as it would be an operation on constant arguments. */ if (arg & SLJIT_IMM) @@ -1456,9 +1456,9 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_ } /* Emit the necessary instructions. See can_cache above. */ -static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { - sljit_si tmp_r; + sljit_s32 tmp_r; sljit_sw max_delta; sljit_sw sign; sljit_uw imm; @@ -1583,7 +1583,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, return push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, reg_map[tmp_r] | (max_delta & 0xf00 ? SRC2_IMM : 0))); } -static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { if (getput_arg_fast(compiler, flags, reg, arg, argw)) return compiler->error; @@ -1592,17 +1592,17 @@ static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_ return getput_arg(compiler, flags, reg, arg, argw, 0, 0); } -static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w) { if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) return compiler->error; return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); } -static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si inp_flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 inp_flags, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { /* arg1 goes to TMP_REG1 or src reg arg2 goes to TMP_REG2, imm or src reg @@ -1610,25 +1610,25 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ /* We prefers register and simple consts. */ - sljit_si dst_r; - sljit_si src1_r; - sljit_si src2_r = 0; - sljit_si sugg_src2_r = TMP_REG2; - sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0; + sljit_s32 dst_r; + sljit_s32 src1_r; + sljit_s32 src2_r = 0; + sljit_s32 sugg_src2_r = TMP_REG2; + sljit_s32 flags = GET_FLAGS(op) ? SET_FLAGS : 0; compiler->cache_arg = 0; compiler->cache_argw = 0; /* Destination check. */ if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32 && !(src2 & SLJIT_MEM)) return SLJIT_SUCCESS; dst_r = TMP_REG2; } else if (FAST_IS_REG(dst)) { dst_r = dst; flags |= REG_DEST; - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) sugg_src2_r = dst_r; } else { @@ -1695,7 +1695,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i if (FAST_IS_REG(src2)) { src2_r = src2; flags |= REG_SOURCE; - if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) dst_r = src2_r; } else do { /* do { } while(0) is used because of breaks. */ @@ -1804,7 +1804,7 @@ extern int __aeabi_idivmod(int numerator, int denominator); } #endif -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { CHECK_ERROR(); CHECK(check_sljit_emit_op0(compiler, op)); @@ -1817,58 +1817,58 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler case SLJIT_NOP: FAIL_IF(push_inst(compiler, NOP)); break; - case SLJIT_LUMUL: - case SLJIT_LSMUL: + case SLJIT_LMUL_UW: + case SLJIT_LMUL_SW: #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) - return push_inst(compiler, (op == SLJIT_LUMUL ? UMULL : SMULL) + return push_inst(compiler, (op == SLJIT_LMUL_UW ? UMULL : SMULL) | (reg_map[SLJIT_R1] << 16) | (reg_map[SLJIT_R0] << 12) | (reg_map[SLJIT_R0] << 8) | reg_map[SLJIT_R1]); #else FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, RM(SLJIT_R1)))); - return push_inst(compiler, (op == SLJIT_LUMUL ? UMULL : SMULL) + return push_inst(compiler, (op == SLJIT_LMUL_UW ? UMULL : SMULL) | (reg_map[SLJIT_R1] << 16) | (reg_map[SLJIT_R0] << 12) | (reg_map[SLJIT_R0] << 8) | reg_map[TMP_REG1]); #endif - case SLJIT_UDIVMOD: - case SLJIT_SDIVMOD: - case SLJIT_UDIVI: - case SLJIT_SDIVI: - SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments); + case SLJIT_DIVMOD_UW: + case SLJIT_DIVMOD_SW: + case SLJIT_DIV_UW: + case SLJIT_DIV_SW: + SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments); SLJIT_COMPILE_ASSERT(reg_map[2] == 1 && reg_map[3] == 2, bad_register_mapping); - if ((op >= SLJIT_UDIVI) && (compiler->scratches >= 3)) { + if ((op >= SLJIT_DIV_UW) && (compiler->scratches >= 3)) { FAIL_IF(push_inst(compiler, 0xe52d2008 /* str r2, [sp, #-8]! */)); FAIL_IF(push_inst(compiler, 0xe58d1004 /* str r1, [sp, #4] */)); } - else if ((op >= SLJIT_UDIVI) || (compiler->scratches >= 3)) - FAIL_IF(push_inst(compiler, 0xe52d0008 | (op >= SLJIT_UDIVI ? 0x1000 : 0x2000) /* str r1/r2, [sp, #-8]! */)); + else if ((op >= SLJIT_DIV_UW) || (compiler->scratches >= 3)) + FAIL_IF(push_inst(compiler, 0xe52d0008 | (op >= SLJIT_DIV_UW ? 0x1000 : 0x2000) /* str r1/r2, [sp, #-8]! */)); #if defined(__GNUC__) FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM, - ((op | 0x2) == SLJIT_UDIVI ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod)))); + ((op | 0x2) == SLJIT_DIV_UW ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod)))); #else #error "Software divmod functions are needed" #endif - if ((op >= SLJIT_UDIVI) && (compiler->scratches >= 3)) { + if ((op >= SLJIT_DIV_UW) && (compiler->scratches >= 3)) { FAIL_IF(push_inst(compiler, 0xe59d1004 /* ldr r1, [sp, #4] */)); FAIL_IF(push_inst(compiler, 0xe49d2008 /* ldr r2, [sp], #8 */)); } - else if ((op >= SLJIT_UDIVI) || (compiler->scratches >= 3)) - return push_inst(compiler, 0xe49d0008 | (op >= SLJIT_UDIVI ? 0x1000 : 0x2000) /* ldr r1/r2, [sp], #8 */); + else if ((op >= SLJIT_DIV_UW) || (compiler->scratches >= 3)) + return push_inst(compiler, 0xe49d0008 | (op >= SLJIT_DIV_UW ? 0x1000 : 0x2000) /* ldr r1/r2, [sp], #8 */); return SLJIT_SUCCESS; } return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { CHECK_ERROR(); CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); @@ -1877,40 +1877,40 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler switch (GET_OPCODE(op)) { case SLJIT_MOV: - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: + case SLJIT_MOV_U32: + case SLJIT_MOV_S32: case SLJIT_MOV_P: return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOV_UB: - return emit_op(compiler, SLJIT_MOV_UB, ALLOW_ANY_IMM | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + case SLJIT_MOV_U8: + return emit_op(compiler, SLJIT_MOV_U8, ALLOW_ANY_IMM | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw); - case SLJIT_MOV_SB: - return emit_op(compiler, SLJIT_MOV_SB, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + case SLJIT_MOV_S8: + return emit_op(compiler, SLJIT_MOV_S8, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw); - case SLJIT_MOV_UH: - return emit_op(compiler, SLJIT_MOV_UH, ALLOW_ANY_IMM | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + case SLJIT_MOV_U16: + return emit_op(compiler, SLJIT_MOV_U16, ALLOW_ANY_IMM | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw); - case SLJIT_MOV_SH: - return emit_op(compiler, SLJIT_MOV_SH, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + case SLJIT_MOV_S16: + return emit_op(compiler, SLJIT_MOV_S16, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw); case SLJIT_MOVU: - case SLJIT_MOVU_UI: - case SLJIT_MOVU_SI: + case SLJIT_MOVU_U32: + case SLJIT_MOVU_S32: case SLJIT_MOVU_P: return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOVU_UB: - return emit_op(compiler, SLJIT_MOV_UB, ALLOW_ANY_IMM | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + case SLJIT_MOVU_U8: + return emit_op(compiler, SLJIT_MOV_U8, ALLOW_ANY_IMM | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw); - case SLJIT_MOVU_SB: - return emit_op(compiler, SLJIT_MOV_SB, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + case SLJIT_MOVU_S8: + return emit_op(compiler, SLJIT_MOV_S8, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw); - case SLJIT_MOVU_UH: - return emit_op(compiler, SLJIT_MOV_UH, ALLOW_ANY_IMM | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + case SLJIT_MOVU_U16: + return emit_op(compiler, SLJIT_MOV_U16, ALLOW_ANY_IMM | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw); - case SLJIT_MOVU_SH: - return emit_op(compiler, SLJIT_MOV_SH, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + case SLJIT_MOVU_S16: + return emit_op(compiler, SLJIT_MOV_S16, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw); case SLJIT_NOT: return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw); @@ -1929,10 +1929,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { CHECK_ERROR(); CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -1971,20 +1971,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_register_index(reg)); return reg_map[reg]; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); return reg << 1; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_s32 size) { CHECK_ERROR(); CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); @@ -2000,7 +2000,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co /* 0 - no fpu 1 - vfp */ -static sljit_si arm_fpu_type = -1; +static sljit_s32 arm_fpu_type = -1; static void init_compiler(void) { @@ -2011,7 +2011,7 @@ static void init_compiler(void) arm_fpu_type = 1; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void) { #ifdef SLJIT_IS_FPU_AVAILABLE return SLJIT_IS_FPU_AVAILABLE; @@ -2026,7 +2026,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) #define arm_fpu_type 1 -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void) { /* Always available. */ return 1; @@ -2040,11 +2040,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) #define EMIT_FPU_OPERATION(opcode, mode, dst, src1, src2) \ ((opcode) | (mode) | ((dst) << 12) | (src1) | ((src2) << 16)) -static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { sljit_sw tmp; sljit_uw imm; - sljit_sw inst = VSTR_F32 | (flags & (SLJIT_SINGLE_OP | FPU_LOAD)); + sljit_sw inst = VSTR_F32 | (flags & (SLJIT_F32_OP | FPU_LOAD)); SLJIT_ASSERT(arg & SLJIT_MEM); if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { @@ -2104,16 +2104,16 @@ static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sl return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, 0)); } -static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { if (src & SLJIT_MEM) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src, srcw)); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src, srcw)); src = TMP_FREG1; } - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_S32_F32, op & SLJIT_SINGLE_OP, TMP_FREG1, src, 0))); + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_S32_F32, op & SLJIT_F32_OP, TMP_FREG1, src, 0))); if (dst == SLJIT_UNUSED) return SLJIT_SUCCESS; @@ -2125,11 +2125,11 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler * return emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw); } -static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; if (FAST_IS_REG(src)) FAIL_IF(push_inst(compiler, VMOV | RD(src) | (TMP_FREG1 << 16))); @@ -2142,85 +2142,85 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler * FAIL_IF(push_inst(compiler, VMOV | RD(TMP_REG1) | (TMP_FREG1 << 16))); } - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_F32_S32, op & SLJIT_SINGLE_OP, dst_r, TMP_FREG1, 0))); + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_F32_S32, op & SLJIT_F32_OP, dst_r, TMP_FREG1, 0))); if (dst & SLJIT_MEM) - return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw); + return emit_fop_mem(compiler, (op & SLJIT_F32_OP), TMP_FREG1, dst, dstw); return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { if (src1 & SLJIT_MEM) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w)); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src1, src1w)); src1 = TMP_FREG1; } if (src2 & SLJIT_MEM) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w)); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG2, src2, src2w)); src2 = TMP_FREG2; } - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCMP_F32, op & SLJIT_SINGLE_OP, src1, src2, 0))); + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCMP_F32, op & SLJIT_F32_OP, src1, src2, 0))); return push_inst(compiler, VMRS); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r; + sljit_s32 dst_r; CHECK_ERROR(); compiler->cache_arg = 0; compiler->cache_argw = 0; - if (GET_OPCODE(op) != SLJIT_CONVD_FROMS) - op ^= SLJIT_SINGLE_OP; + if (GET_OPCODE(op) != SLJIT_CONV_F64_FROM_F32) + op ^= SLJIT_F32_OP; - SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100), float_transfer_bit_error); + SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100), float_transfer_bit_error); SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; if (src & SLJIT_MEM) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, dst_r, src, srcw)); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, dst_r, src, srcw)); src = dst_r; } switch (GET_OPCODE(op)) { - case SLJIT_DMOV: + case SLJIT_MOV_F64: if (src != dst_r) { if (dst_r != TMP_FREG1) - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMOV_F32, op & SLJIT_SINGLE_OP, dst_r, src, 0))); + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMOV_F32, op & SLJIT_F32_OP, dst_r, src, 0))); else dst_r = src; } break; - case SLJIT_DNEG: - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VNEG_F32, op & SLJIT_SINGLE_OP, dst_r, src, 0))); + case SLJIT_NEG_F64: + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VNEG_F32, op & SLJIT_F32_OP, dst_r, src, 0))); break; - case SLJIT_DABS: - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VABS_F32, op & SLJIT_SINGLE_OP, dst_r, src, 0))); + case SLJIT_ABS_F64: + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VABS_F32, op & SLJIT_F32_OP, dst_r, src, 0))); break; - case SLJIT_CONVD_FROMS: - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_F64_F32, op & SLJIT_SINGLE_OP, dst_r, src, 0))); - op ^= SLJIT_SINGLE_OP; + case SLJIT_CONV_F64_FROM_F32: + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_F64_F32, op & SLJIT_F32_OP, dst_r, src, 0))); + op ^= SLJIT_F32_OP; break; } if (dst & SLJIT_MEM) - return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), dst_r, dst, dstw); + return emit_fop_mem(compiler, (op & SLJIT_F32_OP), dst_r, dst, dstw); return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si dst_r; + sljit_s32 dst_r; CHECK_ERROR(); CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -2230,40 +2230,40 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile compiler->cache_arg = 0; compiler->cache_argw = 0; - op ^= SLJIT_SINGLE_OP; + op ^= SLJIT_F32_OP; dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; if (src2 & SLJIT_MEM) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w)); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG2, src2, src2w)); src2 = TMP_FREG2; } if (src1 & SLJIT_MEM) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w)); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src1, src1w)); src1 = TMP_FREG1; } switch (GET_OPCODE(op)) { - case SLJIT_DADD: - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VADD_F32, op & SLJIT_SINGLE_OP, dst_r, src2, src1))); + case SLJIT_ADD_F64: + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VADD_F32, op & SLJIT_F32_OP, dst_r, src2, src1))); break; - case SLJIT_DSUB: - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VSUB_F32, op & SLJIT_SINGLE_OP, dst_r, src2, src1))); + case SLJIT_SUB_F64: + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VSUB_F32, op & SLJIT_F32_OP, dst_r, src2, src1))); break; - case SLJIT_DMUL: - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMUL_F32, op & SLJIT_SINGLE_OP, dst_r, src2, src1))); + case SLJIT_MUL_F64: + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMUL_F32, op & SLJIT_F32_OP, dst_r, src2, src1))); break; - case SLJIT_DDIV: - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VDIV_F32, op & SLJIT_SINGLE_OP, dst_r, src2, src1))); + case SLJIT_DIV_F64: + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VDIV_F32, op & SLJIT_F32_OP, dst_r, src2, src1))); break; } if (dst_r == TMP_FREG1) - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw)); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP), TMP_FREG1, dst, dstw)); return SLJIT_SUCCESS; } @@ -2276,7 +2276,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile /* Other instructions */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); @@ -2299,7 +2299,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c return getput_arg(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); @@ -2326,33 +2326,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * /* Conditional instructions */ /* --------------------------------------------------------------------- */ -static sljit_uw get_cc(sljit_si type) +static sljit_uw get_cc(sljit_s32 type) { switch (type) { case SLJIT_EQUAL: case SLJIT_MUL_NOT_OVERFLOW: - case SLJIT_D_EQUAL: + case SLJIT_EQUAL_F64: return 0x00000000; case SLJIT_NOT_EQUAL: case SLJIT_MUL_OVERFLOW: - case SLJIT_D_NOT_EQUAL: + case SLJIT_NOT_EQUAL_F64: return 0x10000000; case SLJIT_LESS: - case SLJIT_D_LESS: + case SLJIT_LESS_F64: return 0x30000000; case SLJIT_GREATER_EQUAL: - case SLJIT_D_GREATER_EQUAL: + case SLJIT_GREATER_EQUAL_F64: return 0x20000000; case SLJIT_GREATER: - case SLJIT_D_GREATER: + case SLJIT_GREATER_F64: return 0x80000000; case SLJIT_LESS_EQUAL: - case SLJIT_D_LESS_EQUAL: + case SLJIT_LESS_EQUAL_F64: return 0x90000000; case SLJIT_SIG_LESS: @@ -2368,11 +2368,11 @@ static sljit_uw get_cc(sljit_si type) return 0xd0000000; case SLJIT_OVERFLOW: - case SLJIT_D_UNORDERED: + case SLJIT_UNORDERED_F64: return 0x60000000; case SLJIT_NOT_OVERFLOW: - case SLJIT_D_ORDERED: + case SLJIT_ORDERED_F64: return 0x70000000; default: @@ -2397,7 +2397,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi return label; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { struct sljit_jump *jump; @@ -2438,7 +2438,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile return jump; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) { struct sljit_jump *jump; @@ -2475,12 +2475,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw, + sljit_s32 type) { - sljit_si dst_r, flags = GET_ALL_FLAGS(op); + sljit_s32 dst_r, flags = GET_ALL_FLAGS(op); sljit_uw cc, ins; CHECK_ERROR(); @@ -2528,10 +2528,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com return (flags & SLJIT_SET_E) ? push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, SET_FLAGS, TMP_REG1, SLJIT_UNUSED, RM(dst_r))) : SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; - sljit_si reg; + sljit_s32 reg; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); diff --git a/pcre2-10.21/src/sljit/sljitNativeARM_64.c b/pcre2-10.22/src/sljit/sljitNativeARM_64.c similarity index 85% rename from pcre2-10.21/src/sljit/sljitNativeARM_64.c rename to pcre2-10.22/src/sljit/sljitNativeARM_64.c index 044a675ee..d9958512c 100644 --- a/pcre2-10.21/src/sljit/sljitNativeARM_64.c +++ b/pcre2-10.22/src/sljit/sljitNativeARM_64.c @@ -24,13 +24,13 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) { return "ARM-64" SLJIT_CPUINFO; } /* Length of an instruction word */ -typedef sljit_ui sljit_ins; +typedef sljit_u32 sljit_ins; #define TMP_ZERO (0) @@ -43,7 +43,7 @@ typedef sljit_ui sljit_ins; #define TMP_FREG1 (0) #define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 8] = { +static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 8] = { 31, 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 16, 17, 8, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 29, 9, 10, 11, 30, 31 }; @@ -124,7 +124,7 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 8] = { /* dest_reg is the absolute name of the register Useful for reordering instructions in the delay slot. */ -static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins) +static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins) { sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); @@ -133,7 +133,7 @@ static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins) return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_imm64_const(struct sljit_compiler *compiler, sljit_si dst, sljit_uw imm) +static SLJIT_INLINE sljit_s32 emit_imm64_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_uw imm) { FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((imm & 0xffff) << 5))); FAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((imm >> 16) & 0xffff) << 5) | (1 << 21))); @@ -143,7 +143,7 @@ static SLJIT_INLINE sljit_si emit_imm64_const(struct sljit_compiler *compiler, s static SLJIT_INLINE void modify_imm64_const(sljit_ins* inst, sljit_uw new_imm) { - sljit_si dst = inst[0] & 0x1f; + sljit_s32 dst = inst[0] & 0x1f; SLJIT_ASSERT((inst[0] & 0xffe00000) == MOVZ && (inst[1] & 0xffe00000) == (MOVK | (1 << 21))); inst[0] = MOVZ | dst | ((new_imm & 0xffff) << 5); inst[1] = MOVK | dst | (((new_imm >> 16) & 0xffff) << 5) | (1 << 21); @@ -151,7 +151,7 @@ static SLJIT_INLINE void modify_imm64_const(sljit_ins* inst, sljit_uw new_imm) inst[3] = MOVK | dst | ((new_imm >> 48) << 5) | (3 << 21); } -static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) +static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) { sljit_sw diff; sljit_uw target_addr; @@ -212,7 +212,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil sljit_ins *buf_end; sljit_uw word_count; sljit_uw addr; - sljit_si dst; + sljit_s32 dst; struct sljit_label *label; struct sljit_jump *jump; @@ -346,9 +346,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #define LOGICAL_IMM_CHECK 0x100 -static sljit_ins logical_imm(sljit_sw imm, sljit_si len) +static sljit_ins logical_imm(sljit_sw imm, sljit_s32 len) { - sljit_si negated, ones, right; + sljit_s32 negated, ones, right; sljit_uw mask, uimm; sljit_ins ins; @@ -356,12 +356,12 @@ static sljit_ins logical_imm(sljit_sw imm, sljit_si len) len &= ~LOGICAL_IMM_CHECK; if (len == 32 && (imm == 0 || imm == -1)) return 0; - if (len == 16 && ((sljit_si)imm == 0 || (sljit_si)imm == -1)) + if (len == 16 && ((sljit_s32)imm == 0 || (sljit_s32)imm == -1)) return 0; } SLJIT_ASSERT((len == 32 && imm != 0 && imm != -1) - || (len == 16 && (sljit_si)imm != 0 && (sljit_si)imm != -1)); + || (len == 16 && (sljit_s32)imm != 0 && (sljit_s32)imm != -1)); uimm = (sljit_uw)imm; while (1) { if (len <= 0) { @@ -410,10 +410,10 @@ static sljit_ins logical_imm(sljit_sw imm, sljit_si len) #undef COUNT_TRAILING_ZERO -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sljit_sw simm) +static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw simm) { sljit_uw imm = (sljit_uw)simm; - sljit_si i, zeros, ones, first; + sljit_s32 i, zeros, ones, first; sljit_ins bitmask; if (imm <= 0xffff) @@ -512,15 +512,15 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sl dst = TMP_ZERO; \ } -static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, sljit_si dst, sljit_sw arg1, sljit_sw arg2) +static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 dst, sljit_sw arg1, sljit_sw arg2) { /* dst must be register, TMP_REG1 arg1 must be register, TMP_REG1, imm arg2 must be register, TMP_REG2, imm */ sljit_ins inv_bits = (flags & INT_OP) ? (1 << 31) : 0; sljit_ins inst_bits; - sljit_si op = (flags & 0xffff); - sljit_si reg; + sljit_s32 op = (flags & 0xffff); + sljit_s32 reg; sljit_sw imm, nimm; if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) { @@ -667,34 +667,34 @@ static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, slj if (dst == arg2) return SLJIT_SUCCESS; return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(arg2)); - case SLJIT_MOV_UB: - case SLJIT_MOVU_UB: + case SLJIT_MOV_U8: + case SLJIT_MOVU_U8: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); return push_inst(compiler, (UBFM ^ (1 << 31)) | RD(dst) | RN(arg2) | (7 << 10)); - case SLJIT_MOV_SB: - case SLJIT_MOVU_SB: + case SLJIT_MOV_S8: + case SLJIT_MOVU_S8: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if (!(flags & INT_OP)) inv_bits |= 1 << 22; return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (7 << 10)); - case SLJIT_MOV_UH: - case SLJIT_MOVU_UH: + case SLJIT_MOV_U16: + case SLJIT_MOVU_U16: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); return push_inst(compiler, (UBFM ^ (1 << 31)) | RD(dst) | RN(arg2) | (15 << 10)); - case SLJIT_MOV_SH: - case SLJIT_MOVU_SH: + case SLJIT_MOV_S16: + case SLJIT_MOVU_S16: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if (!(flags & INT_OP)) inv_bits |= 1 << 22; return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (15 << 10)); - case SLJIT_MOV_UI: - case SLJIT_MOVU_UI: + case SLJIT_MOV_U32: + case SLJIT_MOVU_U32: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if ((flags & INT_OP) && dst == arg2) return SLJIT_SUCCESS; return push_inst(compiler, (ORR ^ (1 << 31)) | RD(dst) | RN(TMP_ZERO) | RM(arg2)); - case SLJIT_MOV_SI: - case SLJIT_MOVU_SI: + case SLJIT_MOV_S32: + case SLJIT_MOVU_S32: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if ((flags & INT_OP) && dst == arg2) return SLJIT_SUCCESS; @@ -777,28 +777,28 @@ static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, slj #define MEM_SIZE_SHIFT(flags) ((flags) >> 8) -static SLJIT_CONST sljit_ins sljit_mem_imm[4] = { +static const sljit_ins sljit_mem_imm[4] = { /* u l */ 0x39400000 /* ldrb [reg,imm] */, /* u s */ 0x39000000 /* strb [reg,imm] */, /* s l */ 0x39800000 /* ldrsb [reg,imm] */, /* s s */ 0x39000000 /* strb [reg,imm] */, }; -static SLJIT_CONST sljit_ins sljit_mem_simm[4] = { +static const sljit_ins sljit_mem_simm[4] = { /* u l */ 0x38400000 /* ldurb [reg,imm] */, /* u s */ 0x38000000 /* sturb [reg,imm] */, /* s l */ 0x38800000 /* ldursb [reg,imm] */, /* s s */ 0x38000000 /* sturb [reg,imm] */, }; -static SLJIT_CONST sljit_ins sljit_mem_pre_simm[4] = { +static const sljit_ins sljit_mem_pre_simm[4] = { /* u l */ 0x38400c00 /* ldrb [reg,imm]! */, /* u s */ 0x38000c00 /* strb [reg,imm]! */, /* s l */ 0x38800c00 /* ldrsb [reg,imm]! */, /* s s */ 0x38000c00 /* strb [reg,imm]! */, }; -static SLJIT_CONST sljit_ins sljit_mem_reg[4] = { +static const sljit_ins sljit_mem_reg[4] = { /* u l */ 0x38606800 /* ldrb [reg,reg] */, /* u s */ 0x38206800 /* strb [reg,reg] */, /* s l */ 0x38a06800 /* ldrsb [reg,reg] */, @@ -806,7 +806,7 @@ static SLJIT_CONST sljit_ins sljit_mem_reg[4] = { }; /* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */ -static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sljit_si reg, sljit_sw value) +static sljit_s32 emit_set_delta(struct sljit_compiler *compiler, sljit_s32 dst, sljit_s32 reg, sljit_sw value) { if (value >= 0) { if (value <= 0xfff) @@ -825,9 +825,9 @@ static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sl } /* Can perform an operation using at most 1 instruction. */ -static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { - sljit_ui shift = MEM_SIZE_SHIFT(flags); + sljit_u32 shift = MEM_SIZE_SHIFT(flags); SLJIT_ASSERT(arg & SLJIT_MEM); @@ -882,7 +882,7 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, /* see getput_arg below. Note: can_cache is called only for binary operators. Those operators always uses word arguments without write back. */ -static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { sljit_sw diff; if ((arg & OFFS_REG_MASK) || !(next_arg & SLJIT_MEM)) @@ -906,11 +906,11 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_ } /* Emit the necessary instructions. See can_cache above. */ -static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, - sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, + sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { - sljit_ui shift = MEM_SIZE_SHIFT(flags); - sljit_si tmp_r, other_r; + sljit_u32 shift = MEM_SIZE_SHIFT(flags); + sljit_s32 tmp_r, other_r; sljit_sw diff; SLJIT_ASSERT(arg & SLJIT_MEM); @@ -1040,7 +1040,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(TMP_REG3)); } -static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { if (getput_arg_fast(compiler, flags, reg, arg, argw)) return compiler->error; @@ -1049,7 +1049,7 @@ static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_ return getput_arg(compiler, flags, reg, arg, argw, 0, 0); } -static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w) { if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) return compiler->error; @@ -1060,11 +1060,11 @@ static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit /* Entry, exit */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_si i, tmp, offs, prev, saved_regs_size; + sljit_s32 i, tmp, offs, prev, saved_regs_size; CHECK_ERROR(); CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -1148,9 +1148,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { CHECK_ERROR(); CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -1162,10 +1162,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { - sljit_si local_size; - sljit_si i, tmp, offs, prev, saved_regs_size; + sljit_s32 local_size; + sljit_s32 i, tmp, offs, prev, saved_regs_size; CHECK_ERROR(); CHECK(check_sljit_emit_return(compiler, op, src, srcw)); @@ -1243,9 +1243,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi /* Operators */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { - sljit_ins inv_bits = (op & SLJIT_INT_OP) ? (1 << 31) : 0; + sljit_ins inv_bits = (op & SLJIT_I32_OP) ? (1 << 31) : 0; CHECK_ERROR(); CHECK(check_sljit_emit_op0(compiler, op)); @@ -1256,31 +1256,31 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler return push_inst(compiler, BRK); case SLJIT_NOP: return push_inst(compiler, NOP); - case SLJIT_LUMUL: - case SLJIT_LSMUL: + case SLJIT_LMUL_UW: + case SLJIT_LMUL_SW: FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0))); FAIL_IF(push_inst(compiler, MADD | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO))); - return push_inst(compiler, (op == SLJIT_LUMUL ? UMULH : SMULH) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1)); - case SLJIT_UDIVMOD: - case SLJIT_SDIVMOD: + return push_inst(compiler, (op == SLJIT_LMUL_UW ? UMULH : SMULH) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1)); + case SLJIT_DIVMOD_UW: + case SLJIT_DIVMOD_SW: FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0))); - FAIL_IF(push_inst(compiler, ((op == SLJIT_UDIVMOD ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1))); + FAIL_IF(push_inst(compiler, ((op == SLJIT_DIVMOD_UW ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1))); FAIL_IF(push_inst(compiler, (MADD ^ inv_bits) | RD(SLJIT_R1) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO))); return push_inst(compiler, (SUB ^ inv_bits) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1)); - case SLJIT_UDIVI: - case SLJIT_SDIVI: - return push_inst(compiler, ((op == SLJIT_UDIVI ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)); + case SLJIT_DIV_UW: + case SLJIT_DIV_SW: + return push_inst(compiler, ((op == SLJIT_DIV_UW ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)); } return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r, flags, mem_flags; - sljit_si op_flags = GET_ALL_FLAGS(op); + sljit_s32 dst_r, flags, mem_flags; + sljit_s32 op_flags = GET_ALL_FLAGS(op); CHECK_ERROR(); CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); @@ -1299,69 +1299,69 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler case SLJIT_MOV_P: flags = WORD_SIZE; break; - case SLJIT_MOV_UB: + case SLJIT_MOV_U8: flags = BYTE_SIZE; if (src & SLJIT_IMM) - srcw = (sljit_ub)srcw; + srcw = (sljit_u8)srcw; break; - case SLJIT_MOV_SB: + case SLJIT_MOV_S8: flags = BYTE_SIZE | SIGNED; if (src & SLJIT_IMM) - srcw = (sljit_sb)srcw; + srcw = (sljit_s8)srcw; break; - case SLJIT_MOV_UH: + case SLJIT_MOV_U16: flags = HALF_SIZE; if (src & SLJIT_IMM) - srcw = (sljit_uh)srcw; + srcw = (sljit_u16)srcw; break; - case SLJIT_MOV_SH: + case SLJIT_MOV_S16: flags = HALF_SIZE | SIGNED; if (src & SLJIT_IMM) - srcw = (sljit_sh)srcw; + srcw = (sljit_s16)srcw; break; - case SLJIT_MOV_UI: + case SLJIT_MOV_U32: flags = INT_SIZE; if (src & SLJIT_IMM) - srcw = (sljit_ui)srcw; + srcw = (sljit_u32)srcw; break; - case SLJIT_MOV_SI: + case SLJIT_MOV_S32: flags = INT_SIZE | SIGNED; if (src & SLJIT_IMM) - srcw = (sljit_si)srcw; + srcw = (sljit_s32)srcw; break; case SLJIT_MOVU: case SLJIT_MOVU_P: flags = WORD_SIZE | UPDATE; break; - case SLJIT_MOVU_UB: + case SLJIT_MOVU_U8: flags = BYTE_SIZE | UPDATE; if (src & SLJIT_IMM) - srcw = (sljit_ub)srcw; + srcw = (sljit_u8)srcw; break; - case SLJIT_MOVU_SB: + case SLJIT_MOVU_S8: flags = BYTE_SIZE | SIGNED | UPDATE; if (src & SLJIT_IMM) - srcw = (sljit_sb)srcw; + srcw = (sljit_s8)srcw; break; - case SLJIT_MOVU_UH: + case SLJIT_MOVU_U16: flags = HALF_SIZE | UPDATE; if (src & SLJIT_IMM) - srcw = (sljit_uh)srcw; + srcw = (sljit_u16)srcw; break; - case SLJIT_MOVU_SH: + case SLJIT_MOVU_S16: flags = HALF_SIZE | SIGNED | UPDATE; if (src & SLJIT_IMM) - srcw = (sljit_sh)srcw; + srcw = (sljit_s16)srcw; break; - case SLJIT_MOVU_UI: + case SLJIT_MOVU_U32: flags = INT_SIZE | UPDATE; if (src & SLJIT_IMM) - srcw = (sljit_ui)srcw; + srcw = (sljit_u32)srcw; break; - case SLJIT_MOVU_SI: + case SLJIT_MOVU_S32: flags = INT_SIZE | SIGNED | UPDATE; if (src & SLJIT_IMM) - srcw = (sljit_si)srcw; + srcw = (sljit_s32)srcw; break; default: SLJIT_ASSERT_STOP(); @@ -1378,7 +1378,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler FAIL_IF(getput_arg(compiler, flags, dst_r, src, srcw, dst, dstw)); } else { if (dst_r != TMP_REG1) - return emit_op_imm(compiler, op | ((op_flags & SLJIT_INT_OP) ? INT_OP : 0), dst_r, TMP_REG1, src); + return emit_op_imm(compiler, op | ((op_flags & SLJIT_I32_OP) ? INT_OP : 0), dst_r, TMP_REG1, src); dst_r = src; } @@ -1393,7 +1393,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler flags = GET_FLAGS(op_flags) ? SET_FLAGS : 0; mem_flags = WORD_SIZE; - if (op_flags & SLJIT_INT_OP) { + if (op_flags & SLJIT_I32_OP) { flags |= INT_OP; mem_flags = INT_SIZE; } @@ -1411,8 +1411,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler if (src & SLJIT_IMM) { flags |= ARG2_IMM; - if (op_flags & SLJIT_INT_OP) - srcw = (sljit_si)srcw; + if (op_flags & SLJIT_I32_OP) + srcw = (sljit_s32)srcw; } else srcw = src; @@ -1427,12 +1427,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si dst_r, flags, mem_flags; + sljit_s32 dst_r, flags, mem_flags; CHECK_ERROR(); CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -1446,7 +1446,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; flags = GET_FLAGS(op) ? SET_FLAGS : 0; mem_flags = WORD_SIZE; - if (op & SLJIT_INT_OP) { + if (op & SLJIT_I32_OP) { flags |= INT_OP; mem_flags = INT_SIZE; } @@ -1512,20 +1512,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_register_index(reg)); return reg_map[reg]; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); return reg; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_s32 size) { CHECK_ERROR(); CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); @@ -1537,7 +1537,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co /* Floating point operators */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void) { #ifdef SLJIT_IS_FPU_AVAILABLE return SLJIT_IS_FPU_AVAILABLE; @@ -1547,11 +1547,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) #endif } -static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { - sljit_ui shift = MEM_SIZE_SHIFT(flags); + sljit_u32 shift = MEM_SIZE_SHIFT(flags); sljit_ins ins_bits = (shift << 30); - sljit_si other_r; + sljit_s32 other_r; sljit_sw diff; SLJIT_ASSERT(arg & SLJIT_MEM); @@ -1600,45 +1600,45 @@ static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sl return push_inst(compiler, STR_FI | ins_bits | VT(reg) | RN(TMP_REG3)); } -static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; - sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0; + sljit_s32 dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; + sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0; - if (GET_OPCODE(op) == SLJIT_CONVI_FROMD) + if (GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64) inv_bits |= (1 << 31); if (src & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE, TMP_FREG1, src, srcw); + emit_fop_mem(compiler, (op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE, TMP_FREG1, src, srcw); src = TMP_FREG1; } FAIL_IF(push_inst(compiler, (FCVTZS ^ inv_bits) | RD(dst_r) | VN(src))); if (dst_r == TMP_REG1 && dst != SLJIT_UNUSED) - return emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONVI_FROMD) ? INT_SIZE : WORD_SIZE) | STORE, TMP_REG1, dst, dstw); + return emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64) ? INT_SIZE : WORD_SIZE) | STORE, TMP_REG1, dst, dstw); return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0; + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0; - if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) inv_bits |= (1 << 31); if (src & SLJIT_MEM) { - emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONVD_FROMI) ? INT_SIZE : WORD_SIZE), TMP_REG1, src, srcw); + emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) ? INT_SIZE : WORD_SIZE), TMP_REG1, src, srcw); src = TMP_REG1; } else if (src & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) - srcw = (sljit_si)srcw; + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) + srcw = (sljit_s32)srcw; #endif FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); src = TMP_REG1; @@ -1647,16 +1647,16 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler * FAIL_IF(push_inst(compiler, (SCVTF ^ inv_bits) | VD(dst_r) | RN(src))); if (dst & SLJIT_MEM) - return emit_fop_mem(compiler, ((op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE) | STORE, TMP_FREG1, dst, dstw); + return emit_fop_mem(compiler, ((op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE) | STORE, TMP_FREG1, dst, dstw); return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si mem_flags = (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE; - sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0; + sljit_s32 mem_flags = (op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE; + sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0; if (src1 & SLJIT_MEM) { emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w); @@ -1671,11 +1671,11 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler return push_inst(compiler, (FCMP ^ inv_bits) | VN(src1) | VM(src2)); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r, mem_flags = (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE; + sljit_s32 dst_r, mem_flags = (op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE; sljit_ins inv_bits; CHECK_ERROR(); @@ -1685,16 +1685,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile SLJIT_COMPILE_ASSERT((INT_SIZE ^ 0x100) == WORD_SIZE, must_be_one_bit_difference); SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); - inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0; + inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0; dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; if (src & SLJIT_MEM) { - emit_fop_mem(compiler, (GET_OPCODE(op) == SLJIT_CONVD_FROMS) ? (mem_flags ^ 0x100) : mem_flags, dst_r, src, srcw); + emit_fop_mem(compiler, (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) ? (mem_flags ^ 0x100) : mem_flags, dst_r, src, srcw); src = dst_r; } switch (GET_OPCODE(op)) { - case SLJIT_DMOV: + case SLJIT_MOV_F64: if (src != dst_r) { if (dst_r != TMP_FREG1) FAIL_IF(push_inst(compiler, (FMOV ^ inv_bits) | VD(dst_r) | VN(src))); @@ -1702,14 +1702,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile dst_r = src; } break; - case SLJIT_DNEG: + case SLJIT_NEG_F64: FAIL_IF(push_inst(compiler, (FNEG ^ inv_bits) | VD(dst_r) | VN(src))); break; - case SLJIT_DABS: + case SLJIT_ABS_F64: FAIL_IF(push_inst(compiler, (FABS ^ inv_bits) | VD(dst_r) | VN(src))); break; - case SLJIT_CONVD_FROMS: - FAIL_IF(push_inst(compiler, FCVT | ((op & SLJIT_SINGLE_OP) ? (1 << 22) : (1 << 15)) | VD(dst_r) | VN(src))); + case SLJIT_CONV_F64_FROM_F32: + FAIL_IF(push_inst(compiler, FCVT | ((op & SLJIT_F32_OP) ? (1 << 22) : (1 << 15)) | VD(dst_r) | VN(src))); break; } @@ -1718,13 +1718,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si dst_r, mem_flags = (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE; - sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0; + sljit_s32 dst_r, mem_flags = (op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE; + sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0; CHECK_ERROR(); CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -1746,16 +1746,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile } switch (GET_OPCODE(op)) { - case SLJIT_DADD: + case SLJIT_ADD_F64: FAIL_IF(push_inst(compiler, (FADD ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); break; - case SLJIT_DSUB: + case SLJIT_SUB_F64: FAIL_IF(push_inst(compiler, (FSUB ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); break; - case SLJIT_DMUL: + case SLJIT_MUL_F64: FAIL_IF(push_inst(compiler, (FMUL ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); break; - case SLJIT_DDIV: + case SLJIT_DIV_F64: FAIL_IF(push_inst(compiler, (FDIV ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); break; } @@ -1769,7 +1769,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile /* Other instructions */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); @@ -1786,7 +1786,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_LR, dst, dstw); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); @@ -1806,33 +1806,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * /* Conditional instructions */ /* --------------------------------------------------------------------- */ -static sljit_uw get_cc(sljit_si type) +static sljit_uw get_cc(sljit_s32 type) { switch (type) { case SLJIT_EQUAL: case SLJIT_MUL_NOT_OVERFLOW: - case SLJIT_D_EQUAL: + case SLJIT_EQUAL_F64: return 0x1; case SLJIT_NOT_EQUAL: case SLJIT_MUL_OVERFLOW: - case SLJIT_D_NOT_EQUAL: + case SLJIT_NOT_EQUAL_F64: return 0x0; case SLJIT_LESS: - case SLJIT_D_LESS: + case SLJIT_LESS_F64: return 0x2; case SLJIT_GREATER_EQUAL: - case SLJIT_D_GREATER_EQUAL: + case SLJIT_GREATER_EQUAL_F64: return 0x3; case SLJIT_GREATER: - case SLJIT_D_GREATER: + case SLJIT_GREATER_F64: return 0x9; case SLJIT_LESS_EQUAL: - case SLJIT_D_LESS_EQUAL: + case SLJIT_LESS_EQUAL_F64: return 0x8; case SLJIT_SIG_LESS: @@ -1848,11 +1848,11 @@ static sljit_uw get_cc(sljit_si type) return 0xc; case SLJIT_OVERFLOW: - case SLJIT_D_UNORDERED: + case SLJIT_UNORDERED_F64: return 0x7; case SLJIT_NOT_OVERFLOW: - case SLJIT_D_ORDERED: + case SLJIT_ORDERED_F64: return 0x6; default: @@ -1877,7 +1877,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi return label; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { struct sljit_jump *jump; @@ -1903,11 +1903,11 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile return jump; } -static SLJIT_INLINE struct sljit_jump* emit_cmp_to0(struct sljit_compiler *compiler, sljit_si type, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE struct sljit_jump* emit_cmp_to0(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 src, sljit_sw srcw) { struct sljit_jump *jump; - sljit_ins inv_bits = (type & SLJIT_INT_OP) ? (1 << 31) : 0; + sljit_ins inv_bits = (type & SLJIT_I32_OP) ? (1 << 31) : 0; SLJIT_ASSERT((type & 0xff) == SLJIT_EQUAL || (type & 0xff) == SLJIT_NOT_EQUAL); ADJUST_LOCAL_OFFSET(src, srcw); @@ -1937,7 +1937,7 @@ static SLJIT_INLINE struct sljit_jump* emit_cmp_to0(struct sljit_compiler *compi return jump; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) { struct sljit_jump *jump; @@ -1964,12 +1964,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil return push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG1)); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw, + sljit_s32 type) { - sljit_si dst_r, flags, mem_flags; + sljit_s32 dst_r, flags, mem_flags; sljit_ins cc; CHECK_ERROR(); @@ -1994,7 +1994,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com compiler->cache_argw = 0; flags = GET_FLAGS(op) ? SET_FLAGS : 0; mem_flags = WORD_SIZE; - if (op & SLJIT_INT_OP) { + if (op & SLJIT_I32_OP) { flags |= INT_OP; mem_flags = INT_SIZE; } @@ -2014,10 +2014,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com return emit_op_mem2(compiler, mem_flags | STORE, TMP_REG1, dst, dstw, 0, 0); } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; - sljit_si dst_r; + sljit_s32 dst_r; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); diff --git a/pcre2-10.21/src/sljit/sljitNativeARM_T2_32.c b/pcre2-10.22/src/sljit/sljitNativeARM_T2_32.c similarity index 85% rename from pcre2-10.21/src/sljit/sljitNativeARM_T2_32.c rename to pcre2-10.22/src/sljit/sljitNativeARM_T2_32.c index f9803f5d4..1ed44a813 100644 --- a/pcre2-10.21/src/sljit/sljitNativeARM_T2_32.c +++ b/pcre2-10.22/src/sljit/sljitNativeARM_T2_32.c @@ -24,13 +24,13 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) { return "ARM-Thumb2" SLJIT_CPUINFO; } /* Length of an instruction word. */ -typedef sljit_ui sljit_ins; +typedef sljit_u32 sljit_ins; /* Last register + 1. */ #define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) @@ -42,7 +42,7 @@ typedef sljit_ui sljit_ins; #define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) /* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */ -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { +static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { 0, 0, 1, 2, 12, 11, 10, 9, 8, 7, 6, 5, 13, 3, 4, 14, 15 }; @@ -181,21 +181,21 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { #define VSTR_F32 0xed000a00 #define VSUB_F32 0xee300a40 -static sljit_si push_inst16(struct sljit_compiler *compiler, sljit_ins inst) +static sljit_s32 push_inst16(struct sljit_compiler *compiler, sljit_ins inst) { - sljit_uh *ptr; + sljit_u16 *ptr; SLJIT_ASSERT(!(inst & 0xffff0000)); - ptr = (sljit_uh*)ensure_buf(compiler, sizeof(sljit_uh)); + ptr = (sljit_u16*)ensure_buf(compiler, sizeof(sljit_u16)); FAIL_IF(!ptr); *ptr = inst; compiler->size++; return SLJIT_SUCCESS; } -static sljit_si push_inst32(struct sljit_compiler *compiler, sljit_ins inst) +static sljit_s32 push_inst32(struct sljit_compiler *compiler, sljit_ins inst) { - sljit_uh *ptr = (sljit_uh*)ensure_buf(compiler, sizeof(sljit_ins)); + sljit_u16 *ptr = (sljit_u16*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); *ptr++ = inst >> 16; *ptr = inst; @@ -203,7 +203,7 @@ static sljit_si push_inst32(struct sljit_compiler *compiler, sljit_ins inst) return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_imm32_const(struct sljit_compiler *compiler, sljit_si dst, sljit_uw imm) +static SLJIT_INLINE sljit_s32 emit_imm32_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_uw imm) { FAIL_IF(push_inst32(compiler, MOVW | RD4(dst) | COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff))); @@ -211,9 +211,9 @@ static SLJIT_INLINE sljit_si emit_imm32_const(struct sljit_compiler *compiler, s COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16)); } -static SLJIT_INLINE void modify_imm32_const(sljit_uh *inst, sljit_uw new_imm) +static SLJIT_INLINE void modify_imm32_const(sljit_u16 *inst, sljit_uw new_imm) { - sljit_si dst = inst[1] & 0x0f00; + sljit_s32 dst = inst[1] & 0x0f00; SLJIT_ASSERT(((inst[0] & 0xfbf0) == (MOVW >> 16)) && ((inst[2] & 0xfbf0) == (MOVT >> 16)) && dst == (inst[3] & 0x0f00)); inst[0] = (MOVW >> 16) | COPY_BITS(new_imm, 12, 0, 4) | COPY_BITS(new_imm, 11, 10, 1); inst[1] = dst | COPY_BITS(new_imm, 8, 12, 3) | (new_imm & 0xff); @@ -221,7 +221,7 @@ static SLJIT_INLINE void modify_imm32_const(sljit_uh *inst, sljit_uw new_imm) inst[3] = dst | COPY_BITS(new_imm, 8 + 16, 12, 3) | ((new_imm & 0xff0000) >> 16); } -static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uh *code_ptr, sljit_uh *code) +static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_u16 *code_ptr, sljit_u16 *code) { sljit_sw diff; @@ -278,13 +278,13 @@ static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uh static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump) { - sljit_si type = (jump->flags >> 4) & 0xf; + sljit_s32 type = (jump->flags >> 4) & 0xf; sljit_sw diff; - sljit_uh *jump_inst; - sljit_si s, j1, j2; + sljit_u16 *jump_inst; + sljit_s32 s, j1, j2; if (SLJIT_UNLIKELY(type == 0)) { - modify_imm32_const((sljit_uh*)jump->addr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target); + modify_imm32_const((sljit_u16*)jump->addr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target); return; } @@ -294,7 +294,7 @@ static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump) } else diff = ((sljit_sw)(jump->u.label->addr) - (sljit_sw)(jump->addr + 4)) >> 1; - jump_inst = (sljit_uh*)jump->addr; + jump_inst = (sljit_u16*)jump->addr; switch (type) { case 1: @@ -342,10 +342,10 @@ static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump) SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) { struct sljit_memory_fragment *buf; - sljit_uh *code; - sljit_uh *code_ptr; - sljit_uh *buf_ptr; - sljit_uh *buf_end; + sljit_u16 *code; + sljit_u16 *code_ptr; + sljit_u16 *buf_ptr; + sljit_u16 *buf_end; sljit_uw half_count; struct sljit_label *label; @@ -356,7 +356,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil CHECK_PTR(check_sljit_generate_code(compiler)); reverse_buf(compiler); - code = (sljit_uh*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_uh)); + code = (sljit_u16*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_u16)); PTR_FAIL_WITH_EXEC_IF(code); buf = compiler->buf; @@ -367,7 +367,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil const_ = compiler->consts; do { - buf_ptr = (sljit_uh*)buf->memory; + buf_ptr = (sljit_u16*)buf->memory; buf_end = buf_ptr + (buf->used_size >> 1); do { *code_ptr = *buf_ptr++; @@ -414,7 +414,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } compiler->error = SLJIT_ERR_COMPILED; - compiler->executable_size = (code_ptr - code) * sizeof(sljit_uh); + compiler->executable_size = (code_ptr - code) * sizeof(sljit_u16); SLJIT_CACHE_FLUSH(code, code_ptr); /* Set thumb mode flag. */ return (void*)((sljit_uw)code | 0x1); @@ -428,7 +428,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil static sljit_uw get_imm(sljit_uw imm) { /* Thumb immediate form. */ - sljit_si counter; + sljit_s32 counter; if (imm <= 0xff) return imm; @@ -474,7 +474,7 @@ static sljit_uw get_imm(sljit_uw imm) return ((imm >> 24) & 0x7f) | COPY_BITS(counter, 4, 26, 1) | COPY_BITS(counter, 1, 12, 3) | COPY_BITS(counter, 0, 7, 1); } -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sljit_uw imm) +static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst, sljit_uw imm) { sljit_uw tmp; @@ -508,12 +508,12 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sl #define SLOW_SRC1 0x0800000 #define SLOW_SRC2 0x1000000 -static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, sljit_si dst, sljit_uw arg1, sljit_uw arg2) +static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 dst, sljit_uw arg1, sljit_uw arg2) { /* dst must be register, TMP_REG1 arg1 must be register, TMP_REG1, imm arg2 must be register, TMP_REG2, imm */ - sljit_si reg; + sljit_s32 reg; sljit_uw imm, nimm; if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) { @@ -677,37 +677,37 @@ static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, slj /* Both arguments are registers. */ switch (flags & 0xffff) { case SLJIT_MOV: - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: + case SLJIT_MOV_U32: + case SLJIT_MOV_S32: case SLJIT_MOV_P: case SLJIT_MOVU: - case SLJIT_MOVU_UI: - case SLJIT_MOVU_SI: + case SLJIT_MOVU_U32: + case SLJIT_MOVU_S32: case SLJIT_MOVU_P: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if (dst == arg2) return SLJIT_SUCCESS; return push_inst16(compiler, MOV | SET_REGS44(dst, arg2)); - case SLJIT_MOV_UB: - case SLJIT_MOVU_UB: + case SLJIT_MOV_U8: + case SLJIT_MOVU_U8: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if (IS_2_LO_REGS(dst, arg2)) return push_inst16(compiler, UXTB | RD3(dst) | RN3(arg2)); return push_inst32(compiler, UXTB_W | RD4(dst) | RM4(arg2)); - case SLJIT_MOV_SB: - case SLJIT_MOVU_SB: + case SLJIT_MOV_S8: + case SLJIT_MOVU_S8: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if (IS_2_LO_REGS(dst, arg2)) return push_inst16(compiler, SXTB | RD3(dst) | RN3(arg2)); return push_inst32(compiler, SXTB_W | RD4(dst) | RM4(arg2)); - case SLJIT_MOV_UH: - case SLJIT_MOVU_UH: + case SLJIT_MOV_U16: + case SLJIT_MOVU_U16: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if (IS_2_LO_REGS(dst, arg2)) return push_inst16(compiler, UXTH | RD3(dst) | RN3(arg2)); return push_inst32(compiler, UXTH_W | RD4(dst) | RM4(arg2)); - case SLJIT_MOV_SH: - case SLJIT_MOVU_SH: + case SLJIT_MOV_S16: + case SLJIT_MOVU_S16: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if (IS_2_LO_REGS(dst, arg2)) return push_inst16(compiler, SXTH | RD3(dst) | RN3(arg2)); @@ -813,7 +813,7 @@ static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, slj s = store */ -static SLJIT_CONST sljit_ins sljit_mem16[12] = { +static const sljit_ins sljit_mem16[12] = { /* w u l */ 0x5800 /* ldr */, /* w u s */ 0x5000 /* str */, /* w s l */ 0x5800 /* ldr */, @@ -830,7 +830,7 @@ static SLJIT_CONST sljit_ins sljit_mem16[12] = { /* h s s */ 0x5200 /* strh */, }; -static SLJIT_CONST sljit_ins sljit_mem16_imm5[12] = { +static const sljit_ins sljit_mem16_imm5[12] = { /* w u l */ 0x6800 /* ldr imm5 */, /* w u s */ 0x6000 /* str imm5 */, /* w s l */ 0x6800 /* ldr imm5 */, @@ -849,7 +849,7 @@ static SLJIT_CONST sljit_ins sljit_mem16_imm5[12] = { #define MEM_IMM8 0xc00 #define MEM_IMM12 0x800000 -static SLJIT_CONST sljit_ins sljit_mem32[12] = { +static const sljit_ins sljit_mem32[12] = { /* w u l */ 0xf8500000 /* ldr.w */, /* w u s */ 0xf8400000 /* str.w */, /* w s l */ 0xf8500000 /* ldr.w */, @@ -867,7 +867,7 @@ static SLJIT_CONST sljit_ins sljit_mem32[12] = { }; /* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */ -static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sljit_si reg, sljit_sw value) +static sljit_s32 emit_set_delta(struct sljit_compiler *compiler, sljit_s32 dst, sljit_s32 reg, sljit_sw value) { if (value >= 0) { if (value <= 0xfff) @@ -888,9 +888,9 @@ static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sl } /* Can perform an operation using at most 1 instruction. */ -static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { - sljit_si other_r, shift; + sljit_s32 other_r, shift; SLJIT_ASSERT(arg & SLJIT_MEM); @@ -975,7 +975,7 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, /* see getput_arg below. Note: can_cache is called only for binary operators. Those operators always uses word arguments without write back. */ -static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { sljit_sw diff; if ((arg & OFFS_REG_MASK) || !(next_arg & SLJIT_MEM)) @@ -999,10 +999,10 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_ } /* Emit the necessary instructions. See can_cache above. */ -static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, - sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, + sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { - sljit_si tmp_r, other_r; + sljit_s32 tmp_r, other_r; sljit_sw diff; SLJIT_ASSERT(arg & SLJIT_MEM); @@ -1107,7 +1107,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | 0); } -static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { if (getput_arg_fast(compiler, flags, reg, arg, argw)) return compiler->error; @@ -1116,7 +1116,7 @@ static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_ return getput_arg(compiler, flags, reg, arg, argw, 0, 0); } -static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w) { if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) return compiler->error; @@ -1127,11 +1127,11 @@ static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit /* Entry, exit */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_si size, i, tmp; + sljit_s32 size, i, tmp; sljit_ins push; CHECK_ERROR(); @@ -1172,11 +1172,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_si size; + sljit_s32 size; CHECK_ERROR(); CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -1187,9 +1187,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { - sljit_si i, tmp; + sljit_s32 i, tmp; sljit_ins pop; CHECK_ERROR(); @@ -1237,7 +1237,7 @@ extern int __aeabi_idivmod(int numerator, int denominator); } #endif -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { sljit_sw saved_reg_list[3]; sljit_sw saved_reg_count; @@ -1251,18 +1251,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler return push_inst16(compiler, BKPT); case SLJIT_NOP: return push_inst16(compiler, NOP); - case SLJIT_LUMUL: - case SLJIT_LSMUL: - return push_inst32(compiler, (op == SLJIT_LUMUL ? UMULL : SMULL) + case SLJIT_LMUL_UW: + case SLJIT_LMUL_SW: + return push_inst32(compiler, (op == SLJIT_LMUL_UW ? UMULL : SMULL) | (reg_map[SLJIT_R1] << 8) | (reg_map[SLJIT_R0] << 12) | (reg_map[SLJIT_R0] << 16) | reg_map[SLJIT_R1]); - case SLJIT_UDIVMOD: - case SLJIT_SDIVMOD: - case SLJIT_UDIVI: - case SLJIT_SDIVI: - SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments); + case SLJIT_DIVMOD_UW: + case SLJIT_DIVMOD_SW: + case SLJIT_DIV_UW: + case SLJIT_DIV_SW: + SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments); SLJIT_COMPILE_ASSERT(reg_map[2] == 1 && reg_map[3] == 2 && reg_map[4] == 12, bad_register_mapping); saved_reg_count = 0; @@ -1270,7 +1270,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler saved_reg_list[saved_reg_count++] = 12; if (compiler->scratches >= 3) saved_reg_list[saved_reg_count++] = 2; - if (op >= SLJIT_UDIVI) + if (op >= SLJIT_DIV_UW) saved_reg_list[saved_reg_count++] = 1; if (saved_reg_count > 0) { @@ -1288,7 +1288,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler #if defined(__GNUC__) FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM, - ((op | 0x2) == SLJIT_UDIVI ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod)))); + ((op | 0x2) == SLJIT_DIV_UW ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod)))); #else #error "Software divmod functions are needed" #endif @@ -1311,12 +1311,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r, flags; - sljit_si op_flags = GET_ALL_FLAGS(op); + sljit_s32 dst_r, flags; + sljit_s32 op_flags = GET_ALL_FLAGS(op); CHECK_ERROR(); CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); @@ -1332,56 +1332,56 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) { switch (op) { case SLJIT_MOV: - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: + case SLJIT_MOV_U32: + case SLJIT_MOV_S32: case SLJIT_MOV_P: flags = WORD_SIZE; break; - case SLJIT_MOV_UB: + case SLJIT_MOV_U8: flags = BYTE_SIZE; if (src & SLJIT_IMM) - srcw = (sljit_ub)srcw; + srcw = (sljit_u8)srcw; break; - case SLJIT_MOV_SB: + case SLJIT_MOV_S8: flags = BYTE_SIZE | SIGNED; if (src & SLJIT_IMM) - srcw = (sljit_sb)srcw; + srcw = (sljit_s8)srcw; break; - case SLJIT_MOV_UH: + case SLJIT_MOV_U16: flags = HALF_SIZE; if (src & SLJIT_IMM) - srcw = (sljit_uh)srcw; + srcw = (sljit_u16)srcw; break; - case SLJIT_MOV_SH: + case SLJIT_MOV_S16: flags = HALF_SIZE | SIGNED; if (src & SLJIT_IMM) - srcw = (sljit_sh)srcw; + srcw = (sljit_s16)srcw; break; case SLJIT_MOVU: - case SLJIT_MOVU_UI: - case SLJIT_MOVU_SI: + case SLJIT_MOVU_U32: + case SLJIT_MOVU_S32: case SLJIT_MOVU_P: flags = WORD_SIZE | UPDATE; break; - case SLJIT_MOVU_UB: + case SLJIT_MOVU_U8: flags = BYTE_SIZE | UPDATE; if (src & SLJIT_IMM) - srcw = (sljit_ub)srcw; + srcw = (sljit_u8)srcw; break; - case SLJIT_MOVU_SB: + case SLJIT_MOVU_S8: flags = BYTE_SIZE | SIGNED | UPDATE; if (src & SLJIT_IMM) - srcw = (sljit_sb)srcw; + srcw = (sljit_s8)srcw; break; - case SLJIT_MOVU_UH: + case SLJIT_MOVU_U16: flags = HALF_SIZE | UPDATE; if (src & SLJIT_IMM) - srcw = (sljit_uh)srcw; + srcw = (sljit_u16)srcw; break; - case SLJIT_MOVU_SH: + case SLJIT_MOVU_S16: flags = HALF_SIZE | SIGNED | UPDATE; if (src & SLJIT_IMM) - srcw = (sljit_sh)srcw; + srcw = (sljit_s16)srcw; break; default: SLJIT_ASSERT_STOP(); @@ -1444,12 +1444,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si dst_r, flags; + sljit_s32 dst_r, flags; CHECK_ERROR(); CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -1523,26 +1523,26 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_register_index(reg)); return reg_map[reg]; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); return reg << 1; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_s32 size) { CHECK_ERROR(); CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); if (size == 2) - return push_inst16(compiler, *(sljit_uh*)instruction); + return push_inst16(compiler, *(sljit_u16*)instruction); return push_inst32(compiler, *(sljit_ins*)instruction); } @@ -1550,7 +1550,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co /* Floating point operators */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void) { #ifdef SLJIT_IS_FPU_AVAILABLE return SLJIT_IS_FPU_AVAILABLE; @@ -1562,11 +1562,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) #define FPU_LOAD (1 << 20) -static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { sljit_sw tmp; sljit_uw imm; - sljit_sw inst = VSTR_F32 | (flags & (SLJIT_SINGLE_OP | FPU_LOAD)); + sljit_sw inst = VSTR_F32 | (flags & (SLJIT_F32_OP | FPU_LOAD)); SLJIT_ASSERT(arg & SLJIT_MEM); @@ -1626,16 +1626,16 @@ static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sl return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg)); } -static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { if (src & SLJIT_MEM) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src, srcw)); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src, srcw)); src = TMP_FREG1; } - FAIL_IF(push_inst32(compiler, VCVT_S32_F32 | (op & SLJIT_SINGLE_OP) | DD4(TMP_FREG1) | DM4(src))); + FAIL_IF(push_inst32(compiler, VCVT_S32_F32 | (op & SLJIT_F32_OP) | DD4(TMP_FREG1) | DM4(src))); if (dst == SLJIT_UNUSED) return SLJIT_SUCCESS; @@ -1647,11 +1647,11 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler * return emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw); } -static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; if (FAST_IS_REG(src)) FAIL_IF(push_inst32(compiler, VMOV | RT4(src) | DN4(TMP_FREG1))); @@ -1664,85 +1664,85 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler * FAIL_IF(push_inst32(compiler, VMOV | RT4(TMP_REG1) | DN4(TMP_FREG1))); } - FAIL_IF(push_inst32(compiler, VCVT_F32_S32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(TMP_FREG1))); + FAIL_IF(push_inst32(compiler, VCVT_F32_S32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DM4(TMP_FREG1))); if (dst & SLJIT_MEM) - return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw); + return emit_fop_mem(compiler, (op & SLJIT_F32_OP), TMP_FREG1, dst, dstw); return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { if (src1 & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w); + emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src1, src1w); src1 = TMP_FREG1; } if (src2 & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w); + emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG2, src2, src2w); src2 = TMP_FREG2; } - FAIL_IF(push_inst32(compiler, VCMP_F32 | (op & SLJIT_SINGLE_OP) | DD4(src1) | DM4(src2))); + FAIL_IF(push_inst32(compiler, VCMP_F32 | (op & SLJIT_F32_OP) | DD4(src1) | DM4(src2))); return push_inst32(compiler, VMRS); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r; + sljit_s32 dst_r; CHECK_ERROR(); compiler->cache_arg = 0; compiler->cache_argw = 0; - if (GET_OPCODE(op) != SLJIT_CONVD_FROMS) - op ^= SLJIT_SINGLE_OP; + if (GET_OPCODE(op) != SLJIT_CONV_F64_FROM_F32) + op ^= SLJIT_F32_OP; - SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100), float_transfer_bit_error); + SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100), float_transfer_bit_error); SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; if (src & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, dst_r, src, srcw); + emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, dst_r, src, srcw); src = dst_r; } switch (GET_OPCODE(op)) { - case SLJIT_DMOV: + case SLJIT_MOV_F64: if (src != dst_r) { if (dst_r != TMP_FREG1) - FAIL_IF(push_inst32(compiler, VMOV_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src))); + FAIL_IF(push_inst32(compiler, VMOV_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DM4(src))); else dst_r = src; } break; - case SLJIT_DNEG: - FAIL_IF(push_inst32(compiler, VNEG_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src))); + case SLJIT_NEG_F64: + FAIL_IF(push_inst32(compiler, VNEG_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DM4(src))); break; - case SLJIT_DABS: - FAIL_IF(push_inst32(compiler, VABS_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src))); + case SLJIT_ABS_F64: + FAIL_IF(push_inst32(compiler, VABS_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DM4(src))); break; - case SLJIT_CONVD_FROMS: - FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src))); - op ^= SLJIT_SINGLE_OP; + case SLJIT_CONV_F64_FROM_F32: + FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DM4(src))); + op ^= SLJIT_F32_OP; break; } if (dst & SLJIT_MEM) - return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), dst_r, dst, dstw); + return emit_fop_mem(compiler, (op & SLJIT_F32_OP), dst_r, dst, dstw); return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si dst_r; + sljit_s32 dst_r; CHECK_ERROR(); CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -1752,36 +1752,36 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile compiler->cache_arg = 0; compiler->cache_argw = 0; - op ^= SLJIT_SINGLE_OP; + op ^= SLJIT_F32_OP; dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; if (src1 & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w); + emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src1, src1w); src1 = TMP_FREG1; } if (src2 & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w); + emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG2, src2, src2w); src2 = TMP_FREG2; } switch (GET_OPCODE(op)) { - case SLJIT_DADD: - FAIL_IF(push_inst32(compiler, VADD_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); + case SLJIT_ADD_F64: + FAIL_IF(push_inst32(compiler, VADD_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); break; - case SLJIT_DSUB: - FAIL_IF(push_inst32(compiler, VSUB_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); + case SLJIT_SUB_F64: + FAIL_IF(push_inst32(compiler, VSUB_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); break; - case SLJIT_DMUL: - FAIL_IF(push_inst32(compiler, VMUL_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); + case SLJIT_MUL_F64: + FAIL_IF(push_inst32(compiler, VMUL_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); break; - case SLJIT_DDIV: - FAIL_IF(push_inst32(compiler, VDIV_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); + case SLJIT_DIV_F64: + FAIL_IF(push_inst32(compiler, VDIV_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); break; } if (!(dst & SLJIT_MEM)) return SLJIT_SUCCESS; - return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw); + return emit_fop_mem(compiler, (op & SLJIT_F32_OP), TMP_FREG1, dst, dstw); } #undef FPU_LOAD @@ -1790,7 +1790,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile /* Other instructions */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); @@ -1813,7 +1813,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c return getput_arg(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, 0, 0); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); @@ -1840,33 +1840,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * /* Conditional instructions */ /* --------------------------------------------------------------------- */ -static sljit_uw get_cc(sljit_si type) +static sljit_uw get_cc(sljit_s32 type) { switch (type) { case SLJIT_EQUAL: case SLJIT_MUL_NOT_OVERFLOW: - case SLJIT_D_EQUAL: + case SLJIT_EQUAL_F64: return 0x0; case SLJIT_NOT_EQUAL: case SLJIT_MUL_OVERFLOW: - case SLJIT_D_NOT_EQUAL: + case SLJIT_NOT_EQUAL_F64: return 0x1; case SLJIT_LESS: - case SLJIT_D_LESS: + case SLJIT_LESS_F64: return 0x3; case SLJIT_GREATER_EQUAL: - case SLJIT_D_GREATER_EQUAL: + case SLJIT_GREATER_EQUAL_F64: return 0x2; case SLJIT_GREATER: - case SLJIT_D_GREATER: + case SLJIT_GREATER_F64: return 0x8; case SLJIT_LESS_EQUAL: - case SLJIT_D_LESS_EQUAL: + case SLJIT_LESS_EQUAL_F64: return 0x9; case SLJIT_SIG_LESS: @@ -1882,11 +1882,11 @@ static sljit_uw get_cc(sljit_si type) return 0xd; case SLJIT_OVERFLOW: - case SLJIT_D_UNORDERED: + case SLJIT_UNORDERED_F64: return 0x6; case SLJIT_NOT_OVERFLOW: - case SLJIT_D_ORDERED: + case SLJIT_ORDERED_F64: return 0x7; default: /* SLJIT_JUMP */ @@ -1911,7 +1911,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi return label; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { struct sljit_jump *jump; sljit_ins cc; @@ -1944,7 +1944,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile return jump; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) { struct sljit_jump *jump; @@ -1972,12 +1972,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(TMP_REG1)); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw, + sljit_s32 type) { - sljit_si dst_r, flags = GET_ALL_FLAGS(op); + sljit_s32 dst_r, flags = GET_ALL_FLAGS(op); sljit_ins cc, ins; CHECK_ERROR(); @@ -2054,10 +2054,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; - sljit_si dst_r; + sljit_s32 dst_r; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); @@ -2077,14 +2077,14 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) { - sljit_uh *inst = (sljit_uh*)addr; + sljit_u16 *inst = (sljit_u16*)addr; modify_imm32_const(inst, new_addr); SLJIT_CACHE_FLUSH(inst, inst + 4); } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) { - sljit_uh *inst = (sljit_uh*)addr; + sljit_u16 *inst = (sljit_u16*)addr; modify_imm32_const(inst, new_constant); SLJIT_CACHE_FLUSH(inst, inst + 4); } diff --git a/pcre2-10.21/src/sljit/sljitNativeMIPS_32.c b/pcre2-10.22/src/sljit/sljitNativeMIPS_32.c similarity index 96% rename from pcre2-10.21/src/sljit/sljitNativeMIPS_32.c rename to pcre2-10.22/src/sljit/sljitNativeMIPS_32.c index b2b60d7a4..5096e4f55 100644 --- a/pcre2-10.21/src/sljit/sljitNativeMIPS_32.c +++ b/pcre2-10.22/src/sljit/sljitNativeMIPS_32.c @@ -26,7 +26,7 @@ /* mips 32-bit arch dependent functions. */ -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm) +static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm) { if (!(imm & ~0xffff)) return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar); @@ -66,24 +66,24 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | D(dst), DR(dst))); \ } -static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_si src1, sljit_sw src2) +static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, + sljit_s32 dst, sljit_s32 src1, sljit_sw src2) { switch (GET_OPCODE(op)) { case SLJIT_MOV: - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: + case SLJIT_MOV_U32: + case SLJIT_MOV_S32: case SLJIT_MOV_P: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if (dst != src2) return push_inst(compiler, ADDU | S(src2) | TA(0) | D(dst), DR(dst)); return SLJIT_SUCCESS; - case SLJIT_MOV_UB: - case SLJIT_MOV_SB: + case SLJIT_MOV_U8: + case SLJIT_MOV_S8: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SB) { + if (op == SLJIT_MOV_S8) { #if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst)); #else @@ -97,11 +97,11 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj SLJIT_ASSERT_STOP(); return SLJIT_SUCCESS; - case SLJIT_MOV_UH: - case SLJIT_MOV_SH: + case SLJIT_MOV_U16: + case SLJIT_MOV_S16: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SH) { + if (op == SLJIT_MOV_S16) { #if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst)); #else @@ -341,7 +341,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value) +static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value) { FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 16), DR(dst))); return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst)); diff --git a/pcre2-10.21/src/sljit/sljitNativeMIPS_64.c b/pcre2-10.22/src/sljit/sljitNativeMIPS_64.c similarity index 95% rename from pcre2-10.21/src/sljit/sljitNativeMIPS_64.c rename to pcre2-10.22/src/sljit/sljitNativeMIPS_64.c index 185fb5768..c7ee8c9c2 100644 --- a/pcre2-10.21/src/sljit/sljitNativeMIPS_64.c +++ b/pcre2-10.22/src/sljit/sljitNativeMIPS_64.c @@ -26,11 +26,11 @@ /* mips 64-bit arch dependent functions. */ -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm) +static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm) { - sljit_si shift = 32; - sljit_si shift2; - sljit_si inv = 0; + sljit_s32 shift = 32; + sljit_s32 shift2; + sljit_s32 inv = 0; sljit_ins ins; sljit_uw uimm; @@ -119,7 +119,7 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, } #define SELECT_OP(a, b) \ - (!(op & SLJIT_INT_OP) ? a : b) + (!(op & SLJIT_I32_OP) ? a : b) #define EMIT_LOGICAL(op_imm, op_norm) \ if (flags & SRC2_IMM) { \ @@ -138,27 +138,27 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, #define EMIT_SHIFT(op_dimm, op_dimm32, op_imm, op_dv, op_v) \ if (flags & SRC2_IMM) { \ if (src2 >= 32) { \ - SLJIT_ASSERT(!(op & SLJIT_INT_OP)); \ + SLJIT_ASSERT(!(op & SLJIT_I32_OP)); \ ins = op_dimm32; \ src2 -= 32; \ } \ else \ - ins = (op & SLJIT_INT_OP) ? op_imm : op_dimm; \ + ins = (op & SLJIT_I32_OP) ? op_imm : op_dimm; \ if (op & SLJIT_SET_E) \ FAIL_IF(push_inst(compiler, ins | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \ if (CHECK_FLAGS(SLJIT_SET_E)) \ FAIL_IF(push_inst(compiler, ins | T(src1) | D(dst) | SH_IMM(src2), DR(dst))); \ } \ else { \ - ins = (op & SLJIT_INT_OP) ? op_v : op_dv; \ + ins = (op & SLJIT_I32_OP) ? op_v : op_dv; \ if (op & SLJIT_SET_E) \ FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \ if (CHECK_FLAGS(SLJIT_SET_E)) \ FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | D(dst), DR(dst))); \ } -static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_si src1, sljit_sw src2) +static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, + sljit_s32 dst, sljit_s32 src1, sljit_sw src2) { sljit_ins ins; @@ -170,11 +170,11 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(dst), DR(dst)); return SLJIT_SUCCESS; - case SLJIT_MOV_UB: - case SLJIT_MOV_SB: + case SLJIT_MOV_U8: + case SLJIT_MOV_S8: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SB) { + if (op == SLJIT_MOV_S8) { FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(24), DR(dst))); return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(24), DR(dst)); } @@ -184,11 +184,11 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj SLJIT_ASSERT_STOP(); return SLJIT_SUCCESS; - case SLJIT_MOV_UH: - case SLJIT_MOV_SH: + case SLJIT_MOV_U16: + case SLJIT_MOV_S16: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SH) { + if (op == SLJIT_MOV_S16) { FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(16), DR(dst))); return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(16), DR(dst)); } @@ -198,12 +198,12 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj SLJIT_ASSERT_STOP(); return SLJIT_SUCCESS; - case SLJIT_MOV_UI: - SLJIT_ASSERT(!(op & SLJIT_INT_OP)); + case SLJIT_MOV_U32: + SLJIT_ASSERT(!(op & SLJIT_I32_OP)); FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(0), DR(dst))); return push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst)); - case SLJIT_MOV_SI: + case SLJIT_MOV_S32: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); return push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(0), DR(dst)); @@ -231,7 +231,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1))); /* Check zero. */ FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(5), UNMOVABLE_INS)); - FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM((op & SLJIT_INT_OP) ? 32 : 64), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM((op & SLJIT_I32_OP) ? 32 : 64), UNMOVABLE_INS)); FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | T(dst) | IMM(-1), DR(dst))); /* Loop for searching the highest bit. */ FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(dst) | T(dst) | IMM(1), DR(dst))); @@ -392,7 +392,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj SLJIT_ASSERT(!(flags & SRC2_IMM)); if (!(op & SLJIT_SET_O)) { #if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) - if (op & SLJIT_INT_OP) + if (op & SLJIT_I32_OP) return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst)); FAIL_IF(push_inst(compiler, DMULT | S(src1) | T(src2), MOVABLE_INS)); return push_inst(compiler, MFLO | D(dst), DR(dst)); @@ -436,7 +436,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value) +static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value) { FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 48), DR(dst))); FAIL_IF(push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value >> 32), DR(dst))); diff --git a/pcre2-10.21/src/sljit/sljitNativeMIPS_common.c b/pcre2-10.22/src/sljit/sljitNativeMIPS_common.c similarity index 84% rename from pcre2-10.21/src/sljit/sljitNativeMIPS_common.c rename to pcre2-10.22/src/sljit/sljitNativeMIPS_common.c index cf3535f81..c2c251b1f 100644 --- a/pcre2-10.21/src/sljit/sljitNativeMIPS_common.c +++ b/pcre2-10.22/src/sljit/sljitNativeMIPS_common.c @@ -27,7 +27,7 @@ /* Latest MIPS architecture. */ /* Automatically detect SLJIT_MIPS_R1 */ -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) { #if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) @@ -42,7 +42,7 @@ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) /* Length of an instruction word Both for mips-32 and mips-64 */ -typedef sljit_ui sljit_ins; +typedef sljit_u32 sljit_ins; #define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) #define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) @@ -68,7 +68,7 @@ typedef sljit_ui sljit_ins; #define TMP_FREG1 (0) #define TMP_FREG2 ((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) << 1) -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { +static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { 0, 2, 5, 6, 7, 8, 9, 10, 11, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 3, 25, 4 }; @@ -201,7 +201,7 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { /* dest_reg is the absolute name of the register Useful for reordering instructions in the delay slot. */ -static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_si delay_slot) +static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 delay_slot) { SLJIT_ASSERT(delay_slot == MOVABLE_INS || delay_slot >= UNMOVABLE_INS || delay_slot == ((ins >> 11) & 0x1f) || delay_slot == ((ins >> 16) & 0x1f)); @@ -213,7 +213,7 @@ static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_ return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_ins invert_branch(sljit_si flags) +static SLJIT_INLINE sljit_ins invert_branch(sljit_s32 flags) { return (flags & IS_BIT26_COND) ? (1 << 26) : (1 << 16); } @@ -538,12 +538,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #include "sljitNativeMIPS_64.c" #endif -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { sljit_ins base; - sljit_si i, tmp, offs; + sljit_s32 i, tmp, offs; CHECK_ERROR(); CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -575,12 +575,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; for (i = SLJIT_S0; i >= tmp; i--) { - offs -= (sljit_si)(sizeof(sljit_sw)); + offs -= (sljit_s32)(sizeof(sljit_sw)); FAIL_IF(push_inst(compiler, STACK_STORE | base | T(i) | IMM(offs), MOVABLE_INS)); } for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { - offs -= (sljit_si)(sizeof(sljit_sw)); + offs -= (sljit_s32)(sizeof(sljit_sw)); FAIL_IF(push_inst(compiler, STACK_STORE | base | T(i) | IMM(offs), MOVABLE_INS)); } @@ -594,9 +594,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { CHECK_ERROR(); CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -611,9 +611,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { - sljit_si local_size, i, tmp, offs; + sljit_s32 local_size, i, tmp, offs; sljit_ins base; CHECK_ERROR(); @@ -631,19 +631,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi local_size = 0; } - FAIL_IF(push_inst(compiler, STACK_LOAD | base | TA(RETURN_ADDR_REG) | IMM(local_size - (sljit_si)sizeof(sljit_sw)), RETURN_ADDR_REG)); - offs = local_size - (sljit_si)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1); + FAIL_IF(push_inst(compiler, STACK_LOAD | base | TA(RETURN_ADDR_REG) | IMM(local_size - (sljit_s32)sizeof(sljit_sw)), RETURN_ADDR_REG)); + offs = local_size - (sljit_s32)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1); tmp = compiler->scratches; for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) { FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(i) | IMM(offs), DR(i))); - offs += (sljit_si)(sizeof(sljit_sw)); + offs += (sljit_s32)(sizeof(sljit_sw)); } tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG; for (i = tmp; i <= SLJIT_S0; i++) { FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(i) | IMM(offs), DR(i))); - offs += (sljit_si)(sizeof(sljit_sw)); + offs += (sljit_s32)(sizeof(sljit_sw)); } SLJIT_ASSERT(offs == local_size - (sljit_sw)(sizeof(sljit_sw))); @@ -668,7 +668,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi #define ARCH_32_64(a, b) b #endif -static SLJIT_CONST sljit_ins data_transfer_insts[16 + 4] = { +static const sljit_ins data_transfer_insts[16 + 4] = { /* u w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */), /* u w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */), /* u b s */ HI(40) /* sb */, @@ -698,7 +698,7 @@ static SLJIT_CONST sljit_ins data_transfer_insts[16 + 4] = { /* reg_ar is an absoulute register! */ /* Can perform an operation using at most 1 instruction. */ -static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw) +static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw) { SLJIT_ASSERT(arg & SLJIT_MEM); @@ -716,7 +716,7 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, /* See getput_arg below. Note: can_cache is called only for binary operators. Those operators always uses word arguments without write back. */ -static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); @@ -739,9 +739,9 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_ } /* Emit the necessary instructions. See can_cache above. */ -static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { - sljit_si tmp_ar, base, delay_slot; + sljit_s32 tmp_ar, base, delay_slot; SLJIT_ASSERT(arg & SLJIT_MEM); if (!(next_arg & SLJIT_MEM)) { @@ -878,7 +878,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot); } -static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw) +static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw) { if (getput_arg_fast(compiler, flags, reg_ar, arg, argw)) return compiler->error; @@ -887,26 +887,26 @@ static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_ return getput_arg(compiler, flags, reg_ar, arg, argw, 0, 0); } -static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w) { if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) return compiler->error; return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); } -static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { /* arg1 goes to TMP_REG1 or src reg arg2 goes to TMP_REG2, imm or src reg TMP_REG3 can be used for caching result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ - sljit_si dst_r = TMP_REG2; - sljit_si src1_r; + sljit_s32 dst_r = TMP_REG2; + sljit_s32 src1_r; sljit_sw src2_r = 0; - sljit_si sugg_src2_r = TMP_REG2; + sljit_s32 sugg_src2_r = TMP_REG2; if (!(flags & ALT_KEEP_CACHE)) { compiler->cache_arg = 0; @@ -914,7 +914,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f } if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32 && !(src2 & SLJIT_MEM)) return SLJIT_SUCCESS; if (GET_FLAGS(op)) flags |= UNUSED_DEST; @@ -922,7 +922,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f else if (FAST_IS_REG(dst)) { dst_r = dst; flags |= REG_DEST; - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) sugg_src2_r = dst_r; } else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, DR(TMP_REG1), dst, dstw)) @@ -976,7 +976,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f if (FAST_IS_REG(src2)) { src2_r = src2; flags |= REG2_SOURCE; - if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) dst_r = src2_r; } else if (src2 & SLJIT_IMM) { @@ -987,7 +987,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f } else { src2_r = 0; - if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) && (dst & SLJIT_MEM)) + if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) && (dst & SLJIT_MEM)) dst_r = 0; } } @@ -1029,10 +1029,10 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - sljit_si int_op = op & SLJIT_INT_OP; + sljit_s32 int_op = op & SLJIT_I32_OP; #endif CHECK_ERROR(); @@ -1044,20 +1044,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler return push_inst(compiler, BREAK, UNMOVABLE_INS); case SLJIT_NOP: return push_inst(compiler, NOP, UNMOVABLE_INS); - case SLJIT_LUMUL: - case SLJIT_LSMUL: + case SLJIT_LMUL_UW: + case SLJIT_LMUL_SW: #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - FAIL_IF(push_inst(compiler, (op == SLJIT_LUMUL ? DMULTU : DMULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULTU : DMULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); #else - FAIL_IF(push_inst(compiler, (op == SLJIT_LUMUL ? MULTU : MULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MULTU : MULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); #endif FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0))); return push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1)); - case SLJIT_UDIVMOD: - case SLJIT_SDIVMOD: - case SLJIT_UDIVI: - case SLJIT_SDIVI: - SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments); + case SLJIT_DIVMOD_UW: + case SLJIT_DIVMOD_SW: + case SLJIT_DIV_UW: + case SLJIT_DIV_SW: + SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments); #if !(defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); @@ -1065,28 +1065,28 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) if (int_op) - FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); else - FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); #else - FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); #endif FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0))); - return (op >= SLJIT_UDIVI) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1)); + return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1)); } return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) # define flags 0 #else - sljit_si flags = 0; + sljit_s32 flags = 0; #endif CHECK_ERROR(); @@ -1095,10 +1095,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler ADJUST_LOCAL_OFFSET(src, srcw); #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - if ((op & SLJIT_INT_OP) && GET_OPCODE(op) >= SLJIT_NOT) { + if ((op & SLJIT_I32_OP) && GET_OPCODE(op) >= SLJIT_NOT) { flags |= INT_DATA | SIGNED_DATA; if (src & SLJIT_IMM) - srcw = (sljit_si)srcw; + srcw = (sljit_s32)srcw; } #endif @@ -1107,61 +1107,61 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler case SLJIT_MOV_P: return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOV_UI: + case SLJIT_MOV_U32: #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - return emit_op(compiler, SLJIT_MOV_UI, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, SLJIT_MOV_U32, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); #else - return emit_op(compiler, SLJIT_MOV_UI, INT_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ui)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_U32, INT_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u32)srcw : srcw); #endif - case SLJIT_MOV_SI: + case SLJIT_MOV_S32: #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); #else - return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_si)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s32)srcw : srcw); #endif - case SLJIT_MOV_UB: - return emit_op(compiler, SLJIT_MOV_UB, BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + case SLJIT_MOV_U8: + return emit_op(compiler, SLJIT_MOV_U8, BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw); - case SLJIT_MOV_SB: - return emit_op(compiler, SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + case SLJIT_MOV_S8: + return emit_op(compiler, SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw); - case SLJIT_MOV_UH: - return emit_op(compiler, SLJIT_MOV_UH, HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + case SLJIT_MOV_U16: + return emit_op(compiler, SLJIT_MOV_U16, HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw); - case SLJIT_MOV_SH: - return emit_op(compiler, SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + case SLJIT_MOV_S16: + return emit_op(compiler, SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw); case SLJIT_MOVU: case SLJIT_MOVU_P: return emit_op(compiler, SLJIT_MOV, WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOVU_UI: + case SLJIT_MOVU_U32: #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - return emit_op(compiler, SLJIT_MOV_UI, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); #else - return emit_op(compiler, SLJIT_MOV_UI, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ui)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u32)srcw : srcw); #endif - case SLJIT_MOVU_SI: + case SLJIT_MOVU_S32: #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); #else - return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_si)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s32)srcw : srcw); #endif - case SLJIT_MOVU_UB: - return emit_op(compiler, SLJIT_MOV_UB, BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + case SLJIT_MOVU_U8: + return emit_op(compiler, SLJIT_MOV_U8, BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw); - case SLJIT_MOVU_SB: - return emit_op(compiler, SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + case SLJIT_MOVU_S8: + return emit_op(compiler, SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw); - case SLJIT_MOVU_UH: - return emit_op(compiler, SLJIT_MOV_UH, HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + case SLJIT_MOVU_U16: + return emit_op(compiler, SLJIT_MOV_U16, HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw); - case SLJIT_MOVU_SH: - return emit_op(compiler, SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + case SLJIT_MOVU_S16: + return emit_op(compiler, SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw); case SLJIT_NOT: return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw); @@ -1180,15 +1180,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler #endif } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) # define flags 0 #else - sljit_si flags = 0; + sljit_s32 flags = 0; #endif CHECK_ERROR(); @@ -1198,12 +1198,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler ADJUST_LOCAL_OFFSET(src2, src2w); #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - if (op & SLJIT_INT_OP) { + if (op & SLJIT_I32_OP) { flags |= INT_DATA | SIGNED_DATA; if (src1 & SLJIT_IMM) - src1w = (sljit_si)src1w; + src1w = (sljit_s32)src1w; if (src2 & SLJIT_IMM) - src2w = (sljit_si)src2w; + src2w = (sljit_s32)src2w; } #endif @@ -1232,7 +1232,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler src2w &= 0x1f; #else if (src2 & SLJIT_IMM) { - if (op & SLJIT_INT_OP) + if (op & SLJIT_I32_OP) src2w &= 0x1f; else src2w &= 0x3f; @@ -1248,20 +1248,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler #endif } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_register_index(reg)); return reg_map[reg]; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); return reg << 1; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_s32 size) { CHECK_ERROR(); CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); @@ -1273,7 +1273,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co /* Floating point operators */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void) { #ifdef SLJIT_IS_FPU_AVAILABLE return SLJIT_IS_FPU_AVAILABLE; @@ -1286,17 +1286,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) #endif } -#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 7)) -#define FMT(op) (((op & SLJIT_SINGLE_OP) ^ SLJIT_SINGLE_OP) << (21 - 8)) +#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_F32_OP) >> 7)) +#define FMT(op) (((op & SLJIT_F32_OP) ^ SLJIT_F32_OP) << (21 - 8)) -static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) # define flags 0 #else - sljit_si flags = (GET_OPCODE(op) == SLJIT_CONVW_FROMD) << 21; + sljit_s32 flags = (GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64) << 21; #endif if (src & SLJIT_MEM) { @@ -1322,17 +1322,17 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler * #endif } -static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) # define flags 0 #else - sljit_si flags = (GET_OPCODE(op) == SLJIT_CONVD_FROMW) << 21; + sljit_s32 flags = (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW) << 21; #endif - sljit_si dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1; + sljit_s32 dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1; if (FAST_IS_REG(src)) FAIL_IF(push_inst(compiler, MTC1 | flags | T(src) | FS(TMP_FREG1), MOVABLE_INS)); @@ -1342,14 +1342,14 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler * } else { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) - srcw = (sljit_si)srcw; + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) + srcw = (sljit_s32)srcw; #endif FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw)); FAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG1) | FS(TMP_FREG1), MOVABLE_INS)); } - FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | (((op & SLJIT_SINGLE_OP) ^ SLJIT_SINGLE_OP) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | (((op & SLJIT_F32_OP) ^ SLJIT_F32_OP) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS)); if (dst & SLJIT_MEM) return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0); @@ -1360,9 +1360,9 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler * #endif } -static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { if (src1 & SLJIT_MEM) { FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); @@ -1399,21 +1399,21 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler return push_inst(compiler, C_UN_S | FMT(op) | FT(src2) | FS(src1), FCSR_FCC); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r; + sljit_s32 dst_r; CHECK_ERROR(); compiler->cache_arg = 0; compiler->cache_argw = 0; - SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error); + SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error); SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); - if (GET_OPCODE(op) == SLJIT_CONVD_FROMS) - op ^= SLJIT_SINGLE_OP; + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) + op ^= SLJIT_F32_OP; dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1; @@ -1425,7 +1425,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile src <<= 1; switch (GET_OPCODE(op)) { - case SLJIT_DMOV: + case SLJIT_MOV_F64: if (src != dst_r) { if (dst_r != TMP_FREG1) FAIL_IF(push_inst(compiler, MOV_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS)); @@ -1433,15 +1433,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile dst_r = src; } break; - case SLJIT_DNEG: + case SLJIT_NEG_F64: FAIL_IF(push_inst(compiler, NEG_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS)); break; - case SLJIT_DABS: + case SLJIT_ABS_F64: FAIL_IF(push_inst(compiler, ABS_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS)); break; - case SLJIT_CONVD_FROMS: - FAIL_IF(push_inst(compiler, CVT_S_S | ((op & SLJIT_SINGLE_OP) ? 1 : (1 << 21)) | FS(src) | FD(dst_r), MOVABLE_INS)); - op ^= SLJIT_SINGLE_OP; + case SLJIT_CONV_F64_FROM_F32: + FAIL_IF(push_inst(compiler, CVT_S_S | ((op & SLJIT_F32_OP) ? 1 : (1 << 21)) | FS(src) | FD(dst_r), MOVABLE_INS)); + op ^= SLJIT_F32_OP; break; } @@ -1450,12 +1450,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si dst_r, flags = 0; + sljit_s32 dst_r, flags = 0; CHECK_ERROR(); CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -1509,19 +1509,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile src2 = TMP_FREG2; switch (GET_OPCODE(op)) { - case SLJIT_DADD: + case SLJIT_ADD_F64: FAIL_IF(push_inst(compiler, ADD_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS)); break; - case SLJIT_DSUB: + case SLJIT_SUB_F64: FAIL_IF(push_inst(compiler, SUB_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS)); break; - case SLJIT_DMUL: + case SLJIT_MUL_F64: FAIL_IF(push_inst(compiler, MUL_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS)); break; - case SLJIT_DDIV: + case SLJIT_DIV_F64: FAIL_IF(push_inst(compiler, DIV_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS)); break; } @@ -1536,7 +1536,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile /* Other instructions */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); @@ -1553,7 +1553,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c return emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); @@ -1617,12 +1617,12 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi flags = IS_BIT16_COND; \ delay_check = FCSR_FCC; -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { struct sljit_jump *jump; sljit_ins inst; - sljit_si flags = 0; - sljit_si delay_check = UNMOVABLE_INS; + sljit_s32 flags = 0; + sljit_s32 delay_check = UNMOVABLE_INS; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_emit_jump(compiler, type)); @@ -1634,27 +1634,27 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile switch (type) { case SLJIT_EQUAL: - case SLJIT_D_NOT_EQUAL: + case SLJIT_NOT_EQUAL_F64: BR_NZ(EQUAL_FLAG); break; case SLJIT_NOT_EQUAL: - case SLJIT_D_EQUAL: + case SLJIT_EQUAL_F64: BR_Z(EQUAL_FLAG); break; case SLJIT_LESS: - case SLJIT_D_LESS: + case SLJIT_LESS_F64: BR_Z(ULESS_FLAG); break; case SLJIT_GREATER_EQUAL: - case SLJIT_D_GREATER_EQUAL: + case SLJIT_GREATER_EQUAL_F64: BR_NZ(ULESS_FLAG); break; case SLJIT_GREATER: - case SLJIT_D_GREATER: + case SLJIT_GREATER_F64: BR_Z(UGREATER_FLAG); break; case SLJIT_LESS_EQUAL: - case SLJIT_D_LESS_EQUAL: + case SLJIT_LESS_EQUAL_F64: BR_NZ(UGREATER_FLAG); break; case SLJIT_SIG_LESS: @@ -1677,10 +1677,10 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile case SLJIT_MUL_NOT_OVERFLOW: BR_NZ(OVERFLOW_FLAG); break; - case SLJIT_D_UNORDERED: + case SLJIT_UNORDERED_F64: BR_F(); break; - case SLJIT_D_ORDERED: + case SLJIT_ORDERED_F64: BR_T(); break; default: @@ -1733,12 +1733,12 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile src2 = 0; \ } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { struct sljit_jump *jump; - sljit_si flags; + sljit_s32 flags; sljit_ins inst; CHECK_ERROR_PTR(); @@ -1748,7 +1748,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler compiler->cache_arg = 0; compiler->cache_argw = 0; - flags = ((type & SLJIT_INT_OP) ? INT_DATA : WORD_DATA) | LOAD_DATA; + flags = ((type & SLJIT_I32_OP) ? INT_DATA : WORD_DATA) | LOAD_DATA; if (src1 & SLJIT_MEM) { PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG1), src1, src1w, src2, src2w)); src1 = TMP_REG1; @@ -1854,13 +1854,13 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler #undef RESOLVE_IMM1 #undef RESOLVE_IMM2 -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { struct sljit_jump *jump; sljit_ins inst; - sljit_si if_true; + sljit_s32 if_true; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w)); @@ -1888,37 +1888,37 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compile jump->flags |= IS_BIT16_COND; switch (type & 0xff) { - case SLJIT_D_EQUAL: + case SLJIT_EQUAL_F64: inst = C_UEQ_S; if_true = 1; break; - case SLJIT_D_NOT_EQUAL: + case SLJIT_NOT_EQUAL_F64: inst = C_UEQ_S; if_true = 0; break; - case SLJIT_D_LESS: + case SLJIT_LESS_F64: inst = C_ULT_S; if_true = 1; break; - case SLJIT_D_GREATER_EQUAL: + case SLJIT_GREATER_EQUAL_F64: inst = C_ULT_S; if_true = 0; break; - case SLJIT_D_GREATER: + case SLJIT_GREATER_F64: inst = C_ULE_S; if_true = 0; break; - case SLJIT_D_LESS_EQUAL: + case SLJIT_LESS_EQUAL_F64: inst = C_ULE_S; if_true = 1; break; - case SLJIT_D_UNORDERED: + case SLJIT_UNORDERED_F64: inst = C_UN_S; if_true = 1; break; default: /* Make compilers happy. */ SLJIT_ASSERT_STOP(); - case SLJIT_D_ORDERED: + case SLJIT_ORDERED_F64: inst = C_UN_S; if_true = 0; break; @@ -1943,9 +1943,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compile #undef FLOAT_DATA #undef FMT -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) { - sljit_si src_r = TMP_REG2; + sljit_s32 src_r = TMP_REG2; struct sljit_jump *jump = NULL; CHECK_ERROR(); @@ -2001,17 +2001,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw, + sljit_s32 type) { - sljit_si sugg_dst_ar, dst_ar; - sljit_si flags = GET_ALL_FLAGS(op); + sljit_s32 sugg_dst_ar, dst_ar; + sljit_s32 flags = GET_ALL_FLAGS(op); #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) # define mem_type WORD_DATA #else - sljit_si mem_type = (op & SLJIT_INT_OP) ? (INT_DATA | SIGNED_DATA) : WORD_DATA; + sljit_s32 mem_type = (op & SLJIT_I32_OP) ? (INT_DATA | SIGNED_DATA) : WORD_DATA; #endif CHECK_ERROR(); @@ -2023,7 +2023,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com op = GET_OPCODE(op); #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - if (op == SLJIT_MOV_SI || op == SLJIT_MOV_UI) + if (op == SLJIT_MOV_S32 || op == SLJIT_MOV_U32) mem_type = INT_DATA | SIGNED_DATA; #endif sugg_dst_ar = DR((op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2); @@ -2045,14 +2045,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com break; case SLJIT_LESS: case SLJIT_GREATER_EQUAL: - case SLJIT_D_LESS: - case SLJIT_D_GREATER_EQUAL: + case SLJIT_LESS_F64: + case SLJIT_GREATER_EQUAL_F64: dst_ar = ULESS_FLAG; break; case SLJIT_GREATER: case SLJIT_LESS_EQUAL: - case SLJIT_D_GREATER: - case SLJIT_D_LESS_EQUAL: + case SLJIT_GREATER_F64: + case SLJIT_LESS_EQUAL_F64: dst_ar = UGREATER_FLAG; break; case SLJIT_SIG_LESS: @@ -2073,13 +2073,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com dst_ar = sugg_dst_ar; type ^= 0x1; /* Flip type bit for the XORI below. */ break; - case SLJIT_D_EQUAL: - case SLJIT_D_NOT_EQUAL: + case SLJIT_EQUAL_F64: + case SLJIT_NOT_EQUAL_F64: dst_ar = EQUAL_FLAG; break; - case SLJIT_D_UNORDERED: - case SLJIT_D_ORDERED: + case SLJIT_UNORDERED_F64: + case SLJIT_ORDERED_F64: FAIL_IF(push_inst(compiler, CFC1 | TA(sugg_dst_ar) | DA(FCSR_REG), sugg_dst_ar)); FAIL_IF(push_inst(compiler, SRL | TA(sugg_dst_ar) | DA(sugg_dst_ar) | SH_IMM(23), sugg_dst_ar)); FAIL_IF(push_inst(compiler, ANDI | SA(sugg_dst_ar) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar)); @@ -2115,10 +2115,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com #endif } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; - sljit_si reg; + sljit_s32 reg; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); diff --git a/pcre2-10.21/src/sljit/sljitNativePPC_32.c b/pcre2-10.22/src/sljit/sljitNativePPC_32.c similarity index 94% rename from pcre2-10.21/src/sljit/sljitNativePPC_32.c rename to pcre2-10.22/src/sljit/sljitNativePPC_32.c index b14b75ceb..0f23cf86d 100644 --- a/pcre2-10.21/src/sljit/sljitNativePPC_32.c +++ b/pcre2-10.22/src/sljit/sljitNativePPC_32.c @@ -26,7 +26,7 @@ /* ppc 32-bit arch dependent functions. */ -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm) +static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm) { if (imm <= SIMM_MAX && imm >= SIMM_MIN) return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm)); @@ -41,39 +41,39 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sl #define INS_CLEAR_LEFT(dst, src, from) \ (RLWINM | S(src) | A(dst) | ((from) << 6) | (31 << 1)) -static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_si src1, sljit_si src2) +static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, + sljit_s32 dst, sljit_s32 src1, sljit_s32 src2) { switch (op) { case SLJIT_MOV: - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: + case SLJIT_MOV_U32: + case SLJIT_MOV_S32: case SLJIT_MOV_P: SLJIT_ASSERT(src1 == TMP_REG1); if (dst != src2) return push_inst(compiler, OR | S(src2) | A(dst) | B(src2)); return SLJIT_SUCCESS; - case SLJIT_MOV_UB: - case SLJIT_MOV_SB: + case SLJIT_MOV_U8: + case SLJIT_MOV_S8: SLJIT_ASSERT(src1 == TMP_REG1); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SB) + if (op == SLJIT_MOV_S8) return push_inst(compiler, EXTSB | S(src2) | A(dst)); return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24)); } - else if ((flags & REG_DEST) && op == SLJIT_MOV_SB) + else if ((flags & REG_DEST) && op == SLJIT_MOV_S8) return push_inst(compiler, EXTSB | S(src2) | A(dst)); else { SLJIT_ASSERT(dst == src2); } return SLJIT_SUCCESS; - case SLJIT_MOV_UH: - case SLJIT_MOV_SH: + case SLJIT_MOV_U16: + case SLJIT_MOV_S16: SLJIT_ASSERT(src1 == TMP_REG1); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SH) + if (op == SLJIT_MOV_S16) return push_inst(compiler, EXTSH | S(src2) | A(dst)); return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16)); } @@ -244,7 +244,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si reg, sljit_sw init_value) +static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw init_value) { FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 16))); return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value)); diff --git a/pcre2-10.21/src/sljit/sljitNativePPC_64.c b/pcre2-10.22/src/sljit/sljitNativePPC_64.c similarity index 95% rename from pcre2-10.21/src/sljit/sljitNativePPC_64.c rename to pcre2-10.22/src/sljit/sljitNativePPC_64.c index 182ac7b3d..8e3223f72 100644 --- a/pcre2-10.21/src/sljit/sljitNativePPC_64.c +++ b/pcre2-10.22/src/sljit/sljitNativePPC_64.c @@ -41,7 +41,7 @@ #define PUSH_RLDICR(reg, shift) \ push_inst(compiler, RLDI(reg, reg, 63 - shift, shift, 1)) -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm) +static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm) { sljit_uw tmp; sljit_uw shift; @@ -145,8 +145,8 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sl src1 = TMP_REG1; \ } -static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_si src1, sljit_si src2) +static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, + sljit_s32 dst, sljit_s32 src1, sljit_s32 src2) { switch (op) { case SLJIT_MOV: @@ -156,11 +156,11 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj return push_inst(compiler, OR | S(src2) | A(dst) | B(src2)); return SLJIT_SUCCESS; - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: + case SLJIT_MOV_U32: + case SLJIT_MOV_S32: SLJIT_ASSERT(src1 == TMP_REG1); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SI) + if (op == SLJIT_MOV_S32) return push_inst(compiler, EXTSW | S(src2) | A(dst)); return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 0)); } @@ -169,26 +169,26 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj } return SLJIT_SUCCESS; - case SLJIT_MOV_UB: - case SLJIT_MOV_SB: + case SLJIT_MOV_U8: + case SLJIT_MOV_S8: SLJIT_ASSERT(src1 == TMP_REG1); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SB) + if (op == SLJIT_MOV_S8) return push_inst(compiler, EXTSB | S(src2) | A(dst)); return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24)); } - else if ((flags & REG_DEST) && op == SLJIT_MOV_SB) + else if ((flags & REG_DEST) && op == SLJIT_MOV_S8) return push_inst(compiler, EXTSB | S(src2) | A(dst)); else { SLJIT_ASSERT(dst == src2); } return SLJIT_SUCCESS; - case SLJIT_MOV_UH: - case SLJIT_MOV_SH: + case SLJIT_MOV_U16: + case SLJIT_MOV_S16: SLJIT_ASSERT(src1 == TMP_REG1); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SH) + if (op == SLJIT_MOV_S16) return push_inst(compiler, EXTSH | S(src2) | A(dst)); return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16)); } @@ -389,7 +389,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si reg, sljit_sw init_value) +static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw init_value) { FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 48))); FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value >> 32))); diff --git a/pcre2-10.21/src/sljit/sljitNativePPC_common.c b/pcre2-10.22/src/sljit/sljitNativePPC_common.c similarity index 87% rename from pcre2-10.21/src/sljit/sljitNativePPC_common.c rename to pcre2-10.22/src/sljit/sljitNativePPC_common.c index b6a043f4e..a3647327b 100644 --- a/pcre2-10.21/src/sljit/sljitNativePPC_common.c +++ b/pcre2-10.22/src/sljit/sljitNativePPC_common.c @@ -24,14 +24,14 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) { return "PowerPC" SLJIT_CPUINFO; } /* Length of an instruction word. Both for ppc-32 and ppc-64. */ -typedef sljit_ui sljit_ins; +typedef sljit_u32 sljit_ins; #if ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && (defined _AIX)) \ || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) @@ -46,6 +46,8 @@ typedef sljit_ui sljit_ins; #define SLJIT_PASS_ENTRY_ADDR_TO_CALL 1 #endif +#if (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL) + static void ppc_cache_flush(sljit_ins *from, sljit_ins *to) { #ifdef _AIX @@ -87,6 +89,8 @@ static void ppc_cache_flush(sljit_ins *from, sljit_ins *to) #endif /* _AIX */ } +#endif /* (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL) */ + #define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) #define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) #define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4) @@ -101,7 +105,7 @@ static void ppc_cache_flush(sljit_ins *from, sljit_ins *to) #define TMP_FREG1 (0) #define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 7] = { +static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 7] = { 0, 3, 4, 5, 6, 7, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 1, 8, 9, 10, 31, 12 }; @@ -236,7 +240,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct } #endif -static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins) +static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins) { sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); @@ -245,7 +249,7 @@ static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins) return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) +static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) { sljit_sw diff; sljit_uw target_addr; @@ -571,32 +575,32 @@ ALT_FORM6 0x200000 */ #define STACK_LOAD LD #endif -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_si i, tmp, offs; + sljit_s32 i, tmp, offs; CHECK_ERROR(); CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); FAIL_IF(push_inst(compiler, MFLR | D(0))); - offs = -(sljit_si)(sizeof(sljit_sw)); + offs = -(sljit_s32)(sizeof(sljit_sw)); FAIL_IF(push_inst(compiler, STACK_STORE | S(TMP_ZERO) | A(SLJIT_SP) | IMM(offs))); tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; for (i = SLJIT_S0; i >= tmp; i--) { - offs -= (sljit_si)(sizeof(sljit_sw)); + offs -= (sljit_s32)(sizeof(sljit_sw)); FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs))); } for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { - offs -= (sljit_si)(sizeof(sljit_sw)); + offs -= (sljit_s32)(sizeof(sljit_sw)); FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs))); } - SLJIT_ASSERT(offs == -(sljit_si)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1)); + SLJIT_ASSERT(offs == -(sljit_s32)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1)); #if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2) FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_SP) | IMM(2 * sizeof(sljit_sw)))); @@ -635,9 +639,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { CHECK_ERROR(); CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -648,9 +652,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { - sljit_si i, tmp, offs; + sljit_s32 i, tmp, offs; CHECK_ERROR(); CHECK(check_sljit_emit_return(compiler, op, src, srcw)); @@ -670,18 +674,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_SP) | IMM(sizeof(sljit_sw)))); #endif - offs = -(sljit_si)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1); + offs = -(sljit_s32)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1); tmp = compiler->scratches; for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) { FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs))); - offs += (sljit_si)(sizeof(sljit_sw)); + offs += (sljit_s32)(sizeof(sljit_sw)); } tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG; for (i = tmp; i <= SLJIT_S0; i++) { FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs))); - offs += (sljit_si)(sizeof(sljit_sw)); + offs += (sljit_s32)(sizeof(sljit_sw)); } FAIL_IF(push_inst(compiler, STACK_LOAD | D(TMP_ZERO) | A(SLJIT_SP) | IMM(offs))); @@ -722,7 +726,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi (((inst) & ~(INT_ALIGNED | UPDATE_REQ)) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg))) #endif -static SLJIT_CONST sljit_ins data_transfer_insts[64 + 8] = { +static const sljit_ins data_transfer_insts[64 + 8] = { /* -------- Unsigned -------- */ @@ -841,7 +845,7 @@ static SLJIT_CONST sljit_ins data_transfer_insts[64 + 8] = { #undef ARCH_32_64 /* Simple cases, (no caching is required). */ -static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { sljit_ins inst; @@ -891,7 +895,7 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_fl /* See getput_arg below. Note: can_cache is called only for binary operators. Those operator always uses word arguments without write back. */ -static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { sljit_sw high_short, next_high_short; #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) @@ -940,9 +944,9 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_ #endif /* Emit the necessary instructions. See can_cache above. */ -static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { - sljit_si tmp_r; + sljit_s32 tmp_r; sljit_ins inst; sljit_sw high_short, next_high_short; #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) @@ -992,7 +996,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, #endif arg &= REG_MASK; - high_short = (sljit_si)(argw + ((argw & 0x8000) << 1)) & ~0xffff; + high_short = (sljit_s32)(argw + ((argw & 0x8000) << 1)) & ~0xffff; /* The getput_arg_fast should handle this otherwise. */ #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) SLJIT_ASSERT(high_short && high_short <= 0x7fffffffl && high_short >= -0x80000000l); @@ -1010,7 +1014,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, } else if (compiler->cache_arg != (SLJIT_MEM | arg) || high_short != compiler->cache_argw) { if ((next_arg & SLJIT_MEM) && !(next_arg & OFFS_REG_MASK)) { - next_high_short = (sljit_si)(next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff; + next_high_short = (sljit_s32)(next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff; if (high_short == next_high_short) { compiler->cache_arg = SLJIT_MEM | arg; compiler->cache_argw = high_short; @@ -1107,27 +1111,27 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, #endif } -static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w) { if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) return compiler->error; return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); } -static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si input_flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 input_flags, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { /* arg1 goes to TMP_REG1 or src reg arg2 goes to TMP_REG2, imm or src reg TMP_REG3 can be used for caching result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ - sljit_si dst_r; - sljit_si src1_r; - sljit_si src2_r; - sljit_si sugg_src2_r = TMP_REG2; - sljit_si flags = input_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_FORM6 | ALT_SIGN_EXT | ALT_SET_FLAGS); + sljit_s32 dst_r; + sljit_s32 src1_r; + sljit_s32 src2_r; + sljit_s32 sugg_src2_r = TMP_REG2; + sljit_s32 flags = input_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_FORM6 | ALT_SIGN_EXT | ALT_SET_FLAGS); if (!(input_flags & ALT_KEEP_CACHE)) { compiler->cache_arg = 0; @@ -1136,14 +1140,14 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i /* Destination check. */ if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32 && !(src2 & SLJIT_MEM)) return SLJIT_SUCCESS; dst_r = TMP_REG2; } else if (FAST_IS_REG(dst)) { dst_r = dst; flags |= REG_DEST; - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) sugg_src2_r = dst_r; } else { @@ -1178,7 +1182,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i if (FAST_IS_REG(src2)) { src2_r = src2; flags |= REG2_SOURCE; - if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) dst_r = src2_r; } else if (src2 & SLJIT_IMM) { @@ -1243,10 +1247,10 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - sljit_si int_op = op & SLJIT_INT_OP; + sljit_s32 int_op = op & SLJIT_I32_OP; #endif CHECK_ERROR(); @@ -1257,33 +1261,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler case SLJIT_BREAKPOINT: case SLJIT_NOP: return push_inst(compiler, NOP); - case SLJIT_LUMUL: - case SLJIT_LSMUL: + case SLJIT_LMUL_UW: + case SLJIT_LMUL_SW: FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0))); #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1))); - return push_inst(compiler, (op == SLJIT_LUMUL ? MULHDU : MULHD) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1)); + return push_inst(compiler, (op == SLJIT_LMUL_UW ? MULHDU : MULHD) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1)); #else FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1))); - return push_inst(compiler, (op == SLJIT_LUMUL ? MULHWU : MULHW) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1)); + return push_inst(compiler, (op == SLJIT_LMUL_UW ? MULHWU : MULHW) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1)); #endif - case SLJIT_UDIVMOD: - case SLJIT_SDIVMOD: + case SLJIT_DIVMOD_UW: + case SLJIT_DIVMOD_SW: FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0))); #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - FAIL_IF(push_inst(compiler, (int_op ? (op == SLJIT_UDIVMOD ? DIVWU : DIVW) : (op == SLJIT_UDIVMOD ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1))); + FAIL_IF(push_inst(compiler, (int_op ? (op == SLJIT_DIVMOD_UW ? DIVWU : DIVW) : (op == SLJIT_DIVMOD_UW ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1))); FAIL_IF(push_inst(compiler, (int_op ? MULLW : MULLD) | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1))); #else - FAIL_IF(push_inst(compiler, (op == SLJIT_UDIVMOD ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1))); + FAIL_IF(push_inst(compiler, (op == SLJIT_DIVMOD_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1))); FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1))); #endif return push_inst(compiler, SUBF | D(SLJIT_R1) | A(SLJIT_R1) | B(TMP_REG1)); - case SLJIT_UDIVI: - case SLJIT_SDIVI: + case SLJIT_DIV_UW: + case SLJIT_DIV_SW: #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - return push_inst(compiler, (int_op ? (op == SLJIT_UDIVI ? DIVWU : DIVW) : (op == SLJIT_UDIVI ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)); + return push_inst(compiler, (int_op ? (op == SLJIT_DIV_UW ? DIVWU : DIVW) : (op == SLJIT_DIV_UW ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)); #else - return push_inst(compiler, (op == SLJIT_UDIVI ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)); + return push_inst(compiler, (op == SLJIT_DIV_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)); #endif } @@ -1293,12 +1297,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler #define EMIT_MOV(type, type_flags, type_cast) \ emit_op(compiler, (src & SLJIT_IMM) ? SLJIT_MOV : type, flags | (type_flags), dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? type_cast srcw : srcw) -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0; - sljit_si op_flags = GET_ALL_FLAGS(op); + sljit_s32 flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0; + sljit_s32 op_flags = GET_ALL_FLAGS(op); CHECK_ERROR(); CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); @@ -1312,21 +1316,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler if (op_flags & SLJIT_SET_O) FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO))); - if (op_flags & SLJIT_INT_OP) { + if (op_flags & SLJIT_I32_OP) { if (op < SLJIT_NOT) { if (FAST_IS_REG(src) && src == dst) { if (!TYPE_CAST_NEEDED(op)) return SLJIT_SUCCESS; } #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - if (op == SLJIT_MOV_SI && (src & SLJIT_MEM)) - op = SLJIT_MOV_UI; - if (op == SLJIT_MOVU_SI && (src & SLJIT_MEM)) - op = SLJIT_MOVU_UI; - if (op == SLJIT_MOV_UI && (src & SLJIT_IMM)) - op = SLJIT_MOV_SI; - if (op == SLJIT_MOVU_UI && (src & SLJIT_IMM)) - op = SLJIT_MOVU_SI; + if (op == SLJIT_MOV_S32 && (src & SLJIT_MEM)) + op = SLJIT_MOV_U32; + if (op == SLJIT_MOVU_S32 && (src & SLJIT_MEM)) + op = SLJIT_MOVU_U32; + if (op == SLJIT_MOV_U32 && (src & SLJIT_IMM)) + op = SLJIT_MOV_S32; + if (op == SLJIT_MOVU_U32 && (src & SLJIT_IMM)) + op = SLJIT_MOVU_S32; #endif } #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) @@ -1334,7 +1338,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler /* Most operations expect sign extended arguments. */ flags |= INT_DATA | SIGNED_DATA; if (src & SLJIT_IMM) - srcw = (sljit_si)srcw; + srcw = (sljit_s32)srcw; } #endif } @@ -1343,58 +1347,58 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler case SLJIT_MOV: case SLJIT_MOV_P: #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: + case SLJIT_MOV_U32: + case SLJIT_MOV_S32: #endif return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - case SLJIT_MOV_UI: - return EMIT_MOV(SLJIT_MOV_UI, INT_DATA, (sljit_ui)); + case SLJIT_MOV_U32: + return EMIT_MOV(SLJIT_MOV_U32, INT_DATA, (sljit_u32)); - case SLJIT_MOV_SI: - return EMIT_MOV(SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, (sljit_si)); + case SLJIT_MOV_S32: + return EMIT_MOV(SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, (sljit_s32)); #endif - case SLJIT_MOV_UB: - return EMIT_MOV(SLJIT_MOV_UB, BYTE_DATA, (sljit_ub)); + case SLJIT_MOV_U8: + return EMIT_MOV(SLJIT_MOV_U8, BYTE_DATA, (sljit_u8)); - case SLJIT_MOV_SB: - return EMIT_MOV(SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA, (sljit_sb)); + case SLJIT_MOV_S8: + return EMIT_MOV(SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA, (sljit_s8)); - case SLJIT_MOV_UH: - return EMIT_MOV(SLJIT_MOV_UH, HALF_DATA, (sljit_uh)); + case SLJIT_MOV_U16: + return EMIT_MOV(SLJIT_MOV_U16, HALF_DATA, (sljit_u16)); - case SLJIT_MOV_SH: - return EMIT_MOV(SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA, (sljit_sh)); + case SLJIT_MOV_S16: + return EMIT_MOV(SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, (sljit_s16)); case SLJIT_MOVU: case SLJIT_MOVU_P: #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) - case SLJIT_MOVU_UI: - case SLJIT_MOVU_SI: + case SLJIT_MOVU_U32: + case SLJIT_MOVU_S32: #endif return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - case SLJIT_MOVU_UI: - return EMIT_MOV(SLJIT_MOV_UI, INT_DATA | WRITE_BACK, (sljit_ui)); + case SLJIT_MOVU_U32: + return EMIT_MOV(SLJIT_MOV_U32, INT_DATA | WRITE_BACK, (sljit_u32)); - case SLJIT_MOVU_SI: - return EMIT_MOV(SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, (sljit_si)); + case SLJIT_MOVU_S32: + return EMIT_MOV(SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | WRITE_BACK, (sljit_s32)); #endif - case SLJIT_MOVU_UB: - return EMIT_MOV(SLJIT_MOV_UB, BYTE_DATA | WRITE_BACK, (sljit_ub)); + case SLJIT_MOVU_U8: + return EMIT_MOV(SLJIT_MOV_U8, BYTE_DATA | WRITE_BACK, (sljit_u8)); - case SLJIT_MOVU_SB: - return EMIT_MOV(SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA | WRITE_BACK, (sljit_sb)); + case SLJIT_MOVU_S8: + return EMIT_MOV(SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA | WRITE_BACK, (sljit_s8)); - case SLJIT_MOVU_UH: - return EMIT_MOV(SLJIT_MOV_UH, HALF_DATA | WRITE_BACK, (sljit_uh)); + case SLJIT_MOVU_U16: + return EMIT_MOV(SLJIT_MOV_U16, HALF_DATA | WRITE_BACK, (sljit_u16)); - case SLJIT_MOVU_SH: - return EMIT_MOV(SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA | WRITE_BACK, (sljit_sh)); + case SLJIT_MOVU_S16: + return EMIT_MOV(SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA | WRITE_BACK, (sljit_s16)); case SLJIT_NOT: return emit_op(compiler, SLJIT_NOT, flags, dst, dstw, TMP_REG1, 0, src, srcw); @@ -1404,7 +1408,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler case SLJIT_CLZ: #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - return emit_op(compiler, SLJIT_CLZ, flags | (!(op_flags & SLJIT_INT_OP) ? 0 : ALT_FORM1), dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, SLJIT_CLZ, flags | (!(op_flags & SLJIT_I32_OP) ? 0 : ALT_FORM1), dst, dstw, TMP_REG1, 0, src, srcw); #else return emit_op(compiler, SLJIT_CLZ, flags, dst, dstw, TMP_REG1, 0, src, srcw); #endif @@ -1448,12 +1452,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler ((src) & SLJIT_IMM) #endif -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0; + sljit_s32 flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0; CHECK_ERROR(); CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -1467,13 +1471,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler src2 = TMP_ZERO; #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - if (op & SLJIT_INT_OP) { + if (op & SLJIT_I32_OP) { /* Most operations expect sign extended arguments. */ flags |= INT_DATA | SIGNED_DATA; if (src1 & SLJIT_IMM) - src1w = (sljit_si)(src1w); + src1w = (sljit_s32)(src1w); if (src2 & SLJIT_IMM) - src2w = (sljit_si)(src2w); + src2w = (sljit_s32)(src2w); if (GET_FLAGS(op)) flags |= ALT_SIGN_EXT; } @@ -1549,7 +1553,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler } if (dst == SLJIT_UNUSED && (op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S)) && !(op & (SLJIT_SET_O | SLJIT_SET_C))) { if (!(op & SLJIT_SET_U)) { - /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */ + /* We know ALT_SIGN_EXT is set if it is an SLJIT_I32_OP on 64 bit systems. */ if (TEST_SL_IMM(src2, src2w)) { compiler->imm = src2w & 0xffff; return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); @@ -1560,7 +1564,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler } } if (!(op & (SLJIT_SET_E | SLJIT_SET_S))) { - /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */ + /* We know ALT_SIGN_EXT is set if it is an SLJIT_I32_OP on 64 bit systems. */ if (TEST_UL_IMM(src2, src2w)) { compiler->imm = src2w & 0xffff; return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); @@ -1579,7 +1583,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); } } - /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */ + /* We know ALT_SIGN_EXT is set if it is an SLJIT_I32_OP on 64 bit systems. */ return emit_op(compiler, SLJIT_SUB, flags | (!(op & SLJIT_SET_U) ? 0 : ALT_FORM6), dst, dstw, src1, src1w, src2, src2w); case SLJIT_SUBC: @@ -1587,7 +1591,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler case SLJIT_MUL: #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - if (op & SLJIT_INT_OP) + if (op & SLJIT_I32_OP) flags |= ALT_FORM2; #endif if (!GET_FLAGS(op)) { @@ -1643,7 +1647,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler case SLJIT_SHL: case SLJIT_LSHR: #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - if (op & SLJIT_INT_OP) + if (op & SLJIT_I32_OP) flags |= ALT_FORM2; #endif if (src2 & SLJIT_IMM) { @@ -1656,20 +1660,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_register_index(reg)); return reg_map[reg]; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); return reg; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_s32 size) { CHECK_ERROR(); CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); @@ -1681,7 +1685,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co /* Floating point operators */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void) { #ifdef SLJIT_IS_FPU_AVAILABLE return SLJIT_IS_FPU_AVAILABLE; @@ -1691,8 +1695,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) #endif } -#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 6)) -#define SELECT_FOP(op, single, double) ((op & SLJIT_SINGLE_OP) ? single : double) +#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_F32_OP) >> 6)) +#define SELECT_FOP(op, single, double) ((op & SLJIT_F32_OP) ? single : double) #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) #define FLOAT_TMP_MEM_OFFSET (6 * sizeof(sljit_sw)) @@ -1709,9 +1713,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) #endif /* SLJIT_CONFIG_PPC_64 */ -static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { if (src & SLJIT_MEM) { /* We can ignore the temporary data store on the stack from caching point of view. */ @@ -1721,12 +1725,12 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler * #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) op = GET_OPCODE(op); - FAIL_IF(push_inst(compiler, (op == SLJIT_CONVI_FROMD ? FCTIWZ : FCTIDZ) | FD(TMP_FREG1) | FB(src))); + FAIL_IF(push_inst(compiler, (op == SLJIT_CONV_S32_FROM_F64 ? FCTIWZ : FCTIDZ) | FD(TMP_FREG1) | FB(src))); if (dst == SLJIT_UNUSED) return SLJIT_SUCCESS; - if (op == SLJIT_CONVW_FROMD) { + if (op == SLJIT_CONV_SW_FROM_F64) { if (FAST_IS_REG(dst)) { FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0)); return emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0); @@ -1777,21 +1781,21 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler * return push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(dst & REG_MASK) | B(dstw)); } -static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; if (src & SLJIT_IMM) { - if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) - srcw = (sljit_si)srcw; + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) + srcw = (sljit_s32)srcw; FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); src = TMP_REG1; } - else if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) { + else if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) { if (FAST_IS_REG(src)) FAIL_IF(push_inst(compiler, EXTSW | S(src) | A(TMP_REG1))); else @@ -1810,14 +1814,14 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler * if (dst & SLJIT_MEM) return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0); - if (op & SLJIT_SINGLE_OP) + if (op & SLJIT_F32_OP) return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r)); return SLJIT_SUCCESS; #else - sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - sljit_si invert_sign = 1; + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + sljit_s32 invert_sign = 1; if (src & SLJIT_IMM) { FAIL_IF(load_immediate(compiler, TMP_REG1, srcw ^ 0x80000000)); @@ -1848,16 +1852,16 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler * if (dst & SLJIT_MEM) return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0); - if (op & SLJIT_SINGLE_OP) + if (op & SLJIT_F32_OP) return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r)); return SLJIT_SUCCESS; #endif } -static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { if (src1 & SLJIT_MEM) { FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); @@ -1872,21 +1876,21 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler return push_inst(compiler, FCMPU | CRD(4) | FA(src1) | FB(src2)); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r; + sljit_s32 dst_r; CHECK_ERROR(); compiler->cache_arg = 0; compiler->cache_argw = 0; - SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x4), float_transfer_bit_error); + SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100) && !(DOUBLE_DATA & 0x4), float_transfer_bit_error); SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); - if (GET_OPCODE(op) == SLJIT_CONVD_FROMS) - op ^= SLJIT_SINGLE_OP; + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) + op ^= SLJIT_F32_OP; dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; @@ -1896,14 +1900,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile } switch (GET_OPCODE(op)) { - case SLJIT_CONVD_FROMS: - op ^= SLJIT_SINGLE_OP; - if (op & SLJIT_SINGLE_OP) { + case SLJIT_CONV_F64_FROM_F32: + op ^= SLJIT_F32_OP; + if (op & SLJIT_F32_OP) { FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(src))); break; } /* Fall through. */ - case SLJIT_DMOV: + case SLJIT_MOV_F64: if (src != dst_r) { if (dst_r != TMP_FREG1) FAIL_IF(push_inst(compiler, FMR | FD(dst_r) | FB(src))); @@ -1911,10 +1915,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile dst_r = src; } break; - case SLJIT_DNEG: + case SLJIT_NEG_F64: FAIL_IF(push_inst(compiler, FNEG | FD(dst_r) | FB(src))); break; - case SLJIT_DABS: + case SLJIT_ABS_F64: FAIL_IF(push_inst(compiler, FABS | FD(dst_r) | FB(src))); break; } @@ -1924,12 +1928,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si dst_r, flags = 0; + sljit_s32 dst_r, flags = 0; CHECK_ERROR(); CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -1979,19 +1983,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile src2 = TMP_FREG2; switch (GET_OPCODE(op)) { - case SLJIT_DADD: + case SLJIT_ADD_F64: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADD) | FD(dst_r) | FA(src1) | FB(src2))); break; - case SLJIT_DSUB: + case SLJIT_SUB_F64: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUB) | FD(dst_r) | FA(src1) | FB(src2))); break; - case SLJIT_DMUL: + case SLJIT_MUL_F64: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMUL) | FD(dst_r) | FA(src1) | FC(src2) /* FMUL use FC as src2 */)); break; - case SLJIT_DDIV: + case SLJIT_DIV_F64: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIV) | FD(dst_r) | FA(src1) | FB(src2))); break; } @@ -2009,7 +2013,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile /* Other instructions */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); @@ -2027,7 +2031,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); @@ -2065,7 +2069,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi return label; } -static sljit_ins get_bo_bi_flags(sljit_si type) +static sljit_ins get_bo_bi_flags(sljit_s32 type) { switch (type) { case SLJIT_EQUAL: @@ -2075,19 +2079,19 @@ static sljit_ins get_bo_bi_flags(sljit_si type) return (4 << 21) | (2 << 16); case SLJIT_LESS: - case SLJIT_D_LESS: + case SLJIT_LESS_F64: return (12 << 21) | ((4 + 0) << 16); case SLJIT_GREATER_EQUAL: - case SLJIT_D_GREATER_EQUAL: + case SLJIT_GREATER_EQUAL_F64: return (4 << 21) | ((4 + 0) << 16); case SLJIT_GREATER: - case SLJIT_D_GREATER: + case SLJIT_GREATER_F64: return (12 << 21) | ((4 + 1) << 16); case SLJIT_LESS_EQUAL: - case SLJIT_D_LESS_EQUAL: + case SLJIT_LESS_EQUAL_F64: return (4 << 21) | ((4 + 1) << 16); case SLJIT_SIG_LESS: @@ -2110,16 +2114,16 @@ static sljit_ins get_bo_bi_flags(sljit_si type) case SLJIT_MUL_NOT_OVERFLOW: return (4 << 21) | (3 << 16); - case SLJIT_D_EQUAL: + case SLJIT_EQUAL_F64: return (12 << 21) | ((4 + 2) << 16); - case SLJIT_D_NOT_EQUAL: + case SLJIT_NOT_EQUAL_F64: return (4 << 21) | ((4 + 2) << 16); - case SLJIT_D_UNORDERED: + case SLJIT_UNORDERED_F64: return (12 << 21) | ((4 + 3) << 16); - case SLJIT_D_ORDERED: + case SLJIT_ORDERED_F64: return (4 << 21) | ((4 + 3) << 16); default: @@ -2128,7 +2132,7 @@ static sljit_ins get_bo_bi_flags(sljit_si type) } } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { struct sljit_jump *jump; sljit_ins bo_bi_flags; @@ -2160,10 +2164,10 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile return jump; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) { struct sljit_jump *jump = NULL; - sljit_si src_r; + sljit_s32 src_r; CHECK_ERROR(); CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); @@ -2211,13 +2215,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil #define INVERT_BIT(dst) \ FAIL_IF(push_inst(compiler, XORI | S(dst) | A(dst) | 0x1)); -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw, + sljit_s32 type) { - sljit_si reg, input_flags; - sljit_si flags = GET_ALL_FLAGS(op); + sljit_s32 reg, input_flags; + sljit_s32 flags = GET_ALL_FLAGS(op); sljit_sw original_dstw = dstw; CHECK_ERROR(); @@ -2235,7 +2239,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com if (op >= SLJIT_ADD && (src & SLJIT_MEM)) { ADJUST_LOCAL_OFFSET(src, srcw); #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - input_flags = (flags & SLJIT_INT_OP) ? INT_DATA : WORD_DATA; + input_flags = (flags & SLJIT_I32_OP) ? INT_DATA : WORD_DATA; #else input_flags = WORD_DATA; #endif @@ -2255,23 +2259,23 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com break; case SLJIT_LESS: - case SLJIT_D_LESS: + case SLJIT_LESS_F64: GET_CR_BIT(4 + 0, reg); break; case SLJIT_GREATER_EQUAL: - case SLJIT_D_GREATER_EQUAL: + case SLJIT_GREATER_EQUAL_F64: GET_CR_BIT(4 + 0, reg); INVERT_BIT(reg); break; case SLJIT_GREATER: - case SLJIT_D_GREATER: + case SLJIT_GREATER_F64: GET_CR_BIT(4 + 1, reg); break; case SLJIT_LESS_EQUAL: - case SLJIT_D_LESS_EQUAL: + case SLJIT_LESS_EQUAL_F64: GET_CR_BIT(4 + 1, reg); INVERT_BIT(reg); break; @@ -2305,20 +2309,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com INVERT_BIT(reg); break; - case SLJIT_D_EQUAL: + case SLJIT_EQUAL_F64: GET_CR_BIT(4 + 2, reg); break; - case SLJIT_D_NOT_EQUAL: + case SLJIT_NOT_EQUAL_F64: GET_CR_BIT(4 + 2, reg); INVERT_BIT(reg); break; - case SLJIT_D_UNORDERED: + case SLJIT_UNORDERED_F64: GET_CR_BIT(4 + 3, reg); break; - case SLJIT_D_ORDERED: + case SLJIT_ORDERED_F64: GET_CR_BIT(4 + 3, reg); INVERT_BIT(reg); break; @@ -2333,7 +2337,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com if (op == SLJIT_MOV) input_flags = WORD_DATA; else { - op = SLJIT_MOV_UI; + op = SLJIT_MOV_U32; input_flags = INT_DATA; } #else @@ -2352,10 +2356,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com return sljit_emit_op2(compiler, op | flags, dst, original_dstw, src, srcw, TMP_REG2, 0); } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; - sljit_si reg; + sljit_s32 reg; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); diff --git a/pcre2-10.21/src/sljit/sljitNativeSPARC_32.c b/pcre2-10.22/src/sljit/sljitNativeSPARC_32.c similarity index 91% rename from pcre2-10.21/src/sljit/sljitNativeSPARC_32.c rename to pcre2-10.22/src/sljit/sljitNativeSPARC_32.c index 4a2e6293d..7e589a17c 100644 --- a/pcre2-10.21/src/sljit/sljitNativeSPARC_32.c +++ b/pcre2-10.22/src/sljit/sljitNativeSPARC_32.c @@ -24,7 +24,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sljit_sw imm) +static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw imm) { if (imm <= SIMM_MAX && imm >= SIMM_MIN) return push_inst(compiler, OR | D(dst) | S1(0) | IMM(imm), DR(dst)); @@ -35,26 +35,26 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sl #define ARG2(flags, src2) ((flags & SRC2_IMM) ? IMM(src2) : S2(src2)) -static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_si src1, sljit_sw src2) +static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, + sljit_s32 dst, sljit_s32 src1, sljit_sw src2) { SLJIT_COMPILE_ASSERT(ICC_IS_SET == SET_FLAGS, icc_is_set_and_set_flags_must_be_the_same); switch (op) { case SLJIT_MOV: - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: + case SLJIT_MOV_U32: + case SLJIT_MOV_S32: case SLJIT_MOV_P: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if (dst != src2) return push_inst(compiler, OR | D(dst) | S1(0) | S2(src2), DR(dst)); return SLJIT_SUCCESS; - case SLJIT_MOV_UB: - case SLJIT_MOV_SB: + case SLJIT_MOV_U8: + case SLJIT_MOV_S8: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_UB) + if (op == SLJIT_MOV_U8) return push_inst(compiler, AND | D(dst) | S1(src2) | IMM(0xff), DR(dst)); FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src2) | IMM(24), DR(dst))); return push_inst(compiler, SRA | D(dst) | S1(dst) | IMM(24), DR(dst)); @@ -63,12 +63,12 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj SLJIT_ASSERT_STOP(); return SLJIT_SUCCESS; - case SLJIT_MOV_UH: - case SLJIT_MOV_SH: + case SLJIT_MOV_U16: + case SLJIT_MOV_S16: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src2) | IMM(16), DR(dst))); - return push_inst(compiler, (op == SLJIT_MOV_SH ? SRA : SRL) | D(dst) | S1(dst) | IMM(16), DR(dst)); + return push_inst(compiler, (op == SLJIT_MOV_S16 ? SRA : SRL) | D(dst) | S1(dst) | IMM(16), DR(dst)); } else if (dst != src2) SLJIT_ASSERT_STOP(); @@ -139,7 +139,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value) +static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value) { FAIL_IF(push_inst(compiler, SETHI | D(dst) | ((init_value >> 10) & 0x3fffff), DR(dst))); return push_inst(compiler, OR | D(dst) | S1(dst) | IMM_ARG | (init_value & 0x3ff), DR(dst)); diff --git a/pcre2-10.21/src/sljit/sljitNativeSPARC_common.c b/pcre2-10.22/src/sljit/sljitNativeSPARC_common.c similarity index 82% rename from pcre2-10.21/src/sljit/sljitNativeSPARC_common.c rename to pcre2-10.22/src/sljit/sljitNativeSPARC_common.c index 327c4267b..f3a33a109 100644 --- a/pcre2-10.21/src/sljit/sljitNativeSPARC_common.c +++ b/pcre2-10.22/src/sljit/sljitNativeSPARC_common.c @@ -24,14 +24,16 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) { return "SPARC" SLJIT_CPUINFO; } /* Length of an instruction word Both for sparc-32 and sparc-64 */ -typedef sljit_ui sljit_ins; +typedef sljit_u32 sljit_ins; + +#if (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL) static void sparc_cache_flush(sljit_ins *from, sljit_ins *to) { @@ -82,6 +84,8 @@ static void sparc_cache_flush(sljit_ins *from, sljit_ins *to) #endif } +#endif /* (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL) */ + /* TMP_REG2 is not used by getput_arg */ #define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) #define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) @@ -91,7 +95,7 @@ static void sparc_cache_flush(sljit_ins *from, sljit_ins *to) #define TMP_FREG1 (0) #define TMP_FREG2 ((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) << 1) -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { +static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { 0, 8, 9, 10, 13, 29, 28, 27, 23, 22, 21, 20, 19, 18, 17, 16, 26, 25, 24, 14, 1, 11, 12, 15 }; @@ -181,7 +185,7 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { /* dest_reg is the absolute name of the register Useful for reordering instructions in the delay slot. */ -static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_si delay_slot) +static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 delay_slot) { sljit_ins *ptr; SLJIT_ASSERT((delay_slot & DST_INS_MASK) == UNMOVABLE_INS @@ -340,7 +344,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!label); SLJIT_ASSERT(!jump); SLJIT_ASSERT(!const_); - SLJIT_ASSERT(code_ptr - code <= (sljit_si)compiler->size); + SLJIT_ASSERT(code_ptr - code <= (sljit_s32)compiler->size); jump = compiler->jumps; while (jump) { @@ -418,9 +422,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #include "sljitNativeSPARC_64.c" #endif -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { CHECK_ERROR(); CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -442,9 +446,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { CHECK_ERROR(); CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -454,7 +458,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { CHECK_ERROR(); CHECK(check_sljit_emit_return(compiler, op, src, srcw)); @@ -478,7 +482,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi #define ARCH_32_64(a, b) b #endif -static SLJIT_CONST sljit_ins data_transfer_insts[16 + 4] = { +static const sljit_ins data_transfer_insts[16 + 4] = { /* u w s */ ARCH_32_64(OPC1(3) | OPC3(0x04) /* stw */, OPC1(3) | OPC3(0x0e) /* stx */), /* u w l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x0b) /* ldx */), /* u b s */ OPC1(3) | OPC3(0x05) /* stb */, @@ -506,7 +510,7 @@ static SLJIT_CONST sljit_ins data_transfer_insts[16 + 4] = { #undef ARCH_32_64 /* Can perform an operation using at most 1 instruction. */ -static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { SLJIT_ASSERT(arg & SLJIT_MEM); @@ -529,7 +533,7 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, /* See getput_arg below. Note: can_cache is called only for binary operators. Those operators always uses word arguments without write back. */ -static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); @@ -549,9 +553,9 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_ } /* Emit the necessary instructions. See can_cache above. */ -static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { - sljit_si base, arg2, delay_slot; + sljit_s32 base, arg2, delay_slot; sljit_ins dest; SLJIT_ASSERT(arg & SLJIT_MEM); @@ -613,7 +617,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji return push_inst(compiler, ADD | D(base) | S1(base) | S2(arg2), DR(base)); } -static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { if (getput_arg_fast(compiler, flags, reg, arg, argw)) return compiler->error; @@ -622,26 +626,26 @@ static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_ return getput_arg(compiler, flags, reg, arg, argw, 0, 0); } -static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w) { if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) return compiler->error; return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); } -static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { /* arg1 goes to TMP_REG1 or src reg arg2 goes to TMP_REG2, imm or src reg TMP_REG3 can be used for caching result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ - sljit_si dst_r = TMP_REG2; - sljit_si src1_r; + sljit_s32 dst_r = TMP_REG2; + sljit_s32 src1_r; sljit_sw src2_r = 0; - sljit_si sugg_src2_r = TMP_REG2; + sljit_s32 sugg_src2_r = TMP_REG2; if (!(flags & ALT_KEEP_CACHE)) { compiler->cache_arg = 0; @@ -649,13 +653,13 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f } if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32 && !(src2 & SLJIT_MEM)) return SLJIT_SUCCESS; } else if (FAST_IS_REG(dst)) { dst_r = dst; flags |= REG_DEST; - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) sugg_src2_r = dst_r; } else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1, dst, dstw)) @@ -705,7 +709,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f if (FAST_IS_REG(src2)) { src2_r = src2; flags |= REG2_SOURCE; - if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) dst_r = src2_r; } else if (src2 & SLJIT_IMM) { @@ -716,7 +720,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f } else { src2_r = 0; - if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) && (dst & SLJIT_MEM)) + if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) && (dst & SLJIT_MEM)) dst_r = 0; } } @@ -758,7 +762,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { CHECK_ERROR(); CHECK(check_sljit_emit_op0(compiler, op)); @@ -769,30 +773,30 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler return push_inst(compiler, TA, UNMOVABLE_INS); case SLJIT_NOP: return push_inst(compiler, NOP, UNMOVABLE_INS); - case SLJIT_LUMUL: - case SLJIT_LSMUL: + case SLJIT_LMUL_UW: + case SLJIT_LMUL_SW: #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - FAIL_IF(push_inst(compiler, (op == SLJIT_LUMUL ? UMUL : SMUL) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0))); + FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? UMUL : SMUL) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0))); return push_inst(compiler, RDY | D(SLJIT_R1), DR(SLJIT_R1)); #else #error "Implementation required" #endif - case SLJIT_UDIVMOD: - case SLJIT_SDIVMOD: - case SLJIT_UDIVI: - case SLJIT_SDIVI: - SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments); + case SLJIT_DIVMOD_UW: + case SLJIT_DIVMOD_SW: + case SLJIT_DIV_UW: + case SLJIT_DIV_SW: + SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments); #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - if ((op | 0x2) == SLJIT_UDIVI) + if ((op | 0x2) == SLJIT_DIV_UW) FAIL_IF(push_inst(compiler, WRY | S1(0), MOVABLE_INS)); else { FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(SLJIT_R0) | IMM(31), DR(TMP_REG1))); FAIL_IF(push_inst(compiler, WRY | S1(TMP_REG1), MOVABLE_INS)); } - if (op <= SLJIT_SDIVMOD) + if (op <= SLJIT_DIVMOD_SW) FAIL_IF(push_inst(compiler, OR | D(TMP_REG2) | S1(0) | S2(SLJIT_R0), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? UDIV : SDIV) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0))); - if (op >= SLJIT_UDIVI) + FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? UDIV : SDIV) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0))); + if (op >= SLJIT_DIV_UW) return SLJIT_SUCCESS; FAIL_IF(push_inst(compiler, SMUL | D(SLJIT_R1) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R1))); return push_inst(compiler, SUB | D(SLJIT_R1) | S1(TMP_REG2) | S2(SLJIT_R1), DR(SLJIT_R1)); @@ -804,11 +808,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0; + sljit_s32 flags = GET_FLAGS(op) ? SET_FLAGS : 0; CHECK_ERROR(); CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); @@ -821,45 +825,45 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler case SLJIT_MOV_P: return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOV_UI: - return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + case SLJIT_MOV_U32: + return emit_op(compiler, SLJIT_MOV_U32, flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOV_SI: - return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + case SLJIT_MOV_S32: + return emit_op(compiler, SLJIT_MOV_S32, flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOV_UB: - return emit_op(compiler, SLJIT_MOV_UB, flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + case SLJIT_MOV_U8: + return emit_op(compiler, SLJIT_MOV_U8, flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw); - case SLJIT_MOV_SB: - return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + case SLJIT_MOV_S8: + return emit_op(compiler, SLJIT_MOV_S8, flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw); - case SLJIT_MOV_UH: - return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + case SLJIT_MOV_U16: + return emit_op(compiler, SLJIT_MOV_U16, flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw); - case SLJIT_MOV_SH: - return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + case SLJIT_MOV_S16: + return emit_op(compiler, SLJIT_MOV_S16, flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw); case SLJIT_MOVU: case SLJIT_MOVU_P: return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOVU_UI: - return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + case SLJIT_MOVU_U32: + return emit_op(compiler, SLJIT_MOV_U32, flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOVU_SI: - return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + case SLJIT_MOVU_S32: + return emit_op(compiler, SLJIT_MOV_S32, flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOVU_UB: - return emit_op(compiler, SLJIT_MOV_UB, flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + case SLJIT_MOVU_U8: + return emit_op(compiler, SLJIT_MOV_U8, flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw); - case SLJIT_MOVU_SB: - return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + case SLJIT_MOVU_S8: + return emit_op(compiler, SLJIT_MOV_S8, flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw); - case SLJIT_MOVU_UH: - return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + case SLJIT_MOVU_U16: + return emit_op(compiler, SLJIT_MOV_U16, flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw); - case SLJIT_MOVU_SH: - return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + case SLJIT_MOVU_S16: + return emit_op(compiler, SLJIT_MOV_S16, flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw); case SLJIT_NOT: case SLJIT_CLZ: @@ -872,12 +876,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0; + sljit_s32 flags = GET_FLAGS(op) ? SET_FLAGS : 0; CHECK_ERROR(); CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -914,20 +918,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_register_index(reg)); return reg_map[reg]; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); return reg << 1; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_s32 size) { CHECK_ERROR(); CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); @@ -939,7 +943,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co /* Floating point operators */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void) { #ifdef SLJIT_IS_FPU_AVAILABLE return SLJIT_IS_FPU_AVAILABLE; @@ -949,13 +953,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) #endif } -#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 7)) -#define SELECT_FOP(op, single, double) ((op & SLJIT_SINGLE_OP) ? single : double) +#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_F32_OP) >> 7)) +#define SELECT_FOP(op, single, double) ((op & SLJIT_F32_OP) ? single : double) #define FLOAT_TMP_MEM_OFFSET (22 * sizeof(sljit_sw)) -static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { if (src & SLJIT_MEM) { FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw)); @@ -978,16 +982,16 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler * return emit_op_mem2(compiler, SINGLE_DATA, TMP_FREG1, dst, dstw, 0, 0); } -static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1; + sljit_s32 dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1; if (src & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) - srcw = (sljit_si)srcw; + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) + srcw = (sljit_s32)srcw; #endif FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); src = TMP_REG1; @@ -1008,9 +1012,9 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler * return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { if (src1 & SLJIT_MEM) { FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); @@ -1029,21 +1033,21 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler return push_inst(compiler, SELECT_FOP(op, FCMPS, FCMPD) | S1A(src1) | S2A(src2), FCC_IS_SET | MOVABLE_INS); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r; + sljit_s32 dst_r; CHECK_ERROR(); compiler->cache_arg = 0; compiler->cache_argw = 0; - SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error); + SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error); SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); - if (GET_OPCODE(op) == SLJIT_CONVD_FROMS) - op ^= SLJIT_SINGLE_OP; + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) + op ^= SLJIT_F32_OP; dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1; @@ -1055,30 +1059,30 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile src <<= 1; switch (GET_OPCODE(op)) { - case SLJIT_DMOV: + case SLJIT_MOV_F64: if (src != dst_r) { if (dst_r != TMP_FREG1) { FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r) | S2A(src), MOVABLE_INS)); - if (!(op & SLJIT_SINGLE_OP)) + if (!(op & SLJIT_F32_OP)) FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS)); } else dst_r = src; } break; - case SLJIT_DNEG: + case SLJIT_NEG_F64: FAIL_IF(push_inst(compiler, FNEGS | DA(dst_r) | S2A(src), MOVABLE_INS)); - if (dst_r != src && !(op & SLJIT_SINGLE_OP)) + if (dst_r != src && !(op & SLJIT_F32_OP)) FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS)); break; - case SLJIT_DABS: + case SLJIT_ABS_F64: FAIL_IF(push_inst(compiler, FABSS | DA(dst_r) | S2A(src), MOVABLE_INS)); - if (dst_r != src && !(op & SLJIT_SINGLE_OP)) + if (dst_r != src && !(op & SLJIT_F32_OP)) FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS)); break; - case SLJIT_CONVD_FROMS: + case SLJIT_CONV_F64_FROM_F32: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOD, FDTOS) | DA(dst_r) | S2A(src), MOVABLE_INS)); - op ^= SLJIT_SINGLE_OP; + op ^= SLJIT_F32_OP; break; } @@ -1087,12 +1091,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si dst_r, flags = 0; + sljit_s32 dst_r, flags = 0; CHECK_ERROR(); CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -1146,19 +1150,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile src2 = TMP_FREG2; switch (GET_OPCODE(op)) { - case SLJIT_DADD: + case SLJIT_ADD_F64: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADDD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS)); break; - case SLJIT_DSUB: + case SLJIT_SUB_F64: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUBD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS)); break; - case SLJIT_DMUL: + case SLJIT_MUL_F64: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMULD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS)); break; - case SLJIT_DDIV: + case SLJIT_DIV_F64: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIVD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS)); break; } @@ -1176,7 +1180,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile /* Other instructions */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); @@ -1193,7 +1197,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c return emit_op_mem(compiler, WORD_DATA, TMP_LINK, dst, dstw); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); @@ -1231,33 +1235,33 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi return label; } -static sljit_ins get_cc(sljit_si type) +static sljit_ins get_cc(sljit_s32 type) { switch (type) { case SLJIT_EQUAL: case SLJIT_MUL_NOT_OVERFLOW: - case SLJIT_D_NOT_EQUAL: /* Unordered. */ + case SLJIT_NOT_EQUAL_F64: /* Unordered. */ return DA(0x1); case SLJIT_NOT_EQUAL: case SLJIT_MUL_OVERFLOW: - case SLJIT_D_EQUAL: + case SLJIT_EQUAL_F64: return DA(0x9); case SLJIT_LESS: - case SLJIT_D_GREATER: /* Unordered. */ + case SLJIT_GREATER_F64: /* Unordered. */ return DA(0x5); case SLJIT_GREATER_EQUAL: - case SLJIT_D_LESS_EQUAL: + case SLJIT_LESS_EQUAL_F64: return DA(0xd); case SLJIT_GREATER: - case SLJIT_D_GREATER_EQUAL: /* Unordered. */ + case SLJIT_GREATER_EQUAL_F64: /* Unordered. */ return DA(0xc); case SLJIT_LESS_EQUAL: - case SLJIT_D_LESS: + case SLJIT_LESS_F64: return DA(0x4); case SLJIT_SIG_LESS: @@ -1273,11 +1277,11 @@ static sljit_ins get_cc(sljit_si type) return DA(0x2); case SLJIT_OVERFLOW: - case SLJIT_D_UNORDERED: + case SLJIT_UNORDERED_F64: return DA(0x7); case SLJIT_NOT_OVERFLOW: - case SLJIT_D_ORDERED: + case SLJIT_ORDERED_F64: return DA(0xf); default: @@ -1286,7 +1290,7 @@ static sljit_ins get_cc(sljit_si type) } } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { struct sljit_jump *jump; @@ -1298,7 +1302,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); type &= 0xff; - if (type < SLJIT_D_EQUAL) { + if (type < SLJIT_EQUAL_F64) { jump->flags |= IS_COND; if (((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) && !(compiler->delay_slot & ICC_IS_SET)) jump->flags |= IS_MOVABLE; @@ -1332,10 +1336,10 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile return jump; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) { struct sljit_jump *jump = NULL; - sljit_si src_r; + sljit_s32 src_r; CHECK_ERROR(); CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); @@ -1367,12 +1371,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil return push_inst(compiler, NOP, UNMOVABLE_INS); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw, + sljit_s32 type) { - sljit_si reg, flags = (GET_FLAGS(op) ? SET_FLAGS : 0); + sljit_s32 reg, flags = (GET_FLAGS(op) ? SET_FLAGS : 0); CHECK_ERROR(); CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type)); @@ -1395,7 +1399,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com } type &= 0xff; - if (type < SLJIT_D_EQUAL) + if (type < SLJIT_EQUAL_F64) FAIL_IF(push_inst(compiler, BICC | get_cc(type) | 3, UNMOVABLE_INS)); else FAIL_IF(push_inst(compiler, FBFCC | get_cc(type) | 3, UNMOVABLE_INS)); @@ -1412,9 +1416,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com #endif } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { - sljit_si reg; + sljit_s32 reg; struct sljit_const *const_; CHECK_ERROR_PTR(); diff --git a/pcre2-10.21/src/sljit/sljitNativeTILEGX-encoder.c b/pcre2-10.22/src/sljit/sljitNativeTILEGX-encoder.c similarity index 100% rename from pcre2-10.21/src/sljit/sljitNativeTILEGX-encoder.c rename to pcre2-10.22/src/sljit/sljitNativeTILEGX-encoder.c diff --git a/pcre2-10.21/src/sljit/sljitNativeTILEGX_64.c b/pcre2-10.22/src/sljit/sljitNativeTILEGX_64.c similarity index 90% rename from pcre2-10.21/src/sljit/sljitNativeTILEGX_64.c rename to pcre2-10.22/src/sljit/sljitNativeTILEGX_64.c index 4d40392fa..462a8b9cd 100644 --- a/pcre2-10.21/src/sljit/sljitNativeTILEGX_64.c +++ b/pcre2-10.22/src/sljit/sljitNativeTILEGX_64.c @@ -49,7 +49,7 @@ #define ADDR_TMP (SLJIT_NUMBER_OF_REGISTERS + 5) #define PIC_ADDR_REG TMP_REG2 -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { +static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { 63, 0, 1, 2, 3, 4, 30, 31, 32, 33, 34, 54, 5, 16, 6, 7 }; @@ -106,7 +106,7 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { */ #define CHECK_FLAGS(list) (!(flags & UNUSED_DEST) || (op & GET_FLAGS(~(list)))) -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char *sljit_get_platform_name(void) +SLJIT_API_FUNC_ATTRIBUTE const char *sljit_get_platform_name(void) { return "TileGX" SLJIT_CPUINFO; } @@ -307,7 +307,7 @@ struct jit_instr { #define JOFF_X1(x) create_JumpOff_X1(x) #define BOFF_X1(x) create_BrOff_X1(x) -static SLJIT_CONST tilegx_mnemonic data_transfer_insts[16] = { +static const tilegx_mnemonic data_transfer_insts[16] = { /* u w s */ TILEGX_OPC_ST /* st */, /* u w l */ TILEGX_OPC_LD /* ld */, /* u b s */ TILEGX_OPC_ST1 /* st1 */, @@ -327,7 +327,7 @@ static SLJIT_CONST tilegx_mnemonic data_transfer_insts[16] = { }; #ifdef TILEGX_JIT_DEBUG -static sljit_si push_inst_debug(struct sljit_compiler *compiler, sljit_ins ins, int line) +static sljit_s32 push_inst_debug(struct sljit_compiler *compiler, sljit_ins ins, int line) { sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); @@ -338,7 +338,7 @@ static sljit_si push_inst_debug(struct sljit_compiler *compiler, sljit_ins ins, return SLJIT_SUCCESS; } -static sljit_si push_inst_nodebug(struct sljit_compiler *compiler, sljit_ins ins) +static sljit_s32 push_inst_nodebug(struct sljit_compiler *compiler, sljit_ins ins) { sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); @@ -349,7 +349,7 @@ static sljit_si push_inst_nodebug(struct sljit_compiler *compiler, sljit_ins ins #define push_inst(a, b) push_inst_debug(a, b, __LINE__) #else -static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins) +static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins) { sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); @@ -557,7 +557,7 @@ const struct Format* compute_format() return match; } -sljit_si assign_pipes() +sljit_s32 assign_pipes() { unsigned long output_registers = 0; unsigned int i = 0; @@ -621,7 +621,7 @@ tilegx_bundle_bits get_bundle_bit(struct jit_instr *inst) return bits; } -static sljit_si update_buffer(struct sljit_compiler *compiler) +static sljit_s32 update_buffer(struct sljit_compiler *compiler) { int i; int orig_index = inst_buf_index; @@ -733,7 +733,7 @@ static sljit_si update_buffer(struct sljit_compiler *compiler) SLJIT_ASSERT_STOP(); } -static sljit_si flush_buffer(struct sljit_compiler *compiler) +static sljit_s32 flush_buffer(struct sljit_compiler *compiler) { while (inst_buf_index != 0) { FAIL_IF(update_buffer(compiler)); @@ -741,7 +741,7 @@ static sljit_si flush_buffer(struct sljit_compiler *compiler) return SLJIT_SUCCESS; } -static sljit_si push_4_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int op3, int line) +static sljit_s32 push_4_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int op3, int line) { if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) FAIL_IF(update_buffer(compiler)); @@ -761,7 +761,7 @@ static sljit_si push_4_buffer(struct sljit_compiler *compiler, tilegx_mnemonic o return SLJIT_SUCCESS; } -static sljit_si push_3_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int line) +static sljit_s32 push_3_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int line) { if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) FAIL_IF(update_buffer(compiler)); @@ -822,7 +822,7 @@ static sljit_si push_3_buffer(struct sljit_compiler *compiler, tilegx_mnemonic o return SLJIT_SUCCESS; } -static sljit_si push_2_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int line) +static sljit_s32 push_2_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int line) { if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) FAIL_IF(update_buffer(compiler)); @@ -867,7 +867,7 @@ static sljit_si push_2_buffer(struct sljit_compiler *compiler, tilegx_mnemonic o return SLJIT_SUCCESS; } -static sljit_si push_0_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int line) +static sljit_s32 push_0_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int line) { if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) FAIL_IF(update_buffer(compiler)); @@ -883,7 +883,7 @@ static sljit_si push_0_buffer(struct sljit_compiler *compiler, tilegx_mnemonic o return SLJIT_SUCCESS; } -static sljit_si push_jr_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int line) +static sljit_s32 push_jr_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int line) { if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) FAIL_IF(update_buffer(compiler)); @@ -1117,7 +1117,7 @@ SLJIT_API_FUNC_ATTRIBUTE void * sljit_generate_code(struct sljit_compiler *compi return code; } -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm) +static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm) { if (imm <= SIMM_16BIT_MAX && imm >= SIMM_16BIT_MIN) @@ -1140,7 +1140,7 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, return SHL16INSLI(dst_ar, dst_ar, imm); } -static sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm, int flush) +static sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm, int flush) { /* Should *not* be optimized as load_immediate, as pcre relocation mechanism will match this fixed 4-instruction pattern. */ @@ -1155,7 +1155,7 @@ static sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst_ar, slj return SHL16INSLI(dst_ar, dst_ar, imm); } -static sljit_si emit_const_64(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm, int flush) +static sljit_s32 emit_const_64(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm, int flush) { /* Should *not* be optimized as load_immediate, as pcre relocation mechanism will match this fixed 4-instruction pattern. */ @@ -1172,12 +1172,12 @@ static sljit_si emit_const_64(struct sljit_compiler *compiler, sljit_si dst_ar, return SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { sljit_ins base; - sljit_si i, tmp; + sljit_s32 i, tmp; CHECK_ERROR(); CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -1222,9 +1222,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { CHECK_ERROR(); CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -1236,12 +1236,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { - sljit_si local_size; + sljit_s32 local_size; sljit_ins base; - sljit_si i, tmp; - sljit_si saveds; + sljit_s32 i, tmp; + sljit_s32 saveds; CHECK_ERROR(); CHECK(check_sljit_emit_return(compiler, op, src, srcw)); @@ -1285,7 +1285,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi /* reg_ar is an absoulute register! */ /* Can perform an operation using at most 1 instruction. */ -static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw) +static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw) { SLJIT_ASSERT(arg & SLJIT_MEM); @@ -1311,7 +1311,7 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, /* See getput_arg below. Note: can_cache is called only for binary operators. Those operators always uses word arguments without write back. */ -static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); @@ -1337,9 +1337,9 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_ } /* Emit the necessary instructions. See can_cache above. */ -static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { - sljit_si tmp_ar, base; + sljit_s32 tmp_ar, base; SLJIT_ASSERT(arg & SLJIT_MEM); if (!(next_arg & SLJIT_MEM)) { @@ -1530,7 +1530,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar); } -static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw) +static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw) { if (getput_arg_fast(compiler, flags, reg_ar, arg, argw)) return compiler->error; @@ -1540,14 +1540,14 @@ static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_ return getput_arg(compiler, flags, reg_ar, arg, argw, 0, 0); } -static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w) { if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) return compiler->error; return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); @@ -1564,7 +1564,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c return emit_op_mem(compiler, WORD_DATA, RA, dst, dstw); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); @@ -1582,9 +1582,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * return JR(RA); } -static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, sljit_si dst, sljit_si src1, sljit_sw src2) +static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, sljit_s32 dst, sljit_s32 src1, sljit_sw src2) { - sljit_si overflow_ra = 0; + sljit_s32 overflow_ra = 0; switch (GET_OPCODE(op)) { case SLJIT_MOV: @@ -1594,11 +1594,11 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj return ADD(reg_map[dst], reg_map[src2], ZERO); return SLJIT_SUCCESS; - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: + case SLJIT_MOV_U32: + case SLJIT_MOV_S32: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SI) + if (op == SLJIT_MOV_S32) return BFEXTS(reg_map[dst], reg_map[src2], 0, 31); return BFEXTU(reg_map[dst], reg_map[src2], 0, 31); @@ -1609,11 +1609,11 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj return SLJIT_SUCCESS; - case SLJIT_MOV_UB: - case SLJIT_MOV_SB: + case SLJIT_MOV_U8: + case SLJIT_MOV_S8: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SB) + if (op == SLJIT_MOV_S8) return BFEXTS(reg_map[dst], reg_map[src2], 0, 7); return BFEXTU(reg_map[dst], reg_map[src2], 0, 7); @@ -1624,11 +1624,11 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj return SLJIT_SUCCESS; - case SLJIT_MOV_UH: - case SLJIT_MOV_SH: + case SLJIT_MOV_U16: + case SLJIT_MOV_S16: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SH) + if (op == SLJIT_MOV_S16) return BFEXTS(reg_map[dst], reg_map[src2], 0, 15); return BFEXTU(reg_map[dst], reg_map[src2], 0, 15); @@ -1956,16 +1956,16 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj return SLJIT_SUCCESS; } -static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, sljit_si dst, sljit_sw dstw, sljit_si src1, sljit_sw src1w, sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, sljit_s32 dst, sljit_sw dstw, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w) { /* arg1 goes to TMP_REG1 or src reg. arg2 goes to TMP_REG2, imm or src reg. TMP_REG3 can be used for caching. result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ - sljit_si dst_r = TMP_REG2; - sljit_si src1_r; + sljit_s32 dst_r = TMP_REG2; + sljit_s32 src1_r; sljit_sw src2_r = 0; - sljit_si sugg_src2_r = TMP_REG2; + sljit_s32 sugg_src2_r = TMP_REG2; if (!(flags & ALT_KEEP_CACHE)) { compiler->cache_arg = 0; @@ -1973,14 +1973,14 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f } if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32 && !(src2 & SLJIT_MEM)) return SLJIT_SUCCESS; if (GET_FLAGS(op)) flags |= UNUSED_DEST; } else if (FAST_IS_REG(dst)) { dst_r = dst; flags |= REG_DEST; - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) sugg_src2_r = dst_r; } else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1_mapped, dst, dstw)) flags |= SLOW_DEST; @@ -2033,7 +2033,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f if (FAST_IS_REG(src2)) { src2_r = src2; flags |= REG2_SOURCE; - if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) dst_r = src2_r; } else if (src2 & SLJIT_IMM) { if (!(flags & SRC2_IMM)) { @@ -2042,7 +2042,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f src2_r = sugg_src2_r; } else { src2_r = 0; - if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) && (dst & SLJIT_MEM)) + if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) && (dst & SLJIT_MEM)) dst_r = 0; } } @@ -2082,11 +2082,11 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src, sljit_sw srcw, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw, sljit_s32 type) { - sljit_si sugg_dst_ar, dst_ar; - sljit_si flags = GET_ALL_FLAGS(op); - sljit_si mem_type = (op & SLJIT_INT_OP) ? (INT_DATA | SIGNED_DATA) : WORD_DATA; + sljit_s32 sugg_dst_ar, dst_ar; + sljit_s32 flags = GET_ALL_FLAGS(op); + sljit_s32 mem_type = (op & SLJIT_I32_OP) ? (INT_DATA | SIGNED_DATA) : WORD_DATA; CHECK_ERROR(); CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type)); @@ -2096,7 +2096,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com return SLJIT_SUCCESS; op = GET_OPCODE(op); - if (op == SLJIT_MOV_SI || op == SLJIT_MOV_UI) + if (op == SLJIT_MOV_S32 || op == SLJIT_MOV_U32) mem_type = INT_DATA | SIGNED_DATA; sugg_dst_ar = reg_map[(op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2]; @@ -2168,7 +2168,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) { +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { CHECK_ERROR(); CHECK(check_sljit_emit_op0(compiler, op)); @@ -2180,17 +2180,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler case SLJIT_BREAKPOINT: return PI(BPT); - case SLJIT_LUMUL: - case SLJIT_LSMUL: - case SLJIT_UDIVI: - case SLJIT_SDIVI: + case SLJIT_LMUL_UW: + case SLJIT_LMUL_SW: + case SLJIT_DIVMOD_UW: + case SLJIT_DIVMOD_SW: + case SLJIT_DIV_UW: + case SLJIT_DIV_SW: SLJIT_ASSERT_STOP(); } return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) { CHECK_ERROR(); CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); @@ -2202,45 +2204,45 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler case SLJIT_MOV_P: return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOV_UI: - return emit_op(compiler, SLJIT_MOV_UI, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + case SLJIT_MOV_U32: + return emit_op(compiler, SLJIT_MOV_U32, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOV_SI: - return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + case SLJIT_MOV_S32: + return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOV_UB: - return emit_op(compiler, SLJIT_MOV_UB, BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub) srcw : srcw); + case SLJIT_MOV_U8: + return emit_op(compiler, SLJIT_MOV_U8, BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8) srcw : srcw); - case SLJIT_MOV_SB: - return emit_op(compiler, SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb) srcw : srcw); + case SLJIT_MOV_S8: + return emit_op(compiler, SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8) srcw : srcw); - case SLJIT_MOV_UH: - return emit_op(compiler, SLJIT_MOV_UH, HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh) srcw : srcw); + case SLJIT_MOV_U16: + return emit_op(compiler, SLJIT_MOV_U16, HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16) srcw : srcw); - case SLJIT_MOV_SH: - return emit_op(compiler, SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh) srcw : srcw); + case SLJIT_MOV_S16: + return emit_op(compiler, SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16) srcw : srcw); case SLJIT_MOVU: case SLJIT_MOVU_P: return emit_op(compiler, SLJIT_MOV, WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOVU_UI: - return emit_op(compiler, SLJIT_MOV_UI, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + case SLJIT_MOVU_U32: + return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOVU_SI: - return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + case SLJIT_MOVU_S32: + return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOVU_UB: - return emit_op(compiler, SLJIT_MOV_UB, BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub) srcw : srcw); + case SLJIT_MOVU_U8: + return emit_op(compiler, SLJIT_MOV_U8, BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8) srcw : srcw); - case SLJIT_MOVU_SB: - return emit_op(compiler, SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb) srcw : srcw); + case SLJIT_MOVU_S8: + return emit_op(compiler, SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8) srcw : srcw); - case SLJIT_MOVU_UH: - return emit_op(compiler, SLJIT_MOV_UH, HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh) srcw : srcw); + case SLJIT_MOVU_U16: + return emit_op(compiler, SLJIT_MOV_U16, HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16) srcw : srcw); - case SLJIT_MOVU_SH: - return emit_op(compiler, SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh) srcw : srcw); + case SLJIT_MOVU_S16: + return emit_op(compiler, SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16) srcw : srcw); case SLJIT_NOT: return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw); @@ -2249,13 +2251,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler return emit_op(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw); case SLJIT_CLZ: - return emit_op(compiler, op, (op & SLJIT_INT_OP) ? INT_DATA : WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, op, (op & SLJIT_I32_OP) ? INT_DATA : WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); } return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src1, sljit_sw src1w, sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w) { CHECK_ERROR(); CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -2285,7 +2287,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler case SLJIT_ASHR: if (src2 & SLJIT_IMM) src2w &= 0x3f; - if (op & SLJIT_INT_OP) + if (op & SLJIT_I32_OP) src2w &= 0x1f; return emit_op(compiler, op, IMM_OP, dst, dstw, src1, src1w, src2, src2w); @@ -2312,9 +2314,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label * sljit_emit_label(struct sljit_comp return label; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) { - sljit_si src_r = TMP_REG2; + sljit_s32 src_r = TMP_REG2; struct sljit_jump *jump = NULL; flush_buffer(compiler); @@ -2401,11 +2403,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil inst = BNEZ_X1 | SRCA_X1(src); \ flags = IS_COND; -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { struct sljit_jump *jump; sljit_ins inst; - sljit_si flags = 0; + sljit_s32 flags = 0; flush_buffer(compiler); @@ -2485,25 +2487,25 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_jump(struct sljit_compil return jump; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void) { return 0; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) { SLJIT_ASSERT_STOP(); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src1, sljit_sw src1w, sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w) { SLJIT_ASSERT_STOP(); } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const * sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const * sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; - sljit_si reg; + sljit_s32 reg; flush_buffer(compiler); @@ -2545,14 +2547,14 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta SLJIT_CACHE_FLUSH(inst, inst + 4); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_register_index(reg)); return reg_map[reg]; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_s32 size) { CHECK_ERROR(); CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); diff --git a/pcre2-10.21/src/sljit/sljitNativeX86_32.c b/pcre2-10.22/src/sljit/sljitNativeX86_32.c similarity index 84% rename from pcre2-10.21/src/sljit/sljitNativeX86_32.c rename to pcre2-10.22/src/sljit/sljitNativeX86_32.c index d7129c8e2..78f3dcb06 100644 --- a/pcre2-10.21/src/sljit/sljitNativeX86_32.c +++ b/pcre2-10.22/src/sljit/sljitNativeX86_32.c @@ -26,19 +26,19 @@ /* x86 32-bit arch dependent functions. */ -static sljit_si emit_do_imm(struct sljit_compiler *compiler, sljit_ub opcode, sljit_sw imm) +static sljit_s32 emit_do_imm(struct sljit_compiler *compiler, sljit_u8 opcode, sljit_sw imm) { - sljit_ub *inst; + sljit_u8 *inst; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_sw)); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_sw)); FAIL_IF(!inst); INC_SIZE(1 + sizeof(sljit_sw)); *inst++ = opcode; - *(sljit_sw*)inst = imm; + sljit_unaligned_store_sw(inst, imm); return SLJIT_SUCCESS; } -static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type) +static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type) { if (type == SLJIT_JUMP) { *code_ptr++ = JMP_i32; @@ -57,18 +57,18 @@ static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ if (jump->flags & JUMP_LABEL) jump->flags |= PATCH_MW; else - *(sljit_sw*)code_ptr = jump->u.target - (jump->addr + 4); + sljit_unaligned_store_sw(code_ptr, jump->u.target - (jump->addr + 4)); code_ptr += 4; return code_ptr; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_si size; - sljit_ub *inst; + sljit_s32 size; + sljit_u8 *inst; CHECK_ERROR(); CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -83,7 +83,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil #else size += (args > 0 ? (2 + args * 3) : 0); #endif - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); INC_SIZE(size); @@ -143,7 +143,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil if (options & SLJIT_DOUBLE_ALIGNMENT) { local_size = SLJIT_LOCALS_OFFSET + ((local_size + 7) & ~7); - inst = (sljit_ub*)ensure_buf(compiler, 1 + 17); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 17); FAIL_IF(!inst); INC_SIZE(17); @@ -151,12 +151,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil inst[1] = MOD_REG | (reg_map[TMP_REG1] << 3) | reg_map[SLJIT_SP]; inst[2] = GROUP_F7; inst[3] = MOD_REG | (0 << 3) | reg_map[SLJIT_SP]; - *(sljit_sw*)(inst + 4) = 0x4; + sljit_unaligned_store_sw(inst + 4, 0x4); inst[8] = JNE_i8; inst[9] = 6; inst[10] = GROUP_BINARY_81; inst[11] = MOD_REG | (5 << 3) | reg_map[SLJIT_SP]; - *(sljit_sw*)(inst + 12) = 0x4; + sljit_unaligned_store_sw(inst + 12, 0x4); inst[16] = PUSH_r + reg_map[TMP_REG1]; } else @@ -183,9 +183,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { CHECK_ERROR(); CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -205,10 +205,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { - sljit_si size; - sljit_ub *inst; + sljit_s32 size; + sljit_u8 *inst; CHECK_ERROR(); CHECK(check_sljit_emit_return(compiler, op, src, srcw)); @@ -223,7 +223,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi #if !defined(__APPLE__) if (compiler->options & SLJIT_DOUBLE_ALIGNMENT) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 3); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 3); FAIL_IF(!inst); INC_SIZE(3); @@ -242,7 +242,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi if (compiler->args > 0) size += 2; #endif - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); INC_SIZE(size); @@ -271,16 +271,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi /* --------------------------------------------------------------------- */ /* Size contains the flags as well. */ -static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si size, +static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_s32 size, /* The register or immediate operand. */ - sljit_si a, sljit_sw imma, + sljit_s32 a, sljit_sw imma, /* The general operand (not immediate). */ - sljit_si b, sljit_sw immb) + sljit_s32 b, sljit_sw immb) { - sljit_ub *inst; - sljit_ub *buf_ptr; - sljit_si flags = size & ~0xf; - sljit_si inst_size; + sljit_u8 *inst; + sljit_u8 *buf_ptr; + sljit_s32 flags = size & ~0xf; + sljit_s32 inst_size; /* Both cannot be switched on. */ SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS)); @@ -310,7 +310,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si else if (immb != 0 && !(b & OFFS_REG_MASK)) { /* Immediate operand. */ if (immb <= 127 && immb >= -128) - inst_size += sizeof(sljit_sb); + inst_size += sizeof(sljit_s8); else inst_size += sizeof(sljit_sw); } @@ -347,7 +347,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si else SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG); - inst = (sljit_ub*)ensure_buf(compiler, 1 + inst_size); + inst = (sljit_u8*)ensure_buf(compiler, 1 + inst_size); PTR_FAIL_IF(!inst); /* Encoding the byte. */ @@ -406,7 +406,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si if (immb <= 127 && immb >= -128) *buf_ptr++ = immb; /* 8 bit displacement. */ else { - *(sljit_sw*)buf_ptr = immb; /* 32 bit displacement. */ + sljit_unaligned_store_sw(buf_ptr, immb); /* 32 bit displacement. */ buf_ptr += sizeof(sljit_sw); } } @@ -418,7 +418,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si } else { *buf_ptr++ |= 0x05; - *(sljit_sw*)buf_ptr = immb; /* 32 bit displacement. */ + sljit_unaligned_store_sw(buf_ptr, immb); /* 32 bit displacement. */ buf_ptr += sizeof(sljit_sw); } @@ -426,9 +426,9 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si if (flags & EX86_BYTE_ARG) *buf_ptr = imma; else if (flags & EX86_HALF_ARG) - *(short*)buf_ptr = imma; + sljit_unaligned_store_s16(buf_ptr, imma); else if (!(flags & EX86_SHIFT_INS)) - *(sljit_sw*)buf_ptr = imma; + sljit_unaligned_store_sw(buf_ptr, imma); } return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1); @@ -438,12 +438,12 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si /* Call / return instructions */ /* --------------------------------------------------------------------- */ -static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, sljit_si type) +static SLJIT_INLINE sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 type) { - sljit_ub *inst; + sljit_u8 *inst; #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) - inst = (sljit_ub*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2); + inst = (sljit_u8*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2); FAIL_IF(!inst); INC_SIZE(type >= SLJIT_CALL3 ? 2 + 1 : 2); @@ -452,7 +452,7 @@ static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, slj *inst++ = MOV_r_rm; *inst++ = MOD_REG | (reg_map[SLJIT_R2] << 3) | reg_map[SLJIT_R0]; #else - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 * (type - SLJIT_CALL0)); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 * (type - SLJIT_CALL0)); FAIL_IF(!inst); INC_SIZE(4 * (type - SLJIT_CALL0)); @@ -476,9 +476,9 @@ static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, slj return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { - sljit_ub *inst; + sljit_u8 *inst; CHECK_ERROR(); CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); @@ -492,7 +492,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c if (FAST_IS_REG(dst)) { /* Unused dest is possible here. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); INC_SIZE(1); @@ -507,9 +507,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) { - sljit_ub *inst; + sljit_u8 *inst; CHECK_ERROR(); CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); @@ -518,7 +518,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * CHECK_EXTRA_REGS(src, srcw, (void)0); if (FAST_IS_REG(src)) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 1); FAIL_IF(!inst); INC_SIZE(1 + 1); @@ -530,18 +530,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * *inst++ = GROUP_FF; *inst |= PUSH_rm; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); INC_SIZE(1); } else { /* SLJIT_IMM. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 5 + 1); FAIL_IF(!inst); INC_SIZE(5 + 1); *inst++ = PUSH_i32; - *(sljit_sw*)inst = srcw; + sljit_unaligned_store_sw(inst, srcw); inst += sizeof(sljit_sw); } diff --git a/pcre2-10.21/src/sljit/sljitNativeX86_64.c b/pcre2-10.22/src/sljit/sljitNativeX86_64.c similarity index 79% rename from pcre2-10.21/src/sljit/sljitNativeX86_64.c rename to pcre2-10.22/src/sljit/sljitNativeX86_64.c index 1790d8a4d..e88ddedcd 100644 --- a/pcre2-10.21/src/sljit/sljitNativeX86_64.c +++ b/pcre2-10.22/src/sljit/sljitNativeX86_64.c @@ -26,20 +26,20 @@ /* x86 64-bit arch dependent functions. */ -static sljit_si emit_load_imm64(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm) +static sljit_s32 emit_load_imm64(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm) { - sljit_ub *inst; + sljit_u8 *inst; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_sw)); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_sw)); FAIL_IF(!inst); INC_SIZE(2 + sizeof(sljit_sw)); *inst++ = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B); *inst++ = MOV_r_i32 + (reg_map[reg] & 0x7); - *(sljit_sw*)inst = imm; + sljit_unaligned_store_sw(inst, imm); return SLJIT_SUCCESS; } -static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type) +static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type) { if (type < SLJIT_JUMP) { /* Invert type. */ @@ -55,7 +55,7 @@ static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ if (jump->flags & JUMP_LABEL) jump->flags |= PATCH_MD; else - *(sljit_sw*)code_ptr = jump->u.target; + sljit_unaligned_store_sw(code_ptr, jump->u.target); code_ptr += sizeof(sljit_sw); *code_ptr++ = REX_B; @@ -65,19 +65,19 @@ static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ return code_ptr; } -static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_sw addr, sljit_si type) +static sljit_u8* generate_fixed_jump(sljit_u8 *code_ptr, sljit_sw addr, sljit_s32 type) { - sljit_sw delta = addr - ((sljit_sw)code_ptr + 1 + sizeof(sljit_si)); + sljit_sw delta = addr - ((sljit_sw)code_ptr + 1 + sizeof(sljit_s32)); if (delta <= HALFWORD_MAX && delta >= HALFWORD_MIN) { *code_ptr++ = (type == 2) ? CALL_i32 : JMP_i32; - *(sljit_sw*)code_ptr = delta; + sljit_unaligned_store_sw(code_ptr, delta); } else { SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_second); *code_ptr++ = REX_W | REX_B; *code_ptr++ = MOV_r_i32 + 1; - *(sljit_sw*)code_ptr = addr; + sljit_unaligned_store_sw(code_ptr, addr); code_ptr += sizeof(sljit_sw); *code_ptr++ = REX_B; *code_ptr++ = GROUP_FF; @@ -87,12 +87,12 @@ static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_sw addr, sljit_si return code_ptr; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_si i, tmp, size, saved_register_size; - sljit_ub *inst; + sljit_s32 i, tmp, size, saved_register_size; + sljit_u8 *inst; CHECK_ERROR(); CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -106,7 +106,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; for (i = SLJIT_S0; i >= tmp; i--) { size = reg_map[i] >= 8 ? 2 : 1; - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); INC_SIZE(size); if (reg_map[i] >= 8) @@ -116,7 +116,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { size = reg_map[i] >= 8 ? 2 : 1; - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); INC_SIZE(size); if (reg_map[i] >= 8) @@ -126,7 +126,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil if (args > 0) { size = args * 3; - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); INC_SIZE(size); @@ -172,9 +172,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil #ifdef _WIN64 if (local_size > 1024) { /* Allocate stack for the callback, which grows the stack. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + (3 + sizeof(sljit_si))); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 + (3 + sizeof(sljit_s32))); FAIL_IF(!inst); - INC_SIZE(4 + (3 + sizeof(sljit_si))); + INC_SIZE(4 + (3 + sizeof(sljit_s32))); *inst++ = REX_W; *inst++ = GROUP_BINARY_83; *inst++ = MOD_REG | SUB | 4; @@ -193,7 +193,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil *inst++ = REX_W; *inst++ = MOV_rm_i32; *inst++ = MOD_REG | reg_lmap[SLJIT_R0]; - *(sljit_si*)inst = local_size; + sljit_unaligned_store_s32(inst, local_size); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) compiler->skip_checks = 1; @@ -204,7 +204,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil SLJIT_ASSERT(local_size > 0); if (local_size <= 127) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); FAIL_IF(!inst); INC_SIZE(4); *inst++ = REX_W; @@ -213,35 +213,35 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil *inst++ = local_size; } else { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 7); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 7); FAIL_IF(!inst); INC_SIZE(7); *inst++ = REX_W; *inst++ = GROUP_BINARY_81; *inst++ = MOD_REG | SUB | 4; - *(sljit_si*)inst = local_size; - inst += sizeof(sljit_si); + sljit_unaligned_store_s32(inst, local_size); + inst += sizeof(sljit_s32); } #ifdef _WIN64 /* Save xmm6 register: movaps [rsp + 0x20], xmm6 */ if (fscratches >= 6 || fsaveds >= 1) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 5); FAIL_IF(!inst); INC_SIZE(5); *inst++ = GROUP_0F; - *(sljit_si*)inst = 0x20247429; + sljit_unaligned_store_s32(inst, 0x20247429); } #endif return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_si saved_register_size; + sljit_s32 saved_register_size; CHECK_ERROR(); CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -253,10 +253,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { - sljit_si i, tmp, size; - sljit_ub *inst; + sljit_s32 i, tmp, size; + sljit_u8 *inst; CHECK_ERROR(); CHECK(check_sljit_emit_return(compiler, op, src, srcw)); @@ -267,17 +267,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi #ifdef _WIN64 /* Restore xmm6 register: movaps xmm6, [rsp + 0x20] */ if (compiler->fscratches >= 6 || compiler->fsaveds >= 1) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 5); FAIL_IF(!inst); INC_SIZE(5); *inst++ = GROUP_0F; - *(sljit_si*)inst = 0x20247428; + sljit_unaligned_store_s32(inst, 0x20247428); } #endif SLJIT_ASSERT(compiler->local_size > 0); if (compiler->local_size <= 127) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); FAIL_IF(!inst); INC_SIZE(4); *inst++ = REX_W; @@ -286,19 +286,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi *inst = compiler->local_size; } else { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 7); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 7); FAIL_IF(!inst); INC_SIZE(7); *inst++ = REX_W; *inst++ = GROUP_BINARY_81; *inst++ = MOD_REG | ADD | 4; - *(sljit_si*)inst = compiler->local_size; + sljit_unaligned_store_s32(inst, compiler->local_size); } tmp = compiler->scratches; for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) { size = reg_map[i] >= 8 ? 2 : 1; - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); INC_SIZE(size); if (reg_map[i] >= 8) @@ -309,7 +309,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG; for (i = tmp; i <= SLJIT_S0; i++) { size = reg_map[i] >= 8 ? 2 : 1; - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); INC_SIZE(size); if (reg_map[i] >= 8) @@ -317,7 +317,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi POP_REG(reg_lmap[i]); } - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); INC_SIZE(1); RET(); @@ -328,32 +328,32 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi /* Operators */ /* --------------------------------------------------------------------- */ -static sljit_si emit_do_imm32(struct sljit_compiler *compiler, sljit_ub rex, sljit_ub opcode, sljit_sw imm) +static sljit_s32 emit_do_imm32(struct sljit_compiler *compiler, sljit_u8 rex, sljit_u8 opcode, sljit_sw imm) { - sljit_ub *inst; - sljit_si length = 1 + (rex ? 1 : 0) + sizeof(sljit_si); + sljit_u8 *inst; + sljit_s32 length = 1 + (rex ? 1 : 0) + sizeof(sljit_s32); - inst = (sljit_ub*)ensure_buf(compiler, 1 + length); + inst = (sljit_u8*)ensure_buf(compiler, 1 + length); FAIL_IF(!inst); INC_SIZE(length); if (rex) *inst++ = rex; *inst++ = opcode; - *(sljit_si*)inst = imm; + sljit_unaligned_store_s32(inst, imm); return SLJIT_SUCCESS; } -static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si size, +static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_s32 size, /* The register or immediate operand. */ - sljit_si a, sljit_sw imma, + sljit_s32 a, sljit_sw imma, /* The general operand (not immediate). */ - sljit_si b, sljit_sw immb) + sljit_s32 b, sljit_sw immb) { - sljit_ub *inst; - sljit_ub *buf_ptr; - sljit_ub rex = 0; - sljit_si flags = size & ~0xf; - sljit_si inst_size; + sljit_u8 *inst; + sljit_u8 *buf_ptr; + sljit_u8 rex = 0; + sljit_s32 flags = size & ~0xf; + sljit_s32 inst_size; /* The immediate operand must be 32 bit. */ SLJIT_ASSERT(!(a & SLJIT_IMM) || compiler->mode32 || IS_HALFWORD(imma)); @@ -400,7 +400,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si } if ((b & REG_MASK) == SLJIT_UNUSED) - inst_size += 1 + sizeof(sljit_si); /* SIB byte required to avoid RIP based addressing. */ + inst_size += 1 + sizeof(sljit_s32); /* SIB byte required to avoid RIP based addressing. */ else { if (reg_map[b & REG_MASK] >= 8) rex |= REX_B; @@ -408,12 +408,12 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si if (immb != 0 && (!(b & OFFS_REG_MASK) || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP))) { /* Immediate operand. */ if (immb <= 127 && immb >= -128) - inst_size += sizeof(sljit_sb); + inst_size += sizeof(sljit_s8); else - inst_size += sizeof(sljit_si); + inst_size += sizeof(sljit_s32); } else if (reg_lmap[b & REG_MASK] == 5) - inst_size += sizeof(sljit_sb); + inst_size += sizeof(sljit_s8); if ((b & OFFS_REG_MASK) != SLJIT_UNUSED) { inst_size += 1; /* SIB byte. */ @@ -444,7 +444,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si else if (flags & EX86_HALF_ARG) inst_size += sizeof(short); else - inst_size += sizeof(sljit_si); + inst_size += sizeof(sljit_s32); } else { SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG); @@ -456,7 +456,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si if (rex) inst_size++; - inst = (sljit_ub*)ensure_buf(compiler, 1 + inst_size); + inst = (sljit_u8*)ensure_buf(compiler, 1 + inst_size); PTR_FAIL_IF(!inst); /* Encoding the byte. */ @@ -516,8 +516,8 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si if (immb <= 127 && immb >= -128) *buf_ptr++ = immb; /* 8 bit displacement. */ else { - *(sljit_si*)buf_ptr = immb; /* 32 bit displacement. */ - buf_ptr += sizeof(sljit_si); + sljit_unaligned_store_s32(buf_ptr, immb); /* 32 bit displacement. */ + buf_ptr += sizeof(sljit_s32); } } } @@ -533,17 +533,17 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si else { *buf_ptr++ |= 0x04; *buf_ptr++ = 0x25; - *(sljit_si*)buf_ptr = immb; /* 32 bit displacement. */ - buf_ptr += sizeof(sljit_si); + sljit_unaligned_store_s32(buf_ptr, immb); /* 32 bit displacement. */ + buf_ptr += sizeof(sljit_s32); } if (a & SLJIT_IMM) { if (flags & EX86_BYTE_ARG) *buf_ptr = imma; else if (flags & EX86_HALF_ARG) - *(short*)buf_ptr = imma; + sljit_unaligned_store_s16(buf_ptr, imma); else if (!(flags & EX86_SHIFT_INS)) - *(sljit_si*)buf_ptr = imma; + sljit_unaligned_store_s32(buf_ptr, imma); } return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1); @@ -553,14 +553,14 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si /* Call / return instructions */ /* --------------------------------------------------------------------- */ -static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, sljit_si type) +static SLJIT_INLINE sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 type) { - sljit_ub *inst; + sljit_u8 *inst; #ifndef _WIN64 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R1] == 6 && reg_map[SLJIT_R0] < 8 && reg_map[SLJIT_R2] < 8, args_registers); - inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6)); + inst = (sljit_u8*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6)); FAIL_IF(!inst); INC_SIZE((type < SLJIT_CALL3) ? 3 : 6); if (type >= SLJIT_CALL3) { @@ -574,7 +574,7 @@ static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, slj #else SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R1] == 2 && reg_map[SLJIT_R0] < 8 && reg_map[SLJIT_R2] < 8, args_registers); - inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6)); + inst = (sljit_u8*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6)); FAIL_IF(!inst); INC_SIZE((type < SLJIT_CALL3) ? 3 : 6); if (type >= SLJIT_CALL3) { @@ -589,9 +589,9 @@ static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, slj return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { - sljit_ub *inst; + sljit_u8 *inst; CHECK_ERROR(); CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); @@ -603,14 +603,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c if (FAST_IS_REG(dst)) { if (reg_map[dst] < 8) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); INC_SIZE(1); POP_REG(reg_lmap[dst]); return SLJIT_SUCCESS; } - inst = (sljit_ub*)ensure_buf(compiler, 1 + 2); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); FAIL_IF(!inst); INC_SIZE(2); *inst++ = REX_B; @@ -626,9 +626,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) { - sljit_ub *inst; + sljit_u8 *inst; CHECK_ERROR(); CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); @@ -641,14 +641,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * if (FAST_IS_REG(src)) { if (reg_map[src] < 8) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 1); FAIL_IF(!inst); INC_SIZE(1 + 1); PUSH_REG(reg_lmap[src]); } else { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2 + 1); FAIL_IF(!inst); INC_SIZE(2 + 1); @@ -664,20 +664,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * *inst++ = GROUP_FF; *inst |= PUSH_rm; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); INC_SIZE(1); } else { SLJIT_ASSERT(IS_HALFWORD(srcw)); /* SLJIT_IMM. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 5 + 1); FAIL_IF(!inst); INC_SIZE(5 + 1); *inst++ = PUSH_i32; - *(sljit_si*)inst = srcw; - inst += sizeof(sljit_si); + sljit_unaligned_store_s32(inst, srcw); + inst += sizeof(sljit_s32); } RET(); @@ -689,12 +689,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * /* Extend input */ /* --------------------------------------------------------------------- */ -static sljit_si emit_mov_int(struct sljit_compiler *compiler, sljit_si sign, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static sljit_s32 emit_mov_int(struct sljit_compiler *compiler, sljit_s32 sign, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_ub* inst; - sljit_si dst_r; + sljit_u8* inst; + sljit_s32 dst_r; compiler->mode32 = 0; @@ -704,7 +704,7 @@ static sljit_si emit_mov_int(struct sljit_compiler *compiler, sljit_si sign, if (src & SLJIT_IMM) { if (FAST_IS_REG(dst)) { if (sign || ((sljit_uw)srcw <= 0x7fffffff)) { - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw); + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_s32)srcw, dst, dstw); FAIL_IF(!inst); *inst = MOV_rm_i32; return SLJIT_SUCCESS; @@ -712,7 +712,7 @@ static sljit_si emit_mov_int(struct sljit_compiler *compiler, sljit_si sign, return emit_load_imm64(compiler, dst, srcw); } compiler->mode32 = 1; - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw); + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_s32)srcw, dst, dstw); FAIL_IF(!inst); *inst = MOV_rm_i32; compiler->mode32 = 0; diff --git a/pcre2-10.21/src/sljit/sljitNativeX86_common.c b/pcre2-10.22/src/sljit/sljitNativeX86_common.c similarity index 79% rename from pcre2-10.21/src/sljit/sljitNativeX86_common.c rename to pcre2-10.22/src/sljit/sljitNativeX86_common.c index 416c15afa..aa5ba089d 100644 --- a/pcre2-10.21/src/sljit/sljitNativeX86_common.c +++ b/pcre2-10.22/src/sljit/sljitNativeX86_common.c @@ -24,7 +24,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) { return "x86" SLJIT_CPUINFO; } @@ -66,7 +66,7 @@ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) /* Last register + 1. */ #define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 3] = { +static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 3] = { 0, 0, 2, 1, 0, 0, 0, 0, 7, 6, 3, 4, 5 }; @@ -89,20 +89,20 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 3] = { therefore r12 is better for SAVED_EREG than SAVED_REG. */ #ifndef _WIN64 /* 1st passed in rdi, 2nd argument passed in rsi, 3rd in rdx. */ -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { +static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { 0, 0, 6, 1, 8, 11, 10, 12, 5, 13, 14, 15, 3, 4, 2, 7, 9 }; /* low-map. reg_map & 0x7. */ -static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 5] = { +static const sljit_u8 reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 5] = { 0, 0, 6, 1, 0, 3, 2, 4, 5, 5, 6, 7, 3, 4, 2, 7, 1 }; #else /* 1st passed in rcx, 2nd argument passed in rdx, 3rd in r8. */ -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { +static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { 0, 0, 2, 1, 11, 12, 5, 13, 14, 15, 7, 6, 3, 4, 10, 8, 9 }; /* low-map. reg_map & 0x7. */ -static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 5] = { +static const sljit_u8 reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 5] = { 0, 0, 2, 1, 3, 4, 5, 5, 6, 7, 7, 6, 3, 4, 2, 0, 1 }; #endif @@ -269,9 +269,9 @@ static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 5] = { built-in CPU features. Therefore they can be overwritten by different threads if they detect the CPU features in the same time. */ #if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) -static sljit_si cpu_has_sse2 = -1; +static sljit_s32 cpu_has_sse2 = -1; #endif -static sljit_si cpu_has_cmov = -1; +static sljit_s32 cpu_has_cmov = -1; #ifdef _WIN32_WCE #include @@ -279,15 +279,38 @@ static sljit_si cpu_has_cmov = -1; #include #endif +/******************************************************/ +/* Unaligned-store functions */ +/******************************************************/ + +static SLJIT_INLINE void sljit_unaligned_store_s16(void *addr, sljit_s16 value) +{ + SLJIT_MEMCPY(addr, &value, sizeof(value)); +} + +static SLJIT_INLINE void sljit_unaligned_store_s32(void *addr, sljit_s32 value) +{ + SLJIT_MEMCPY(addr, &value, sizeof(value)); +} + +static SLJIT_INLINE void sljit_unaligned_store_sw(void *addr, sljit_sw value) +{ + SLJIT_MEMCPY(addr, &value, sizeof(value)); +} + +/******************************************************/ +/* Utility functions */ +/******************************************************/ + static void get_cpu_features(void) { - sljit_ui features; + sljit_u32 features; #if defined(_MSC_VER) && _MSC_VER >= 1400 int CPUInfo[4]; __cpuid(CPUInfo, 1); - features = (sljit_ui)CPUInfo[3]; + features = (sljit_u32)CPUInfo[3]; #elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C) @@ -330,31 +353,31 @@ static void get_cpu_features(void) cpu_has_cmov = (features >> 15) & 0x1; } -static sljit_ub get_jump_code(sljit_si type) +static sljit_u8 get_jump_code(sljit_s32 type) { switch (type) { case SLJIT_EQUAL: - case SLJIT_D_EQUAL: + case SLJIT_EQUAL_F64: return 0x84 /* je */; case SLJIT_NOT_EQUAL: - case SLJIT_D_NOT_EQUAL: + case SLJIT_NOT_EQUAL_F64: return 0x85 /* jne */; case SLJIT_LESS: - case SLJIT_D_LESS: + case SLJIT_LESS_F64: return 0x82 /* jc */; case SLJIT_GREATER_EQUAL: - case SLJIT_D_GREATER_EQUAL: + case SLJIT_GREATER_EQUAL_F64: return 0x83 /* jae */; case SLJIT_GREATER: - case SLJIT_D_GREATER: + case SLJIT_GREATER_F64: return 0x87 /* jnbe */; case SLJIT_LESS_EQUAL: - case SLJIT_D_LESS_EQUAL: + case SLJIT_LESS_EQUAL_F64: return 0x86 /* jbe */; case SLJIT_SIG_LESS: @@ -377,24 +400,24 @@ static sljit_ub get_jump_code(sljit_si type) case SLJIT_MUL_NOT_OVERFLOW: return 0x81 /* jno */; - case SLJIT_D_UNORDERED: + case SLJIT_UNORDERED_F64: return 0x8a /* jp */; - case SLJIT_D_ORDERED: + case SLJIT_ORDERED_F64: return 0x8b /* jpo */; } return 0; } -static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type); +static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) -static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_sw addr, sljit_si type); +static sljit_u8* generate_fixed_jump(sljit_u8 *code_ptr, sljit_sw addr, sljit_s32 type); #endif -static sljit_ub* generate_near_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_ub *code, sljit_si type) +static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_s32 type) { - sljit_si short_jump; + sljit_s32 short_jump; sljit_uw label_addr; if (jump->flags & JUMP_LABEL) @@ -432,13 +455,13 @@ static sljit_ub* generate_near_jump_code(struct sljit_jump *jump, sljit_ub *code if (short_jump) { jump->flags |= PATCH_MB; - code_ptr += sizeof(sljit_sb); + code_ptr += sizeof(sljit_s8); } else { jump->flags |= PATCH_MW; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) code_ptr += sizeof(sljit_sw); #else - code_ptr += sizeof(sljit_si); + code_ptr += sizeof(sljit_s32); #endif } @@ -448,11 +471,11 @@ static sljit_ub* generate_near_jump_code(struct sljit_jump *jump, sljit_ub *code SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) { struct sljit_memory_fragment *buf; - sljit_ub *code; - sljit_ub *code_ptr; - sljit_ub *buf_ptr; - sljit_ub *buf_end; - sljit_ub len; + sljit_u8 *code; + sljit_u8 *code_ptr; + sljit_u8 *buf_ptr; + sljit_u8 *buf_end; + sljit_u8 len; struct sljit_label *label; struct sljit_jump *jump; @@ -463,7 +486,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil reverse_buf(compiler); /* Second code generation pass. */ - code = (sljit_ub*)SLJIT_MALLOC_EXEC(compiler->size); + code = (sljit_u8*)SLJIT_MALLOC_EXEC(compiler->size); PTR_FAIL_WITH_EXEC_IF(code); buf = compiler->buf; @@ -478,7 +501,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil len = *buf_ptr++; if (len > 0) { /* The code is already generated. */ - SLJIT_MEMMOVE(code_ptr, buf_ptr, len); + SLJIT_MEMCPY(code_ptr, buf_ptr, len); code_ptr += len; buf_ptr += len; } @@ -504,7 +527,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) *code_ptr++ = (*buf_ptr == 2) ? CALL_i32 : JMP_i32; buf_ptr++; - *(sljit_sw*)code_ptr = *(sljit_sw*)buf_ptr - ((sljit_sw)code_ptr + sizeof(sljit_sw)); + sljit_unaligned_store_sw(code_ptr, *(sljit_sw*)buf_ptr - ((sljit_sw)code_ptr + sizeof(sljit_sw))); code_ptr += sizeof(sljit_sw); buf_ptr += sizeof(sljit_sw) - 1; #else @@ -526,29 +549,29 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil jump = compiler->jumps; while (jump) { if (jump->flags & PATCH_MB) { - SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_sb))) >= -128 && (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_sb))) <= 127); - *(sljit_ub*)jump->addr = (sljit_ub)(jump->u.label->addr - (jump->addr + sizeof(sljit_sb))); + SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_s8))) >= -128 && (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_s8))) <= 127); + *(sljit_u8*)jump->addr = (sljit_u8)(jump->u.label->addr - (jump->addr + sizeof(sljit_s8))); } else if (jump->flags & PATCH_MW) { if (jump->flags & JUMP_LABEL) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - *(sljit_sw*)jump->addr = (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_sw))); + sljit_unaligned_store_sw((void*)jump->addr, (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_sw)))); #else - SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_si))) >= HALFWORD_MIN && (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_si))) <= HALFWORD_MAX); - *(sljit_si*)jump->addr = (sljit_si)(jump->u.label->addr - (jump->addr + sizeof(sljit_si))); + SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_s32))) >= HALFWORD_MIN && (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_s32))) <= HALFWORD_MAX); + sljit_unaligned_store_s32((void*)jump->addr, (sljit_s32)(jump->u.label->addr - (jump->addr + sizeof(sljit_s32)))); #endif } else { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - *(sljit_sw*)jump->addr = (sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_sw))); + sljit_unaligned_store_sw((void*)jump->addr, (sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_sw)))); #else - SLJIT_ASSERT((sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_si))) >= HALFWORD_MIN && (sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_si))) <= HALFWORD_MAX); - *(sljit_si*)jump->addr = (sljit_si)(jump->u.target - (jump->addr + sizeof(sljit_si))); + SLJIT_ASSERT((sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_s32))) >= HALFWORD_MIN && (sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_s32))) <= HALFWORD_MAX); + sljit_unaligned_store_s32((void*)jump->addr, (sljit_s32)(jump->u.target - (jump->addr + sizeof(sljit_s32)))); #endif } } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) else if (jump->flags & PATCH_MD) - *(sljit_sw*)jump->addr = jump->u.label->addr; + sljit_unaligned_store_sw((void*)jump->addr, jump->u.label->addr); #endif jump = jump->next; @@ -565,32 +588,32 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil /* Operators */ /* --------------------------------------------------------------------- */ -static sljit_si emit_cum_binary(struct sljit_compiler *compiler, - sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w); +static sljit_s32 emit_cum_binary(struct sljit_compiler *compiler, + sljit_u8 op_rm, sljit_u8 op_mr, sljit_u8 op_imm, sljit_u8 op_eax_imm, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w); -static sljit_si emit_non_cum_binary(struct sljit_compiler *compiler, - sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w); +static sljit_s32 emit_non_cum_binary(struct sljit_compiler *compiler, + sljit_u8 op_rm, sljit_u8 op_mr, sljit_u8 op_imm, sljit_u8 op_eax_imm, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w); -static sljit_si emit_mov(struct sljit_compiler *compiler, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw); +static sljit_s32 emit_mov(struct sljit_compiler *compiler, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw); -static SLJIT_INLINE sljit_si emit_save_flags(struct sljit_compiler *compiler) +static SLJIT_INLINE sljit_s32 emit_save_flags(struct sljit_compiler *compiler) { - sljit_ub *inst; + sljit_u8 *inst; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 5); FAIL_IF(!inst); INC_SIZE(5); #else - inst = (sljit_ub*)ensure_buf(compiler, 1 + 6); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 6); FAIL_IF(!inst); INC_SIZE(6); *inst++ = REX_W; @@ -598,23 +621,23 @@ static SLJIT_INLINE sljit_si emit_save_flags(struct sljit_compiler *compiler) *inst++ = LEA_r_m; /* lea esp/rsp, [esp/rsp + sizeof(sljit_sw)] */ *inst++ = 0x64; *inst++ = 0x24; - *inst++ = (sljit_ub)sizeof(sljit_sw); + *inst++ = (sljit_u8)sizeof(sljit_sw); *inst++ = PUSHF; compiler->flags_saved = 1; return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_restore_flags(struct sljit_compiler *compiler, sljit_si keep_flags) +static SLJIT_INLINE sljit_s32 emit_restore_flags(struct sljit_compiler *compiler, sljit_s32 keep_flags) { - sljit_ub *inst; + sljit_u8 *inst; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 5); FAIL_IF(!inst); INC_SIZE(5); *inst++ = POPF; #else - inst = (sljit_ub*)ensure_buf(compiler, 1 + 6); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 6); FAIL_IF(!inst); INC_SIZE(6); *inst++ = POPF; @@ -623,7 +646,7 @@ static SLJIT_INLINE sljit_si emit_restore_flags(struct sljit_compiler *compiler, *inst++ = LEA_r_m; /* lea esp/rsp, [esp/rsp - sizeof(sljit_sw)] */ *inst++ = 0x64; *inst++ = 0x24; - *inst++ = (sljit_ub)-(sljit_sb)sizeof(sljit_sw); + *inst++ = (sljit_u8)(-(sljit_s8)sizeof(sljit_sw)); compiler->flags_saved = keep_flags; return SLJIT_SUCCESS; } @@ -640,7 +663,7 @@ static void SLJIT_CALL sljit_grow_stack(sljit_sw local_size) CPU cycles if the stack is large enough. However, you don't know it in advance, so it must always be called. I think this is a bad design in general even if it has some reasons. */ - *(volatile sljit_si*)alloca(local_size) = 0; + *(volatile sljit_s32*)alloca(local_size) = 0; } #endif @@ -651,11 +674,11 @@ static void SLJIT_CALL sljit_grow_stack(sljit_sw local_size) #include "sljitNativeX86_64.c" #endif -static sljit_si emit_mov(struct sljit_compiler *compiler, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static sljit_s32 emit_mov(struct sljit_compiler *compiler, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_ub* inst; + sljit_u8* inst; if (dst == SLJIT_UNUSED) { /* No destination, doesn't need to setup flags. */ @@ -719,11 +742,11 @@ static sljit_si emit_mov(struct sljit_compiler *compiler, #define EMIT_MOV(compiler, dst, dstw, src, srcw) \ FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw)); -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { - sljit_ub *inst; + sljit_u8 *inst; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - sljit_si size; + sljit_s32 size; #endif CHECK_ERROR(); @@ -731,23 +754,23 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler switch (GET_OPCODE(op)) { case SLJIT_BREAKPOINT: - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); INC_SIZE(1); *inst = INT3; break; case SLJIT_NOP: - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); INC_SIZE(1); *inst = NOP; break; - case SLJIT_LUMUL: - case SLJIT_LSMUL: - case SLJIT_UDIVMOD: - case SLJIT_SDIVMOD: - case SLJIT_UDIVI: - case SLJIT_SDIVI: + case SLJIT_LMUL_UW: + case SLJIT_LMUL_SW: + case SLJIT_DIVMOD_UW: + case SLJIT_DIVMOD_SW: + case SLJIT_DIV_UW: + case SLJIT_DIV_SW: compiler->flags_saved = 0; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) #ifdef _WIN64 @@ -763,12 +786,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler && reg_map[TMP_REG1] == 2, invalid_register_assignment_for_div_mul); #endif - compiler->mode32 = op & SLJIT_INT_OP; + compiler->mode32 = op & SLJIT_I32_OP; #endif - SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments); + SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments); op = GET_OPCODE(op); - if ((op | 0x2) == SLJIT_UDIVI) { + if ((op | 0x2) == SLJIT_DIV_UW) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64) EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R1, 0); inst = emit_x86_instruction(compiler, 1, SLJIT_R1, 0, SLJIT_R1, 0); @@ -779,24 +802,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler *inst = XOR_r_rm; } - if ((op | 0x2) == SLJIT_SDIVI) { + if ((op | 0x2) == SLJIT_DIV_SW) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64) EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R1, 0); #endif #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); INC_SIZE(1); *inst = CDQ; #else if (compiler->mode32) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); INC_SIZE(1); *inst = CDQ; } else { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 2); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); FAIL_IF(!inst); INC_SIZE(2); *inst++ = REX_W; @@ -806,27 +829,27 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = (sljit_ub*)ensure_buf(compiler, 1 + 2); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); FAIL_IF(!inst); INC_SIZE(2); *inst++ = GROUP_F7; - *inst = MOD_REG | ((op >= SLJIT_UDIVMOD) ? reg_map[TMP_REG1] : reg_map[SLJIT_R1]); + *inst = MOD_REG | ((op >= SLJIT_DIVMOD_UW) ? reg_map[TMP_REG1] : reg_map[SLJIT_R1]); #else #ifdef _WIN64 - size = (!compiler->mode32 || op >= SLJIT_UDIVMOD) ? 3 : 2; + size = (!compiler->mode32 || op >= SLJIT_DIVMOD_UW) ? 3 : 2; #else size = (!compiler->mode32) ? 3 : 2; #endif - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); INC_SIZE(size); #ifdef _WIN64 if (!compiler->mode32) - *inst++ = REX_W | ((op >= SLJIT_UDIVMOD) ? REX_B : 0); - else if (op >= SLJIT_UDIVMOD) + *inst++ = REX_W | ((op >= SLJIT_DIVMOD_UW) ? REX_B : 0); + else if (op >= SLJIT_DIVMOD_UW) *inst++ = REX_B; *inst++ = GROUP_F7; - *inst = MOD_REG | ((op >= SLJIT_UDIVMOD) ? reg_lmap[TMP_REG1] : reg_lmap[SLJIT_R1]); + *inst = MOD_REG | ((op >= SLJIT_DIVMOD_UW) ? reg_lmap[TMP_REG1] : reg_lmap[SLJIT_R1]); #else if (!compiler->mode32) *inst++ = REX_W; @@ -835,26 +858,26 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler #endif #endif switch (op) { - case SLJIT_LUMUL: + case SLJIT_LMUL_UW: *inst |= MUL; break; - case SLJIT_LSMUL: + case SLJIT_LMUL_SW: *inst |= IMUL; break; - case SLJIT_UDIVMOD: - case SLJIT_UDIVI: + case SLJIT_DIVMOD_UW: + case SLJIT_DIV_UW: *inst |= DIV; break; - case SLJIT_SDIVMOD: - case SLJIT_SDIVI: + case SLJIT_DIVMOD_SW: + case SLJIT_DIV_SW: *inst |= IDIV; break; } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64) - if (op <= SLJIT_SDIVMOD) + if (op <= SLJIT_DIVMOD_SW) EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0); #else - if (op >= SLJIT_UDIVI) + if (op >= SLJIT_DIV_UW) EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0); #endif break; @@ -865,20 +888,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler #define ENCODE_PREFIX(prefix) \ do { \ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); \ + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); \ FAIL_IF(!inst); \ INC_SIZE(1); \ *inst = (prefix); \ } while (0) -static sljit_si emit_mov_byte(struct sljit_compiler *compiler, sljit_si sign, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static sljit_s32 emit_mov_byte(struct sljit_compiler *compiler, sljit_s32 sign, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_ub* inst; - sljit_si dst_r; + sljit_u8* inst; + sljit_s32 dst_r; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - sljit_si work_r; + sljit_s32 work_r; #endif #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) @@ -1016,12 +1039,12 @@ static sljit_si emit_mov_byte(struct sljit_compiler *compiler, sljit_si sign, return SLJIT_SUCCESS; } -static sljit_si emit_mov_half(struct sljit_compiler *compiler, sljit_si sign, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static sljit_s32 emit_mov_half(struct sljit_compiler *compiler, sljit_s32 sign, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_ub* inst; - sljit_si dst_r; + sljit_u8* inst; + sljit_s32 dst_r; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 0; @@ -1067,11 +1090,11 @@ static sljit_si emit_mov_half(struct sljit_compiler *compiler, sljit_si sign, return SLJIT_SUCCESS; } -static sljit_si emit_unary(struct sljit_compiler *compiler, sljit_ub opcode, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static sljit_s32 emit_unary(struct sljit_compiler *compiler, sljit_u8 opcode, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_ub* inst; + sljit_u8* inst; if (dst == SLJIT_UNUSED) { EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); @@ -1106,11 +1129,11 @@ static sljit_si emit_unary(struct sljit_compiler *compiler, sljit_ub opcode, return SLJIT_SUCCESS; } -static sljit_si emit_not_with_flags(struct sljit_compiler *compiler, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static sljit_s32 emit_not_with_flags(struct sljit_compiler *compiler, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_ub* inst; + sljit_u8* inst; if (dst == SLJIT_UNUSED) { EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); @@ -1146,12 +1169,12 @@ static sljit_si emit_not_with_flags(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } -static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static sljit_s32 emit_clz(struct sljit_compiler *compiler, sljit_s32 op_flags, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_ub* inst; - sljit_si dst_r; + sljit_u8* inst; + sljit_s32 dst_r; SLJIT_UNUSED_ARG(op_flags); if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { @@ -1164,7 +1187,7 @@ static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 31, TMP_REG1, 0); #else - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, !(op_flags & SLJIT_INT_OP) ? 63 : 31, TMP_REG1, 0); + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, !(op_flags & SLJIT_I32_OP) ? 63 : 31, TMP_REG1, 0); #endif FAIL_IF(!inst); *inst |= SHR; @@ -1199,8 +1222,8 @@ static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, #else dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; compiler->mode32 = 0; - EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, !(op_flags & SLJIT_INT_OP) ? 64 + 63 : 32 + 31); - compiler->mode32 = op_flags & SLJIT_INT_OP; + EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, !(op_flags & SLJIT_I32_OP) ? 64 + 63 : 32 + 31); + compiler->mode32 = op_flags & SLJIT_I32_OP; #endif if (cpu_has_cmov == -1) @@ -1213,7 +1236,7 @@ static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, *inst = CMOVNE_r_rm; } else { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); FAIL_IF(!inst); INC_SIZE(4); @@ -1222,7 +1245,7 @@ static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, *inst++ = MOV_r_rm; *inst++ = MOD_REG | (reg_map[dst_r] << 3) | reg_map[TMP_REG1]; #else - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 5); FAIL_IF(!inst); INC_SIZE(5); @@ -1237,7 +1260,7 @@ static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 31, dst_r, 0); #else - inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, !(op_flags & SLJIT_INT_OP) ? 63 : 31, dst_r, 0); + inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, !(op_flags & SLJIT_I32_OP) ? 63 : 31, dst_r, 0); #endif FAIL_IF(!inst); *(inst + 1) |= XOR; @@ -1255,16 +1278,16 @@ static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_ub* inst; - sljit_si update = 0; - sljit_si op_flags = GET_ALL_FLAGS(op); + sljit_u8* inst; + sljit_s32 update = 0; + sljit_s32 op_flags = GET_ALL_FLAGS(op); #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - sljit_si dst_is_ereg = 0; - sljit_si src_is_ereg = 0; + sljit_s32 dst_is_ereg = 0; + sljit_s32 src_is_ereg = 0; #else # define src_is_ereg 0 #endif @@ -1277,7 +1300,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler CHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1); CHECK_EXTRA_REGS(src, srcw, src_is_ereg = 1); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = op_flags & SLJIT_INT_OP; + compiler->mode32 = op_flags & SLJIT_I32_OP; #endif op = GET_OPCODE(op); @@ -1286,20 +1309,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler compiler->mode32 = 0; #endif - if (op_flags & SLJIT_INT_OP) { + if (op_flags & SLJIT_I32_OP) { if (FAST_IS_REG(src) && src == dst) { if (!TYPE_CAST_NEEDED(op)) return SLJIT_SUCCESS; } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (op == SLJIT_MOV_SI && (src & SLJIT_MEM)) - op = SLJIT_MOV_UI; - if (op == SLJIT_MOVU_SI && (src & SLJIT_MEM)) - op = SLJIT_MOVU_UI; - if (op == SLJIT_MOV_UI && (src & SLJIT_IMM)) - op = SLJIT_MOV_SI; - if (op == SLJIT_MOVU_UI && (src & SLJIT_IMM)) - op = SLJIT_MOVU_SI; + if (op == SLJIT_MOV_S32 && (src & SLJIT_MEM)) + op = SLJIT_MOV_U32; + if (op == SLJIT_MOVU_S32 && (src & SLJIT_MEM)) + op = SLJIT_MOVU_U32; + if (op == SLJIT_MOV_U32 && (src & SLJIT_IMM)) + op = SLJIT_MOV_S32; + if (op == SLJIT_MOVU_U32 && (src & SLJIT_IMM)) + op = SLJIT_MOVU_S32; #endif } @@ -1311,24 +1334,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler if (src & SLJIT_IMM) { switch (op) { - case SLJIT_MOV_UB: - srcw = (sljit_ub)srcw; + case SLJIT_MOV_U8: + srcw = (sljit_u8)srcw; break; - case SLJIT_MOV_SB: - srcw = (sljit_sb)srcw; + case SLJIT_MOV_S8: + srcw = (sljit_s8)srcw; break; - case SLJIT_MOV_UH: - srcw = (sljit_uh)srcw; + case SLJIT_MOV_U16: + srcw = (sljit_u16)srcw; break; - case SLJIT_MOV_SH: - srcw = (sljit_sh)srcw; + case SLJIT_MOV_S16: + srcw = (sljit_s16)srcw; break; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - case SLJIT_MOV_UI: - srcw = (sljit_ui)srcw; + case SLJIT_MOV_U32: + srcw = (sljit_u32)srcw; break; - case SLJIT_MOV_SI: - srcw = (sljit_si)srcw; + case SLJIT_MOV_S32: + srcw = (sljit_s32)srcw; break; #endif } @@ -1347,7 +1370,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - if (SLJIT_UNLIKELY(dst_is_ereg) && (!(op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI || op == SLJIT_MOV_P) || (src & SLJIT_MEM))) { + if (SLJIT_UNLIKELY(dst_is_ereg) && (!(op == SLJIT_MOV || op == SLJIT_MOV_U32 || op == SLJIT_MOV_S32 || op == SLJIT_MOV_P) || (src & SLJIT_MEM))) { SLJIT_ASSERT(dst == SLJIT_MEM1(SLJIT_SP)); dst = TMP_REG1; } @@ -1357,28 +1380,28 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler case SLJIT_MOV: case SLJIT_MOV_P: #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: + case SLJIT_MOV_U32: + case SLJIT_MOV_S32: #endif FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw)); break; - case SLJIT_MOV_UB: + case SLJIT_MOV_U8: FAIL_IF(emit_mov_byte(compiler, 0, dst, dstw, src, srcw)); break; - case SLJIT_MOV_SB: + case SLJIT_MOV_S8: FAIL_IF(emit_mov_byte(compiler, 1, dst, dstw, src, srcw)); break; - case SLJIT_MOV_UH: + case SLJIT_MOV_U16: FAIL_IF(emit_mov_half(compiler, 0, dst, dstw, src, srcw)); break; - case SLJIT_MOV_SH: + case SLJIT_MOV_S16: FAIL_IF(emit_mov_half(compiler, 1, dst, dstw, src, srcw)); break; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - case SLJIT_MOV_UI: + case SLJIT_MOV_U32: FAIL_IF(emit_mov_int(compiler, 0, dst, dstw, src, srcw)); break; - case SLJIT_MOV_SI: + case SLJIT_MOV_S32: FAIL_IF(emit_mov_int(compiler, 1, dst, dstw, src, srcw)); break; #endif @@ -1454,13 +1477,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler #endif -static sljit_si emit_cum_binary(struct sljit_compiler *compiler, - sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_cum_binary(struct sljit_compiler *compiler, + sljit_u8 op_rm, sljit_u8 op_mr, sljit_u8 op_imm, sljit_u8 op_eax_imm, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_ub* inst; + sljit_u8* inst; if (dst == SLJIT_UNUSED) { EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); @@ -1570,13 +1593,13 @@ static sljit_si emit_cum_binary(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } -static sljit_si emit_non_cum_binary(struct sljit_compiler *compiler, - sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_non_cum_binary(struct sljit_compiler *compiler, + sljit_u8 op_rm, sljit_u8 op_mr, sljit_u8 op_imm, sljit_u8 op_eax_imm, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_ub* inst; + sljit_u8* inst; if (dst == SLJIT_UNUSED) { EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); @@ -1652,13 +1675,13 @@ static sljit_si emit_non_cum_binary(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } -static sljit_si emit_mul(struct sljit_compiler *compiler, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_mul(struct sljit_compiler *compiler, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_ub* inst; - sljit_si dst_r; + sljit_u8* inst; + sljit_s32 dst_r; dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; @@ -1686,30 +1709,30 @@ static sljit_si emit_mul(struct sljit_compiler *compiler, inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); FAIL_IF(!inst); *inst = IMUL_r_rm_i8; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); INC_SIZE(1); - *inst = (sljit_sb)src1w; + *inst = (sljit_s8)src1w; } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) else { inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); FAIL_IF(!inst); *inst = IMUL_r_rm_i32; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); FAIL_IF(!inst); INC_SIZE(4); - *(sljit_sw*)inst = src1w; + sljit_unaligned_store_sw(inst, src1w); } #else else if (IS_HALFWORD(src1w)) { inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); FAIL_IF(!inst); *inst = IMUL_r_rm_i32; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); FAIL_IF(!inst); INC_SIZE(4); - *(sljit_si*)inst = (sljit_si)src1w; + sljit_unaligned_store_s32(inst, (sljit_s32)src1w); } else { EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w); @@ -1729,30 +1752,30 @@ static sljit_si emit_mul(struct sljit_compiler *compiler, inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); FAIL_IF(!inst); *inst = IMUL_r_rm_i8; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); INC_SIZE(1); - *inst = (sljit_sb)src2w; + *inst = (sljit_s8)src2w; } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) else { inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); FAIL_IF(!inst); *inst = IMUL_r_rm_i32; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); FAIL_IF(!inst); INC_SIZE(4); - *(sljit_sw*)inst = src2w; + sljit_unaligned_store_sw(inst, src2w); } #else else if (IS_HALFWORD(src2w)) { inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); FAIL_IF(!inst); *inst = IMUL_r_rm_i32; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); FAIL_IF(!inst); INC_SIZE(4); - *(sljit_si*)inst = (sljit_si)src2w; + sljit_unaligned_store_s32(inst, (sljit_s32)src2w); } else { EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src2w); @@ -1782,13 +1805,13 @@ static sljit_si emit_mul(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } -static sljit_si emit_lea_binary(struct sljit_compiler *compiler, sljit_si keep_flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_lea_binary(struct sljit_compiler *compiler, sljit_s32 keep_flags, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_ub* inst; - sljit_si dst_r, done = 0; + sljit_u8* inst; + sljit_s32 dst_r, done = 0; /* These cases better be left to handled by normal way. */ if (!keep_flags) { @@ -1809,7 +1832,7 @@ static sljit_si emit_lea_binary(struct sljit_compiler *compiler, sljit_si keep_f } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if ((src2 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src2w))) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), (sljit_si)src2w); + inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), (sljit_s32)src2w); #else if (src2 & SLJIT_IMM) { inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), src2w); @@ -1822,7 +1845,7 @@ static sljit_si emit_lea_binary(struct sljit_compiler *compiler, sljit_si keep_f else if (FAST_IS_REG(src2)) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if ((src1 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src1w))) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), (sljit_si)src1w); + inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), (sljit_s32)src1w); #else if (src1 & SLJIT_IMM) { inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), src1w); @@ -1841,11 +1864,11 @@ static sljit_si emit_lea_binary(struct sljit_compiler *compiler, sljit_si keep_f return SLJIT_ERR_UNSUPPORTED; } -static sljit_si emit_cmp_binary(struct sljit_compiler *compiler, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_cmp_binary(struct sljit_compiler *compiler, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_ub* inst; + sljit_u8* inst; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { @@ -1892,11 +1915,11 @@ static sljit_si emit_cmp_binary(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } -static sljit_si emit_test_binary(struct sljit_compiler *compiler, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_test_binary(struct sljit_compiler *compiler, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_ub* inst; + sljit_u8* inst; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { @@ -2002,13 +2025,13 @@ static sljit_si emit_test_binary(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } -static sljit_si emit_shift(struct sljit_compiler *compiler, - sljit_ub mode, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_shift(struct sljit_compiler *compiler, + sljit_u8 mode, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_ub* inst; + sljit_u8* inst; if ((src2 & SLJIT_IMM) || (src2 == SLJIT_PREF_SHIFT_REG)) { if (dst == src1 && dstw == src1w) { @@ -2091,11 +2114,11 @@ static sljit_si emit_shift(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } -static sljit_si emit_shift_with_flags(struct sljit_compiler *compiler, - sljit_ub mode, sljit_si set_flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_shift_with_flags(struct sljit_compiler *compiler, + sljit_u8 mode, sljit_s32 set_flags, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { /* The CPU does not set flags if the shift count is 0. */ if (src2 & SLJIT_IMM) { @@ -2126,10 +2149,10 @@ static sljit_si emit_shift_with_flags(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { CHECK_ERROR(); CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -2141,7 +2164,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler CHECK_EXTRA_REGS(src1, src1w, (void)0); CHECK_EXTRA_REGS(src2, src2w, (void)0); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = op & SLJIT_INT_OP; + compiler->mode32 = op & SLJIT_I32_OP; #endif if (GET_OPCODE(op) >= SLJIT_MUL) { @@ -2221,7 +2244,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_register_index(reg)); #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) @@ -2231,24 +2254,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) return reg_map[reg]; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); return reg; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_s32 size) { - sljit_ub *inst; + sljit_u8 *inst; CHECK_ERROR(); CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); INC_SIZE(size); - SLJIT_MEMMOVE(inst, instruction, size); + SLJIT_MEMCPY(inst, instruction, size); return SLJIT_SUCCESS; } @@ -2257,12 +2280,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co /* --------------------------------------------------------------------- */ /* Alignment + 2 * 16 bytes. */ -static sljit_si sse2_data[3 + (4 + 4) * 2]; -static sljit_si *sse2_buffer; +static sljit_s32 sse2_data[3 + (4 + 4) * 2]; +static sljit_s32 *sse2_buffer; static void init_compiler(void) { - sse2_buffer = (sljit_si*)(((sljit_uw)sse2_data + 15) & ~0xf); + sse2_buffer = (sljit_s32*)(((sljit_uw)sse2_data + 15) & ~0xf); /* Single precision constants. */ sse2_buffer[0] = 0x80000000; sse2_buffer[4] = 0x7fffffff; @@ -2273,7 +2296,7 @@ static void init_compiler(void) sse2_buffer[13] = 0x7fffffff; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void) { #ifdef SLJIT_IS_FPU_AVAILABLE return SLJIT_IS_FPU_AVAILABLE; @@ -2286,10 +2309,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) #endif /* SLJIT_DETECT_SSE2 */ } -static sljit_si emit_sse2(struct sljit_compiler *compiler, sljit_ub opcode, - sljit_si single, sljit_si xmm1, sljit_si xmm2, sljit_sw xmm2w) +static sljit_s32 emit_sse2(struct sljit_compiler *compiler, sljit_u8 opcode, + sljit_s32 single, sljit_s32 xmm1, sljit_s32 xmm2, sljit_sw xmm2w) { - sljit_ub *inst; + sljit_u8 *inst; inst = emit_x86_instruction(compiler, 2 | (single ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, xmm1, 0, xmm2, xmm2w); FAIL_IF(!inst); @@ -2298,10 +2321,10 @@ static sljit_si emit_sse2(struct sljit_compiler *compiler, sljit_ub opcode, return SLJIT_SUCCESS; } -static sljit_si emit_sse2_logic(struct sljit_compiler *compiler, sljit_ub opcode, - sljit_si pref66, sljit_si xmm1, sljit_si xmm2, sljit_sw xmm2w) +static sljit_s32 emit_sse2_logic(struct sljit_compiler *compiler, sljit_u8 opcode, + sljit_s32 pref66, sljit_s32 xmm1, sljit_s32 xmm2, sljit_sw xmm2w) { - sljit_ub *inst; + sljit_u8 *inst; inst = emit_x86_instruction(compiler, 2 | (pref66 ? EX86_PREF_66 : 0) | EX86_SSE2, xmm1, 0, xmm2, xmm2w); FAIL_IF(!inst); @@ -2310,31 +2333,31 @@ static sljit_si emit_sse2_logic(struct sljit_compiler *compiler, sljit_ub opcode return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_sse2_load(struct sljit_compiler *compiler, - sljit_si single, sljit_si dst, sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 emit_sse2_load(struct sljit_compiler *compiler, + sljit_s32 single, sljit_s32 dst, sljit_s32 src, sljit_sw srcw) { return emit_sse2(compiler, MOVSD_x_xm, single, dst, src, srcw); } -static SLJIT_INLINE sljit_si emit_sse2_store(struct sljit_compiler *compiler, - sljit_si single, sljit_si dst, sljit_sw dstw, sljit_si src) +static SLJIT_INLINE sljit_s32 emit_sse2_store(struct sljit_compiler *compiler, + sljit_s32 single, sljit_s32 dst, sljit_sw dstw, sljit_s32 src) { return emit_sse2(compiler, MOVSD_xm_x, single, src, dst, dstw); } -static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; - sljit_ub *inst; + sljit_s32 dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; + sljit_u8 *inst; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (GET_OPCODE(op) == SLJIT_CONVW_FROMD) + if (GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64) compiler->mode32 = 0; #endif - inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_SINGLE_OP) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP2, dst_r, 0, src, srcw); + inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_F32_OP) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP2, dst_r, 0, src, srcw); FAIL_IF(!inst); *inst++ = GROUP_0F; *inst = CVTTSD2SI_r_xm; @@ -2344,29 +2367,29 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler * return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG; - sljit_ub *inst; + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG; + sljit_u8 *inst; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (GET_OPCODE(op) == SLJIT_CONVD_FROMW) + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW) compiler->mode32 = 0; #endif if (src & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) - srcw = (sljit_si)srcw; + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) + srcw = (sljit_s32)srcw; #endif EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); src = TMP_REG1; srcw = 0; } - inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_SINGLE_OP) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP1, dst_r, 0, src, srcw); + inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_F32_OP) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP1, dst_r, 0, src, srcw); FAIL_IF(!inst); *inst++ = GROUP_0F; *inst = CVTSI2SD_x_rm; @@ -2375,27 +2398,27 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler * compiler->mode32 = 1; #endif if (dst_r == TMP_FREG) - return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); + return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, TMP_FREG); return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { compiler->flags_saved = 0; if (!FAST_IS_REG(src1)) { - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, TMP_FREG, src1, src1w)); + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, TMP_FREG, src1, src1w)); src1 = TMP_FREG; } - return emit_sse2_logic(compiler, UCOMISD_x_xm, !(op & SLJIT_SINGLE_OP), src1, src2, src2w); + return emit_sse2_logic(compiler, UCOMISD_x_xm, !(op & SLJIT_F32_OP), src1, src2, src2w); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r; + sljit_s32 dst_r; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 1; @@ -2404,65 +2427,65 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile CHECK_ERROR(); SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); - if (GET_OPCODE(op) == SLJIT_DMOV) { + if (GET_OPCODE(op) == SLJIT_MOV_F64) { if (FAST_IS_REG(dst)) - return emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst, src, srcw); + return emit_sse2_load(compiler, op & SLJIT_F32_OP, dst, src, srcw); if (FAST_IS_REG(src)) - return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, src); - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, TMP_FREG, src, srcw)); - return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); + return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, src); + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, TMP_FREG, src, srcw)); + return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, TMP_FREG); } - if (GET_OPCODE(op) == SLJIT_CONVD_FROMS) { + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) { dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG; if (FAST_IS_REG(src)) { /* We overwrite the high bits of source. From SLJIT point of view, this is not an issue. Note: In SSE3, we could also use MOVDDUP and MOVSLDUP. */ - FAIL_IF(emit_sse2_logic(compiler, UNPCKLPD_x_xm, op & SLJIT_SINGLE_OP, src, src, 0)); + FAIL_IF(emit_sse2_logic(compiler, UNPCKLPD_x_xm, op & SLJIT_F32_OP, src, src, 0)); } else { - FAIL_IF(emit_sse2_load(compiler, !(op & SLJIT_SINGLE_OP), TMP_FREG, src, srcw)); + FAIL_IF(emit_sse2_load(compiler, !(op & SLJIT_F32_OP), TMP_FREG, src, srcw)); src = TMP_FREG; } - FAIL_IF(emit_sse2_logic(compiler, CVTPD2PS_x_xm, op & SLJIT_SINGLE_OP, dst_r, src, 0)); + FAIL_IF(emit_sse2_logic(compiler, CVTPD2PS_x_xm, op & SLJIT_F32_OP, dst_r, src, 0)); if (dst_r == TMP_FREG) - return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); + return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, TMP_FREG); return SLJIT_SUCCESS; } if (SLOW_IS_REG(dst)) { dst_r = dst; if (dst != src) - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst_r, src, srcw)); + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, dst_r, src, srcw)); } else { dst_r = TMP_FREG; - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst_r, src, srcw)); + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, dst_r, src, srcw)); } switch (GET_OPCODE(op)) { - case SLJIT_DNEG: - FAIL_IF(emit_sse2_logic(compiler, XORPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_SINGLE_OP ? sse2_buffer : sse2_buffer + 8))); + case SLJIT_NEG_F64: + FAIL_IF(emit_sse2_logic(compiler, XORPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_F32_OP ? sse2_buffer : sse2_buffer + 8))); break; - case SLJIT_DABS: - FAIL_IF(emit_sse2_logic(compiler, ANDPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_SINGLE_OP ? sse2_buffer + 4 : sse2_buffer + 12))); + case SLJIT_ABS_F64: + FAIL_IF(emit_sse2_logic(compiler, ANDPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_F32_OP ? sse2_buffer + 4 : sse2_buffer + 12))); break; } if (dst_r == TMP_FREG) - return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); + return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, TMP_FREG); return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si dst_r; + sljit_s32 dst_r; CHECK_ERROR(); CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -2478,43 +2501,43 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile dst_r = dst; if (dst == src1) ; /* Do nothing here. */ - else if (dst == src2 && (op == SLJIT_DADD || op == SLJIT_DMUL)) { + else if (dst == src2 && (op == SLJIT_ADD_F64 || op == SLJIT_MUL_F64)) { /* Swap arguments. */ src2 = src1; src2w = src1w; } else if (dst != src2) - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst_r, src1, src1w)); + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, dst_r, src1, src1w)); else { dst_r = TMP_FREG; - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, TMP_FREG, src1, src1w)); + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, TMP_FREG, src1, src1w)); } } else { dst_r = TMP_FREG; - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, TMP_FREG, src1, src1w)); + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, TMP_FREG, src1, src1w)); } switch (GET_OPCODE(op)) { - case SLJIT_DADD: - FAIL_IF(emit_sse2(compiler, ADDSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w)); + case SLJIT_ADD_F64: + FAIL_IF(emit_sse2(compiler, ADDSD_x_xm, op & SLJIT_F32_OP, dst_r, src2, src2w)); break; - case SLJIT_DSUB: - FAIL_IF(emit_sse2(compiler, SUBSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w)); + case SLJIT_SUB_F64: + FAIL_IF(emit_sse2(compiler, SUBSD_x_xm, op & SLJIT_F32_OP, dst_r, src2, src2w)); break; - case SLJIT_DMUL: - FAIL_IF(emit_sse2(compiler, MULSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w)); + case SLJIT_MUL_F64: + FAIL_IF(emit_sse2(compiler, MULSD_x_xm, op & SLJIT_F32_OP, dst_r, src2, src2w)); break; - case SLJIT_DDIV: - FAIL_IF(emit_sse2(compiler, DIVSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w)); + case SLJIT_DIV_F64: + FAIL_IF(emit_sse2(compiler, DIVSD_x_xm, op & SLJIT_F32_OP, dst_r, src2, src2w)); break; } if (dst_r == TMP_FREG) - return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); + return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, TMP_FREG); return SLJIT_SUCCESS; } @@ -2524,7 +2547,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) { - sljit_ub *inst; + sljit_u8 *inst; struct sljit_label *label; CHECK_ERROR_PTR(); @@ -2542,7 +2565,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi PTR_FAIL_IF(!label); set_label(label, compiler); - inst = (sljit_ub*)ensure_buf(compiler, 2); + inst = (sljit_u8*)ensure_buf(compiler, 2); PTR_FAIL_IF(!inst); *inst++ = 0; @@ -2551,9 +2574,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi return label; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { - sljit_ub *inst; + sljit_u8 *inst; struct sljit_jump *jump; CHECK_ERROR_PTR(); @@ -2580,7 +2603,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile compiler->size += (type >= SLJIT_JUMP) ? (10 + 3) : (2 + 10 + 3); #endif - inst = (sljit_ub*)ensure_buf(compiler, 2); + inst = (sljit_u8*)ensure_buf(compiler, 2); PTR_FAIL_IF_NULL(inst); *inst++ = 0; @@ -2588,9 +2611,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile return jump; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) { - sljit_ub *inst; + sljit_u8 *inst; struct sljit_jump *jump; CHECK_ERROR(); @@ -2638,7 +2661,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil compiler->size += 10 + 3; #endif - inst = (sljit_ub*)ensure_buf(compiler, 2); + inst = (sljit_u8*)ensure_buf(compiler, 2); FAIL_IF_NULL(inst); *inst++ = 0; @@ -2657,18 +2680,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw, + sljit_s32 type) { - sljit_ub *inst; - sljit_ub cond_set = 0; + sljit_u8 *inst; + sljit_u8 cond_set = 0; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - sljit_si reg; + sljit_s32 reg; #else /* CHECK_EXTRA_REGS migh overwrite these values. */ - sljit_si dst_save = dst; + sljit_s32 dst_save = dst; sljit_sw dstw_save = dstw; #endif @@ -2690,7 +2713,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst) && dst == src) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 3); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 + 3); FAIL_IF(!inst); INC_SIZE(4 + 3); /* Set low register to conditional flag. */ @@ -2706,7 +2729,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com reg = (op == SLJIT_MOV && FAST_IS_REG(dst)) ? dst : TMP_REG1; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 4); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 + 4); FAIL_IF(!inst); INC_SIZE(4 + 4); /* Set low register to conditional flag. */ @@ -2735,7 +2758,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com if (GET_OPCODE(op) < SLJIT_ADD && FAST_IS_REG(dst)) { if (reg_map[dst] <= 4) { /* Low byte is accessible. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 3 + 3); FAIL_IF(!inst); INC_SIZE(3 + 3); /* Set low byte to conditional flag. */ @@ -2758,7 +2781,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com /* a xor reg, reg operation would overwrite the flags. */ EMIT_MOV(compiler, dst, 0, SLJIT_IMM, 0); - inst = (sljit_ub*)ensure_buf(compiler, 1 + 3); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 3); FAIL_IF(!inst); INC_SIZE(3); @@ -2769,7 +2792,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com return SLJIT_SUCCESS; } - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1); FAIL_IF(!inst); INC_SIZE(1 + 3 + 3 + 1); *inst++ = XCHG_EAX_r + reg_map[TMP_REG1]; @@ -2788,7 +2811,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst) && dst == src && reg_map[dst] <= 4) { SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R0] == 0, scratch_reg1_must_be_eax); if (dst != SLJIT_R0) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 3 + 2 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 3 + 2 + 1); FAIL_IF(!inst); INC_SIZE(1 + 3 + 2 + 1); /* Set low register to conditional flag. */ @@ -2801,7 +2824,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com *inst++ = XCHG_EAX_r + reg_map[TMP_REG1]; } else { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 3 + 2 + 2); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2 + 3 + 2 + 2); FAIL_IF(!inst); INC_SIZE(2 + 3 + 2 + 2); /* Set low register to conditional flag. */ @@ -2819,7 +2842,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com } /* Set TMP_REG1 to the bit. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1); FAIL_IF(!inst); INC_SIZE(1 + 3 + 3 + 1); *inst++ = XCHG_EAX_r + reg_map[TMP_REG1]; @@ -2845,7 +2868,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com #endif /* SLJIT_CONFIG_X86_64 */ } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset) { CHECK_ERROR(); CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset)); @@ -2876,12 +2899,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *co return emit_mov(compiler, dst, dstw, SLJIT_SP, 0); } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { - sljit_ub *inst; + sljit_u8 *inst; struct sljit_const *const_; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - sljit_si reg; + sljit_s32 reg; #endif CHECK_ERROR_PTR(); @@ -2908,7 +2931,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi return NULL; #endif - inst = (sljit_ub*)ensure_buf(compiler, 2); + inst = (sljit_u8*)ensure_buf(compiler, 2); PTR_FAIL_IF(!inst); *inst++ = 0; @@ -2926,18 +2949,18 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - *(sljit_sw*)addr = new_addr - (addr + 4); + sljit_unaligned_store_sw((void*)addr, new_addr - (addr + 4)); #else - *(sljit_uw*)addr = new_addr; + sljit_unaligned_store_sw((void*)addr, (sljit_sw) new_addr); #endif } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) { - *(sljit_sw*)addr = new_constant; + sljit_unaligned_store_sw((void*)addr, new_constant); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_sse2_available(void) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_is_sse2_available(void) { #if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) if (cpu_has_sse2 == -1) @@ -2948,34 +2971,34 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_sse2_available(void) #endif } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_cmov_available(void) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_is_cmov_available(void) { if (cpu_has_cmov == -1) get_cpu_features(); return cpu_has_cmov; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_emit_cmov(struct sljit_compiler *compiler, - sljit_si type, - sljit_si dst_reg, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_emit_cmov(struct sljit_compiler *compiler, + sljit_s32 type, + sljit_s32 dst_reg, + sljit_s32 src, sljit_sw srcw) { - sljit_ub* inst; + sljit_u8* inst; CHECK_ERROR(); #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_x86_is_cmov_available()); - CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_INT_OP))); - CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_D_ORDERED); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg & ~SLJIT_INT_OP)); + CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_I32_OP))); + CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_ORDERED_F64); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg & ~SLJIT_I32_OP)); FUNCTION_CHECK_SRC(src, srcw); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " x86_cmov%s %s%s, ", - !(dst_reg & SLJIT_INT_OP) ? "" : ".i", - JUMP_PREFIX(type), jump_names[type & 0xff]); - sljit_verbose_reg(compiler, dst_reg & ~SLJIT_INT_OP); + !(dst_reg & SLJIT_I32_OP) ? "" : ".i", + jump_names[type & 0xff], JUMP_POSTFIX(type)); + sljit_verbose_reg(compiler, dst_reg & ~SLJIT_I32_OP); fprintf(compiler->verbose, ", "); sljit_verbose_param(compiler, src, srcw); fprintf(compiler->verbose, "\n"); @@ -2986,9 +3009,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_emit_cmov(struct sljit_compiler *com CHECK_EXTRA_REGS(src, srcw, (void)0); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = dst_reg & SLJIT_INT_OP; + compiler->mode32 = dst_reg & SLJIT_I32_OP; #endif - dst_reg &= ~SLJIT_INT_OP; + dst_reg &= ~SLJIT_I32_OP; if (SLJIT_UNLIKELY(src & SLJIT_IMM)) { EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcw); diff --git a/pcre2-10.21/src/sljit/sljitUtils.c b/pcre2-10.22/src/sljit/sljitUtils.c similarity index 97% rename from pcre2-10.21/src/sljit/sljitUtils.c rename to pcre2-10.22/src/sljit/sljitUtils.c index 5294b5f3f..ec5c32119 100644 --- a/pcre2-10.21/src/sljit/sljitUtils.c +++ b/pcre2-10.22/src/sljit/sljitUtils.c @@ -163,11 +163,11 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void) #include /* Some old systems does not have MAP_ANON. */ -static sljit_si dev_zero = -1; +static sljit_s32 dev_zero = -1; #if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED) -static SLJIT_INLINE sljit_si open_dev_zero(void) +static SLJIT_INLINE sljit_s32 open_dev_zero(void) { dev_zero = open("/dev/zero", O_RDWR); return dev_zero < 0; @@ -179,10 +179,13 @@ static SLJIT_INLINE sljit_si open_dev_zero(void) static pthread_mutex_t dev_zero_mutex = PTHREAD_MUTEX_INITIALIZER; -static SLJIT_INLINE sljit_si open_dev_zero(void) +static SLJIT_INLINE sljit_s32 open_dev_zero(void) { pthread_mutex_lock(&dev_zero_mutex); - dev_zero = open("/dev/zero", O_RDWR); + /* The dev_zero might be initialized by another thread during the waiting. */ + if (dev_zero < 0) { + dev_zero = open("/dev/zero", O_RDWR); + } pthread_mutex_unlock(&dev_zero_mutex); return dev_zero < 0; } diff --git a/pcre2-10.21/test-driver b/pcre2-10.22/test-driver similarity index 100% rename from pcre2-10.21/test-driver rename to pcre2-10.22/test-driver diff --git a/po/de.po b/po/de.po index 1a283518d..1508b61b3 100644 --- a/po/de.po +++ b/po/de.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: de\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-04-13 22:15+0800\n" +"POT-Creation-Date: 2017-01-10 20:05+0100\n" "PO-Revision-Date: 2013-11-01 18:36+0100\n" -"Last-Translator: Benjamin\n" +"Last-Translator: Fabian Homborg\n" "Language-Team: deutsch \n" "Language: \n" "MIME-Version: 1.0\n" @@ -18,1633 +18,1881 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Lokalize 1.5\n" -#: autoload.cpp:113 -#, c-format -msgid "Could not autoload item '%ls', it is already being autoloaded. " -msgstr "" - -#: builtin.cpp:84 -#, c-format -msgid "Send job %d, '%ls' to foreground\n" -msgstr "Job %d, '%ls' in den Vordergrund schicken\n" - -#: builtin.cpp:352 -#, c-format -msgid "" -"%ls: Type 'help %ls' for related documentation\n" -"\n" -msgstr "" - -#: builtin.cpp:531 -#, c-format -msgid "%ls: No key with name '%ls' found\n" -msgstr "" - -#: builtin.cpp:537 -#, fuzzy, c-format -msgid "%ls: Key with name '%ls' does not have any mapping\n" -msgstr "%ls: Funktion '%ls' existiert nicht\n" - -#: builtin.cpp:543 -#, fuzzy, c-format -msgid "%ls: Unknown error trying to bind to key named '%ls'\n" -msgstr "%ls: Unbekannte Option '%ls'\n" - -#: builtin.cpp:794 -#, fuzzy, c-format -msgid "%ls: No binding found for key '%ls'\n" -msgstr "Beschreibung des mime-Typs ausgeben" - -#: builtin.cpp:798 -#, c-format -msgid "%ls: No binding found for sequence '%ls'\n" -msgstr "" - -#: builtin.cpp:834 -#, fuzzy, c-format -msgid "%ls: Invalid state\n" -msgstr "%ls: Ungültiger Indexstart bei '%ls'\n" - -#: builtin.cpp:939 -#, c-format -msgid "%ls: Can not specify scope when removing block\n" -msgstr "%ls: Bei Blocklöschung kann kein Bereich angegeben werden\n" - -#: builtin.cpp:945 -#, c-format -msgid "%ls: No blocks defined\n" -msgstr "%ls: Keine Blöcke definiert\n" - -#: builtin.cpp:1556 builtin.h:32 -#, c-format -msgid "%ls: Invalid combination of options\n" -msgstr "%ls: Ungültige Kombination der Optionen\n" - -#: builtin.cpp:1578 -#, c-format -msgid "%ls: Expected exactly one function name\n" -msgstr "%ls: Erwartete genau einen Funktionsnamen\n" - -#: builtin.cpp:1588 builtin.cpp:1650 -#, c-format -msgid "%ls: Function '%ls' does not exist\n" -msgstr "%ls: Funktion '%ls' existiert nicht\n" - -#: builtin.cpp:1638 -#, fuzzy, c-format -msgid "" -"%ls: Expected exactly two names (current function name, and new function " -"name)\n" -msgstr "%ls: Erwartete genau einen Funktionsnamen\n" - -#: builtin.cpp:1661 builtin.cpp:2230 -#, c-format -msgid "%ls: Illegal function name '%ls'\n" -msgstr "%ls: Ungültiger Funktionsname '%ls'\n" - -#: builtin.cpp:1672 -#, fuzzy, c-format -msgid "%ls: Function '%ls' already exists. Cannot create copy '%ls'\n" -msgstr "%ls: Funktion '%ls' existiert nicht\n" - -#: builtin.cpp:2070 -#, c-format -msgid "%ls: Unknown signal '%ls'\n" -msgstr "%ls: Unbekanntes Signal '%ls'\n" - -#: builtin.cpp:2085 builtin.cpp:2195 builtin.cpp:2263 -#, c-format -msgid "%ls: Invalid variable name '%ls'\n" -msgstr "%ls: Ungültiger Variablenname '%ls'\n" - -#: builtin.cpp:2138 -#, c-format -msgid "%ls: Cannot find calling job for event handler\n" -msgstr "%ls: Kann aufrufenden Job zur Ereignisbehandlung nicht finden\n" - -#: builtin.cpp:2156 -#, c-format -msgid "%ls: Invalid process id %ls\n" -msgstr "%ls: Ungültige Prozesskennung %ls\n" - -#: builtin.cpp:2223 -#, fuzzy, c-format -msgid "%ls: Expected function name\n" -msgstr "%ls: Erwartete genau einen Funktionsnamen\n" - -#: builtin.cpp:2240 -#, c-format -msgid "" -"%ls: The name '%ls' is reserved,\n" -"and can not be used as a function name\n" -msgstr "" -"%ls: Der Name '%ls' ist reserviert,\n" -"und kann nicht als Funktionsname benutzt werden\n" - -#: builtin.cpp:2248 -#, fuzzy, c-format -msgid "%ls: No function name given\n" -msgstr "%ls: Ungültiger Funktionsname '%ls'\n" - -#: builtin.cpp:2276 -#, c-format -msgid "%ls: Expected one argument, got %d\n" -msgstr "%ls: Erwartete ein Argument, erhielt %d\n" - -#: builtin.cpp:2412 -#, c-format -msgid "%ls: Seed value '%ls' is not a valid number\n" -msgstr "%ls: Seed-Wert '%ls' ist keine gültige Zahl\n" - -#: builtin.cpp:2426 -#, c-format -msgid "%ls: Expected zero or one argument, got %d\n" -msgstr "%ls: Erwartete kein oder ein Argument, erhielt %d\n" - -#: builtin.cpp:2593 -#, fuzzy, c-format -msgid "%ls: Argument '%ls' is out of range\n" -msgstr "%ls: Argument '%ls' muss eine Ganzzahl sein\n" - -#: builtin.cpp:2601 builtin.cpp:3150 builtin.cpp:3817 -#, c-format -msgid "%ls: Argument '%ls' must be an integer\n" -msgstr "%ls: Argument '%ls' muss eine Ganzzahl sein\n" - -#: builtin.cpp:2656 -#, fuzzy, c-format -msgid "%ls: --array option requires a single variable name.\n" -msgstr "" -"%ls: Erase benötigt einen Variablennamen\n" -"%ls\n" - -#: builtin.cpp:3065 fish.cpp:620 parser.cpp:764 -#, fuzzy -msgid "Standard input" -msgstr "Standardmodus" - -#: builtin.cpp:3108 -#, fuzzy -msgid "This is a login shell\n" -msgstr "Login-Shell erstellen" - -#: builtin.cpp:3110 -#, fuzzy -msgid "This is not a login shell\n" -msgstr "Login-Shell erstellen" - -#: builtin.cpp:3112 -#, c-format -msgid "Job control: %ls\n" -msgstr "" - -#: builtin.cpp:3113 -#, fuzzy -msgid "Only on interactive jobs" -msgstr "Ausführung im interaktiven Modus" - -#: builtin.cpp:3114 -msgid "Never" -msgstr "" - -#: builtin.cpp:3114 -msgid "Always" -msgstr "" - -#: builtin.cpp:3192 -#, c-format -msgid "%ls: Could not find home directory\n" -msgstr "%ls: Konnte Startverzeichnis nicht finden\n" - -#: builtin.cpp:3212 builtin.cpp:3266 -#, c-format -msgid "%ls: '%ls' is not a directory\n" -msgstr "%ls: '%ls' ist kein Verzeichnis\n" - -#: builtin.cpp:3219 -#, fuzzy, c-format -msgid "%ls: The directory '%ls' does not exist\n" -msgstr "%ls: Funktion '%ls' existiert nicht\n" - -#: builtin.cpp:3226 -#, fuzzy, c-format -msgid "%ls: '%ls' is a rotten symlink\n" -msgstr "%ls: '%ls' ist keine Datei\n" - -#: builtin.cpp:3234 -#, fuzzy, c-format -msgid "%ls: Unknown error trying to locate directory '%ls'\n" -msgstr "%ls: Unbekannte Option '%ls'\n" - -#: builtin.cpp:3257 -#, fuzzy, c-format -msgid "%ls: Permission denied: '%ls'\n" -msgstr "%ls: Ungültiger Funktionsname '%ls'\n" - -#: builtin.cpp:3281 -#, c-format -msgid "%ls: Could not set PWD variable\n" -msgstr "%ls: Konnte PWD-Variable nicht festlegen\n" - -#: builtin.cpp:3368 -#, fuzzy, c-format -msgid "%ls: Key not specified\n" -msgstr "%s: Schlüssel nicht angegeben\\n" - -#: builtin.cpp:3412 builtin.cpp:3420 -#, fuzzy, c-format -msgid "%ls: Error encountered while sourcing file '%ls':\n" -msgstr "%ls: Fehler beim Lesen der Datei '%ls'\n" - -#: builtin.cpp:3428 -#, c-format -msgid "%ls: '%ls' is not a file\n" -msgstr "%ls: '%ls' ist keine Datei\n" - -#: builtin.cpp:3447 -#, c-format -msgid "%ls: Error while reading file '%ls'\n" -msgstr "%ls: Fehler beim Lesen der Datei '%ls'\n" - -#: builtin.cpp:3503 builtin.cpp:3682 -#, fuzzy, c-format -msgid "%ls: There are no suitable jobs\n" -msgstr "%ls: Es gibt keine Jobs\n" - -#: builtin.cpp:3531 -#, c-format -msgid "%ls: Ambiguous job\n" -msgstr "%ls: Mehrdeutiger Job\n" - -#: builtin.cpp:3537 builtin.cpp:3705 builtin_jobs.cpp:301 -#, c-format -msgid "%ls: '%ls' is not a job\n" -msgstr "%ls: '%ls' ist kein Job\n" - -#: builtin.cpp:3568 builtin_jobs.cpp:316 -#, c-format -msgid "%ls: No suitable job: %d\n" -msgstr "%ls: Kein passender Job: %d\n" - -#: builtin.cpp:3577 -#, c-format -msgid "" -"%ls: Can't put job %d, '%ls' to foreground because it is not under job " -"control\n" -msgstr "" - -#: builtin.cpp:3630 -#, c-format -msgid "%ls: Unknown job '%ls'\n" -msgstr "%ls: Unbekannter Job '%ls'\n" - -#: builtin.cpp:3639 -#, c-format -msgid "" -"%ls: Can't put job %d, '%ls' to background because it is not under job " -"control\n" -msgstr "" - -#: builtin.cpp:3649 -#, c-format -msgid "Send job %d '%ls' to background\n" -msgstr "Sende Job %d '%ls' in den Hintergrund\n" - -#: builtin.cpp:3688 -msgid "(default)" -msgstr "(Standard)" - -#: builtin.cpp:3760 -#, c-format -msgid "%ls: Not inside of loop\n" -msgstr "%ls: Nicht innerhalb einer Schleife\n" - -#: builtin.cpp:3827 builtin_complete.cpp:551 builtin.h:83 -#, c-format -msgid "%ls: Too many arguments\n" -msgstr "%ls: Zu viele Argumente\n" - -#: builtin.cpp:3845 -#, c-format -msgid "%ls: Not inside of function\n" -msgstr "%ls: Nicht innerhalb einer Funktion\n" - -#: builtin.cpp:4069 builtin.cpp:4113 -#, fuzzy -msgid "Test a condition" -msgstr "Konfigurationsoption festlegen" - -#: builtin.cpp:4070 -msgid "Try out the new parser" -msgstr "" - -#: builtin.cpp:4071 -msgid "Execute command if previous command suceeded" -msgstr "Befehl ausführen, wenn vorheriger Befehl fehlerfrei war" - -#: builtin.cpp:4072 -msgid "Create a block of code" -msgstr "Codeblock erstellen" - -#: builtin.cpp:4073 -msgid "Send job to background" -msgstr "Job in Hintergrund schicken" - -#: builtin.cpp:4074 -msgid "Handle fish key bindings" -msgstr "Fish-Tastenbelegungen bearbeiten" - -#: builtin.cpp:4075 -msgid "Temporarily block delivery of events" -msgstr "Ereignisweitergabe vorübergehend blockieren" - -#: builtin.cpp:4076 -msgid "Stop the innermost loop" -msgstr "Innerste Schleife beenden" - -#: builtin.cpp:4077 -msgid "" -"Temporarily halt execution of a script and launch an interactive debug prompt" -msgstr "" - -#: builtin.cpp:4078 -msgid "Run a builtin command instead of a function" -msgstr "Internen Befehl anstatt einer Funktion ausführen" - -#: builtin.cpp:4079 builtin.cpp:4112 -msgid "Conditionally execute a block of commands" -msgstr "Befehlsblock bedingt ausführen" - -#: builtin.cpp:4080 -msgid "Change working directory" -msgstr "Arbeitsverzeichnis wechseln" - -#: builtin.cpp:4081 -msgid "Run a program instead of a function or builtin" -msgstr "Programm statt Funktion oder internem Befehl ausführen" - -#: builtin.cpp:4082 -msgid "Set or get the commandline" -msgstr "Festlegen oder Abrufen der Befehlszeile" - -#: builtin.cpp:4083 -msgid "Edit command specific completions" -msgstr "Befehlsspezifische Erweiterungen bearbeiten" - -#: builtin.cpp:4084 -msgid "Search for a specified string in a list" -msgstr "" - -#: builtin.cpp:4085 -msgid "Skip the rest of the current lap of the innermost loop" -msgstr "Rest des aktuellen Durchlaufs der innersten Schleife überspringen" - -#: builtin.cpp:4086 -#, fuzzy -msgid "Count the number of arguments" -msgstr "Anzahl der Vorkommen ausgeben" - -#: builtin.cpp:4087 -#, fuzzy -msgid "Print arguments" -msgstr "Wortzählung ausgeben" - -#: builtin.cpp:4088 -msgid "Evaluate block if condition is false" -msgstr "Werte Block aus, wenn die Bedingung falsch ist" - -#: builtin.cpp:4089 -#, fuzzy -msgid "Emit an event" -msgstr "Debian-Version auslassen" - -#: builtin.cpp:4090 -msgid "End a block of commands" -msgstr "Befehlsblock beenden" - -#: builtin.cpp:4091 -msgid "Run command in current process" -msgstr "Befehl im aktuellen Prozess ausführen" - -#: builtin.cpp:4092 -msgid "Exit the shell" -msgstr "Shell verlassen" - -#: builtin.cpp:4093 -msgid "Return an unsuccessful result" -msgstr "" - -#: builtin.cpp:4094 -msgid "Send job to foreground" -msgstr "Job in Vordergrund schicken" - -#: builtin.cpp:4095 -msgid "Perform a set of commands multiple times" -msgstr "Eine Befehlsfolge mehrmals ausführen" - -#: builtin.cpp:4096 -msgid "Define a new function" -msgstr "Neue Funktion definieren" - -#: builtin.cpp:4097 -msgid "List or remove functions" -msgstr "Funktionen auflisten oder entfernen" - -#: builtin.cpp:4098 -msgid "History of commands executed by user" -msgstr "" - -#: builtin.cpp:4099 -msgid "Evaluate block if condition is true" -msgstr "Block auswerten, wenn Bedingung wahr ist" - -#: builtin.cpp:4100 -msgid "Print currently running jobs" -msgstr "Derzeit laufende Jobs ausgeben" - -#: builtin.cpp:4101 -msgid "Negate exit status of job" -msgstr "Exit-Status des Jobs verneinen" - -#: builtin.cpp:4102 -msgid "Execute command if previous command failed" -msgstr "Befehl ausführen, wenn vorheriger Befehl fehlerhaft war" - -#: builtin.cpp:4103 -#, fuzzy -msgid "Prints formatted text" -msgstr "Befehlstyp ausgeben" - -#: builtin.cpp:4104 -#, fuzzy -msgid "Print the working directory" -msgstr "Arbeitsverzeichnis ausgeben" - -#: builtin.cpp:4105 -msgid "Generate random number" -msgstr "Zufallszahl generieren" - -#: builtin.cpp:4106 -msgid "Read a line of input into variables" -msgstr "Eine Eingabezeile in Variablen einlesen" - -#: builtin.cpp:4107 -msgid "Stop the currently evaluated function" -msgstr "Derzeit ausgewertete Funktion stoppen" - -#: builtin.cpp:4108 -msgid "Handle environment variables" -msgstr "Behandlung von Umgebungsvariablen" - -#: builtin.cpp:4109 -msgid "Set the terminal color" -msgstr "" - -#: builtin.cpp:4110 -msgid "Evaluate contents of file" -msgstr "Inhalt einer Datei auswerten" - -#: builtin.cpp:4111 -msgid "Return status information about fish" -msgstr "Statusinformation über Fish zurückgeben" - -#: builtin.cpp:4114 -msgid "Return a successful result" -msgstr "" - -#: builtin.cpp:4115 -msgid "Set or get the shells resource usage limits" -msgstr "Die Ressourcengrenzen der Shell festlegen/abrufen" - -#: builtin.cpp:4116 -msgid "Perform a command multiple times" -msgstr "Einen Befehl mehrmals ausführen" - -#: builtin_commandline.cpp:466 -#, fuzzy, c-format -msgid "%ls: Unknown input function '%ls'\n" -msgstr "%ls: Unbekannte Option '%ls'\n" - -#: builtin_jobs.cpp:87 -msgid "Job\tGroup\t" -msgstr "Job\tGruppe\t" - -#: builtin_jobs.cpp:89 -msgid "CPU\t" -msgstr "CPU\t" - -#: builtin_jobs.cpp:91 -msgid "State\tCommand\n" -msgstr "Status\tBefehl\n" - -#: builtin_jobs.cpp:99 proc.cpp:843 -msgid "stopped" -msgstr "gestoppt" - -#: builtin_jobs.cpp:99 -msgid "running" -msgstr "aktiv" - -#: builtin_jobs.cpp:113 -msgid "Group\n" -msgstr "Gruppe\n" - -#: builtin_jobs.cpp:126 -#, fuzzy -msgid "Process\n" -msgstr "Prozess\n" - -#: builtin_jobs.cpp:143 -msgid "Command\n" -msgstr "Befehl\n" - -#: builtin_jobs.cpp:344 -#, c-format -msgid "%ls: There are no jobs\n" -msgstr "%ls: Es gibt keine Jobs\n" - -#: builtin_printf.cpp:175 -#, c-format -msgid "" -"warning: %ls: character(s) following character constant have been ignored" -msgstr "" - -#: builtin_printf.cpp:256 -#, fuzzy, c-format -msgid "%ls: expected a numeric value" -msgstr "%ls: Argument erwartet\n" - -#: builtin_printf.cpp:258 -#, c-format -msgid "%ls: value not completely converted" -msgstr "" - -#: builtin_printf.cpp:359 -msgid "missing hexadecimal number in escape" -msgstr "" - -#: builtin_printf.cpp:388 -msgid "Missing hexadecimal number in Unicode escape" -msgstr "" - -#: builtin_printf.cpp:402 -#, c-format -msgid "Unicode character out of range: \\%c%0*x" -msgstr "" - -#: builtin_printf.cpp:670 -#, c-format -msgid "invalid field width: %ls" -msgstr "" - -#: builtin_printf.cpp:708 -#, fuzzy, c-format -msgid "invalid precision: %ls" -msgstr "%ls: Ungültige Prozesskennung %ls\n" - -#: builtin_printf.cpp:739 -#, fuzzy, c-format -msgid "%.*ls: invalid conversion specification" -msgstr "%ls: Ungültige Kombination der Optionen\n" - -#: builtin_printf.cpp:771 -#, fuzzy -msgid "printf: not enough arguments" -msgstr "Dateiargumente nicht sortieren" - -#: builtin_set.cpp:155 -#, fuzzy, c-format -msgid "%ls: Tried to change the read-only variable '%ls'\n" -msgstr "%ls: Fehler beim Lesen der Datei '%ls'\n" - -#: builtin_set.cpp:162 -#, fuzzy, c-format -msgid "%ls: Tried to set the special variable '%ls' with the wrong scope\n" -msgstr "%ls: Fehler beim Lesen der Datei '%ls'\n" - -#: builtin_set.cpp:169 -#, fuzzy, c-format -msgid "%ls: Tried to set the special variable '%ls' to an invalid value\n" -msgstr "%ls: Fehler beim Lesen der Datei '%ls'\n" - -#: builtin_set.cpp:221 -#, c-format -msgid "%ls: Multiple variable names specified in single call (%ls and %.*ls)\n" -msgstr "" - -#: builtin_set.cpp:248 -#, c-format -msgid "%ls: Invalid index starting at '%ls'\n" -msgstr "%ls: Ungültiger Indexstart bei '%ls'\n" - -#: builtin_set.cpp:647 -#, fuzzy, c-format -msgid "%ls: Erase needs a variable name\n" -msgstr "" -"%ls: Erase benötigt einen Variablennamen\n" -"%ls\n" - -#: builtin_set.cpp:791 -#, fuzzy, c-format -msgid "%ls: Values cannot be specfied with erase\n" -msgstr "" -"%ls: Bei erase können keine Werte angegeben werden\n" -"%ls\n" - -#: builtin_set.cpp:817 -#, c-format -msgid "" -"%ls: Warning: universal scope selected, but a global variable '%ls' exists.\n" -msgstr "" - -#: builtin_set_color.cpp:144 builtin_set_color.cpp:166 -#, fuzzy, c-format -msgid "%ls: Unknown color '%ls'\n" -msgstr "%ls: Unbekannter Job '%ls'\n" - -#: builtin_set_color.cpp:153 -#, fuzzy, c-format -msgid "%ls: Expected an argument\n" -msgstr "%ls: Argument erwartet\n" - -#: builtin_set_color.cpp:173 -#, fuzzy, c-format -msgid "%ls: Could not set up terminal\n" -msgstr "Konnte Terminal nicht einrichten" - -#: common.cpp:1917 +#: src/common.cpp:1537 msgid "This is a bug. Break on bugreport to debug." msgstr "" -#: common.cpp:1936 +#: src/common.cpp:1538 +#, fuzzy, c-format +msgid "If you can reproduce it, please send a bug report to %s." +msgstr "" +"Wenn dieser Fehler reproduziert werden kann, senden Sie bitte einen " +"Fehlerbericht an %s." + +#: src/common.cpp:1548 msgid "empty" msgstr "leer" -#: complete.cpp:61 -#, c-format -msgid "Home for %ls" -msgstr "" - -#: complete.cpp:66 -#, fuzzy, c-format -msgid "Variable: %ls" -msgstr "Variable: " - -#: complete.cpp:901 complete.cpp:919 -msgid "Unknown option: " -msgstr "Unbekannte Option: " - -#: complete.cpp:923 -msgid "Multiple matches for option: " -msgstr "Mehrere Treffer für Option: " - -#: env.cpp:315 -msgid "Changing language to English" -msgstr "Sprachwechsel zu Deutsch" - -#: env.cpp:1180 -msgid "Tried to pop empty environment stack." -msgstr "Versuchte, einen leeren Umgebungsstack zu poppen." - -#: env_universal_common.cpp:617 path.cpp:279 -msgid "" -"Unable to create a configuration directory for fish. Your personal settings " -"will not be saved. Please set the $XDG_CONFIG_HOME variable to a directory " -"where the current user has write access." -msgstr "" - -#: event.cpp:178 -#, c-format -msgid "signal handler for %ls (%ls)" -msgstr "" - -#: event.cpp:182 -#, fuzzy, c-format -msgid "handler for variable '%ls'" -msgstr "Behandlung von Umgebungsvariablen" - -#: event.cpp:188 -#, c-format -msgid "exit handler for process %d" -msgstr "" - -#: event.cpp:194 event.cpp:205 -#, c-format -msgid "exit handler for job %d, '%ls'" -msgstr "" - -#: event.cpp:196 -#, c-format -msgid "exit handler for job with process group %d" -msgstr "" - -#: event.cpp:207 -#, c-format -msgid "exit handler for job with job id %d" -msgstr "" - -#: event.cpp:213 -#, c-format -msgid "handler for generic event '%ls'" -msgstr "" - -#: event.cpp:217 -#, fuzzy, c-format -msgid "Unknown event type '0x%x'" -msgstr "Unbekannter Typ %d bei Eingabeumleitung " - -#: event.cpp:613 -msgid "Signal list overflow. Signals have been ignored." -msgstr "Signallistenüberlauf. Signale wurden ignoriert." - -#: exec.cpp:57 -#, c-format -msgid "An error occurred while redirecting file descriptor %d" -msgstr "Fehler beim Umleiten des Dateideskriptors %d" - -#: exec.cpp:62 -#, fuzzy -msgid "An error occurred while writing output" -msgstr "Fehler beim Einrichten der Pipe aufgetreten" - -#: exec.cpp:67 -#, fuzzy, c-format -msgid "An error occurred while redirecting file '%s'" -msgstr "Fehler beim Umleiten der Datei '%ls'" - -#: exec.cpp:795 -#, c-format -msgid "Unknown function '%ls'" -msgstr "Unbekannte Funktion '%ls'" - -#: exec.cpp:943 -#, c-format -msgid "Unknown input redirection type %d" -msgstr "Unbekannter Typ %d bei Eingabeumleitung " - -#: expand.cpp:59 +#: src/expand.cpp:52 #, fuzzy msgid "Child process" -msgstr "Prozessor ausgeben" +msgstr "Kindprozess" -#: expand.cpp:64 +#: src/expand.cpp:55 #, fuzzy msgid "Process" msgstr "Prozess\n" -#: expand.cpp:69 +#: src/expand.cpp:58 msgid "Job" -msgstr "" +msgstr "Job" -#: expand.cpp:74 +#: src/expand.cpp:61 #, c-format msgid "Job: %ls" -msgstr "" +msgstr "Job: %ls" -#: expand.cpp:79 +#: src/expand.cpp:64 #, fuzzy msgid "Shell process" -msgstr "Preprozessoren" +msgstr "Shellprozess" -#: expand.cpp:84 +#: src/expand.cpp:67 #, fuzzy msgid "Last background job" -msgstr "In Hintergrund verzweigen" +msgstr "Letzter Hintergrundjob" -#: expand.cpp:1419 +#: src/expand.cpp:398 +#, c-format +msgid "Unexpected failure to convert pid '%ls' to integer\n" +msgstr "Unerwarteter Fehler beim Konvertieren von PID '%ls' zu einer Ganzzahl\n" + +#: src/expand.cpp:1009 #, fuzzy msgid "Mismatched brackets" -msgstr "Unpassendes Anführungszeichen" +msgstr "Unpassende Klammern" -#: fish.cpp:330 +#: src/fish.cpp:272 msgid "" "Old versions of fish appear to be running. You will not be able to share " "variable values between old and new fish sessions. For best results, restart " "all running instances of fish." -msgstr "" +msgstr "Alte Fishversionen scheinen zu laufen. Variablen können nicht" +"zwischen alten und neuen Instanzen geteilt werden. Wir empfehlen" +" alle laufenden Fishinstanzen neu zu starten." -#: fish.cpp:420 +#: src/fish.cpp:312 src/fish_indent.cpp:378 +msgid "getopt_long() unexpectedly returned zero\n" +msgstr "getopt_long() gab unerwartet null zurück\n" + +#: src/fish.cpp:330 src/fish_indent.cpp:422 src/fish_key_reader.cpp:351 #, c-format -msgid "Invalid value '%s' for debug level switch" -msgstr "" +msgid "Invalid value '%s' for debug-level flag" +msgstr "Ungültiger Wert '%s' für debug-level Option" -#: fish.cpp:461 mimedb.cpp:1343 +#: src/fish.cpp:357 #, c-format msgid "%s, version %s\n" -msgstr "" +msgstr "%s, version %s\n" -#: fish.cpp:516 +#: src/fish.cpp:371 src/fish_indent.cpp:437 src/fish_key_reader.cpp:366 +#, c-format +msgid "Invalid value '%s' for debug-stack-frames flag" +msgstr "Ungültiger Wert '%s' für debug-stack-frames Option" + +#: src/fish.cpp:447 msgid "Can not use the no-execute mode when running an interactive session" -msgstr "" +msgstr "Kann den no-execute Modus nicht in einer interaktiven Sitzung nutzen" -#: fish.cpp:619 +#: src/fish.cpp:520 #, fuzzy, c-format msgid "Error while reading file %ls\n" msgstr "%ls: Fehler beim Lesen der Datei '%ls'\n" -#: fish_indent.cpp:332 -#, c-format -msgid "%ls, version %s\n" -msgstr "" +#: src/fish.cpp:522 src/parser.cpp:533 src/builtin.cpp:2455 +#, fuzzy +msgid "Standard input" +msgstr "Standardeingabe" -#: input.cpp:483 input.cpp:493 +#: src/wgetopt.cpp:318 +#, fuzzy, c-format +msgid "%ls: Option '%ls' is ambiguous\n" +msgstr "%ls: Option '%ls' ist mehrdeutig\n" + +#: src/wgetopt.cpp:335 +#, fuzzy, c-format +msgid "%ls: Option '--%ls' doesn't allow an argument\n" +msgstr "%ls: Option '--%ls' erlaubt kein Argument\n" + +#: src/wgetopt.cpp:339 +#, fuzzy, c-format +msgid "%ls: Option '%lc%ls' doesn't allow an argument\n" +msgstr "%ls: Option '%lc%ls' erlaubt kein Argument\n" + +#: src/wgetopt.cpp:350 +#, fuzzy, c-format +msgid "%ls: Option '%ls' requires an argument\n" +msgstr "%ls: Option '%ls' benötigt ein Argument\n" + +#: src/wgetopt.cpp:371 +#, fuzzy, c-format +msgid "%ls: Unrecognized option '--%ls'\n" +msgstr "%ls: Unbekannte Option '%ls'\n" + +#: src/wgetopt.cpp:374 +#, fuzzy, c-format +msgid "%ls: Unrecognized option '%lc%ls'\n" +msgstr "%ls: Unbekannte Option '%ls'\n" + +#: src/wgetopt.cpp:392 +#, fuzzy, c-format +msgid "%ls: Invalid option -- %lc\n" +msgstr "%ls: Ungültige Option -- %lc\n" + +#: src/wgetopt.cpp:423 +#, fuzzy, c-format +msgid "%ls: Option requires an argument -- %lc\n" +msgstr "%ls: Option benötigt ein Argument -- %lc\n" + +#: src/input.cpp:359 msgid "Could not set up terminal" msgstr "Konnte Terminal nicht einrichten" -#: input.cpp:486 -#, c-format -msgid "Check that your terminal type, '%ls', is supported on this system" -msgstr "" +#: src/input.cpp:362 +#, fuzzy +msgid "TERM environment variable not set" +msgstr "TERM Umgebungsvariable nicht gesetzt" -#: input.cpp:488 -#, c-format -msgid "Attempting to use '%ls' instead" -msgstr "" +#: src/input.cpp:364 +#, fuzzy, c-format +msgid "TERM environment variable set to '%ls'" +msgstr "TERM Umgebungsvariable gesetzt auf '%ls'" -#: input.cpp:535 +#: src/input.cpp:365 +msgid "Check that this terminal type is supported on this system" +msgstr "Überprüfen sie das dieser Terminaltyp auf diesem System unterstützt wird" + +#: src/input.cpp:371 +#, c-format +msgid "" +"Could not set up terminal using the fallback terminal type '%ls' - exiting" +msgstr "" +"Konnte Terminal mit Fallbacktyp '%ls' nicht einrichten - beende" + +#: src/input.cpp:375 +#, c-format +msgid "Using fallback terminal type '%ls'" +msgstr "Benutze Fallbackterminaltyp '%ls'" + +#: src/input.cpp:403 #, fuzzy msgid "Error while closing terminfo" -msgstr "Fehler beim Schließen des Eingabestroms" +msgstr "Fehler beim Schließen von terminfo" -#: io.cpp:112 +#: src/complete.cpp:49 #, c-format -msgid "" -"An error occured while reading output from code block on file descriptor %d" -msgstr "Fehler beim Lesen der Ausgabe des Codeblocks auf Dateideskriptor %d" +msgid "Home for %ls" +msgstr "Heimordner für %ls" -#: mimedb.cpp:174 mimedb.cpp:188 mimedb.cpp:1179 -#, c-format -msgid "%s: Out of memory\n" -msgstr "" - -#: mimedb.cpp:463 +#: src/complete.cpp:52 #, fuzzy, c-format -msgid "%s: Unknown error in munge()\n" -msgstr "%ls: Unbekannte Option '%ls'\n" +msgid "Variable: %ls" +msgstr "Variable: %ls" -#: mimedb.cpp:481 -#, fuzzy, c-format -msgid "%s: Locale string too long\n" -msgstr "%ls: Parameter '%ls' ist zu lang\n" +#: src/wildcard.cpp:26 +msgid "Executable" +msgstr "Programm" -#: mimedb.cpp:551 mimedb.cpp:559 -#, c-format -msgid "%s: Could not compile regular expressions %s with error %s\n" -msgstr "" +#: src/wildcard.cpp:28 +msgid "Executable link" +msgstr "Programmlink" -#: mimedb.cpp:676 -#, fuzzy, c-format -msgid "%s: No description for type %s\n" -msgstr "Beschreibung des mime-Typs ausgeben" +#: src/wildcard.cpp:30 +msgid "File" +msgstr "Datei" -#: mimedb.cpp:744 -#, fuzzy, c-format -msgid "%s: Could not parse launcher string '%s'\n" -msgstr "Konnte Zeichenkette '%ls' nicht erweitern" +#: src/wildcard.cpp:32 +msgid "Character device" +msgstr "Zeichenorientiertes Gerät" -#: mimedb.cpp:780 -#, c-format -msgid "%s: Default launcher '%s' does not specify how to start\n" -msgstr "" +#: src/wildcard.cpp:34 +msgid "Block device" +msgstr "Blockorientiertes Gerät" -#: mimedb.cpp:1158 -#, c-format -msgid "%s: Unsupported switch '%c' in launch string '%s'\n" -msgstr "" +#: src/wildcard.cpp:36 +msgid "Fifo" +msgstr "Fifo" -#: mimedb.cpp:1354 -#, c-format -msgid "%s: Can not launch a mimetype\n" -msgstr "" +#: src/wildcard.cpp:38 +msgid "Symbolic link" +msgstr "Symbolischer Link" -#: mimedb.cpp:1382 -#, fuzzy, c-format -msgid "%s: Could not parse mimetype from argument '%s'\n" -msgstr "Konnte Sequenz '%ls' nicht auswerten" - -#: mimedb.cpp:1402 signal.cpp:407 signal.cpp:422 +#: src/wildcard.cpp:40 #, fuzzy -msgid "Unknown" -msgstr "unbekannt" +msgid "Symbolic link to directory" +msgstr "Symbolischer Link auf Ordner" -#: output.cpp:608 -#, c-format -msgid "" -"Tried to use terminfo string %s on line %ld of %s, which is undefined in " -"terminal of type \"%ls\". Please report this error to %s" -msgstr "" +#: src/wildcard.cpp:42 +msgid "Rotten symbolic link" +msgstr "Defekter symbolischer Link" -#: pager.cpp:24 -#, fuzzy -msgid "search: " -msgstr "Architektur festlegen" +#: src/wildcard.cpp:44 +msgid "Symbolic link loop" +msgstr "Schleife bei symbolischem Link" -#: pager.cpp:562 -#, c-format -msgid "%lsand 1 more row" -msgstr "" +#: src/wildcard.cpp:46 +msgid "Socket" +msgstr "Socket" -#: pager.cpp:566 -#, c-format -msgid "%lsand %lu more rows" -msgstr "" +#: src/wildcard.cpp:48 +msgid "Directory" +msgstr "Verzeichnis" -#: pager.cpp:571 -#, c-format -msgid "rows %lu to %lu of %lu" -msgstr "" - -#: pager.cpp:576 -#, fuzzy -msgid "(no matches)" -msgstr "Dateibeobachtungen festlegen" - -#: parse_execution.cpp:555 -#, fuzzy, c-format -msgid "switch: Expected exactly one argument, got %lu\n" -msgstr "%ls: Erwartete genau ein Argument, erhielt %d\n" - -#: parse_execution.cpp:799 -#, fuzzy, c-format -msgid "" -"Unknown command '%ls'. Did you mean to run %ls with a modified environment? " -"Try 'env %ls=%ls %ls%ls'. See the help section on the set command by typing " -"'help set'." -msgstr "" -"Unbekannter Befehl '%ls'. Meinten Sie 'set VARIABLE WERT'? Zu Informationen " -"zum Festlegen von Variablenwerten schauen Sie in der Hilfe zum set-Befehl " -"nach oder geben Sie 'help set' ein." - -#: parse_execution.cpp:824 -#, c-format -msgid "" -"Variables may not be used as commands. Instead, define a function like " -"'function %ls; %ls $argv; end' or use the eval builtin instead, like 'eval " -"%ls'. See the help section for the function command by typing 'help " -"function'." -msgstr "" - -#: parse_execution.cpp:833 -#, c-format -msgid "" -"Variables may not be used as commands. Instead, define a function or use the " -"eval builtin instead, like 'eval %ls'. See the help section for the function " -"command by typing 'help function'." -msgstr "" - -#: parse_execution.cpp:841 -#, fuzzy, c-format -msgid "" -"Commands may not contain variables. Use the eval builtin instead, like 'eval " -"%ls'. See the help section for the eval command by typing 'help eval'." -msgstr "" -"Unbekannter Befehl '%ls'. Meinten Sie 'set VARIABLE WERT'? Zu Informationen " -"zum Festlegen von Variablenwerten schauen Sie in der Hilfe zum set-Befehl " -"nach oder geben Sie 'help set' ein." - -#: parse_execution.cpp:848 -#, c-format -msgid "The file '%ls' is not executable by this user" -msgstr "" - -#: parse_execution.cpp:1057 -#, fuzzy, c-format -msgid "Invalid redirection target: %ls" -msgstr "Ungültige Umleitung" - -#: parse_execution.cpp:1081 -#, fuzzy, c-format -msgid "Requested redirection to '%ls', which is not a valid file descriptor" -msgstr "Angeforderte Umleitung auf etwas, das kein Dateideskriptor ist %ls" - -#: parse_util.cpp:46 -#, fuzzy, c-format -msgid "The '%ls' command can not be used in a pipeline" -msgstr "Dieser Befehl kann nicht in einer Pipe benutzt werden" - -#: parse_util.cpp:49 -#, fuzzy, c-format -msgid "The '%ls' command can not be used immediately after a backgrounded job" -msgstr "Dieser Befehl kann nicht in einer Pipe benutzt werden" - -#: parse_util.cpp:52 -#, fuzzy -msgid "Backgrounded commands can not be used as conditionals" -msgstr "Dieser Befehl kann nicht in einer Pipe benutzt werden" - -#: parser.cpp:52 -#, c-format -msgid "Tokenizer error: '%ls'" -msgstr "Tokenizer-Fehler: '%ls'" - -#: parser.cpp:57 -#, c-format -msgid "Tried to evaluate commands using invalid block type '%ls'" -msgstr "Versuchte, Befehle mittels des ungültigen Blocktyps '%ls' auszuwerten" - -#: parser.cpp:62 -#, c-format -msgid "Unexpected token of type '%ls'" -msgstr "Unerwartetes Zeichen des Typs '%ls'" - -#: parser.cpp:67 parse_constants.h:255 -msgid "'while' block" -msgstr "'while'-Block" - -#: parser.cpp:72 parse_constants.h:260 -msgid "'for' block" -msgstr "'for'-Block" - -#: parser.cpp:77 parse_constants.h:265 -msgid "block created by breakpoint" -msgstr "block created by breakpoint" - -#: parser.cpp:82 parse_constants.h:272 -msgid "'if' conditional block" -msgstr "'if'-Bedingungsblock" - -#: parser.cpp:87 parse_constants.h:278 -msgid "function definition block" -msgstr "Funktionsdefinitonsblock" - -#: parser.cpp:92 parse_constants.h:284 -msgid "function invocation block" -msgstr "Funktionsausführungsblock" - -#: parser.cpp:97 parse_constants.h:289 -#, fuzzy -msgid "function invocation block with no variable shadowing" -msgstr "Funktionsausführungsblock" - -#: parser.cpp:102 parse_constants.h:295 -msgid "'switch' block" -msgstr "'switch'-Block" - -#: parser.cpp:107 parse_constants.h:301 -msgid "unexecutable block" -msgstr "nicht ausführbarer Block" - -#: parser.cpp:112 parse_constants.h:307 -msgid "global root block" -msgstr "globaler Root-Block" - -#: parser.cpp:117 parse_constants.h:313 -msgid "command substitution block" -msgstr "Befehlsersetzungsblock" - -#: parser.cpp:122 parse_constants.h:319 -msgid "'begin' unconditional block" -msgstr "'begin' unbedingter Block" - -#: parser.cpp:127 parse_constants.h:325 -msgid "block created by the . builtin" -msgstr "block created by the . builtin" - -#: parser.cpp:132 parse_constants.h:330 -#, fuzzy -msgid "event handler block" -msgstr "nicht ausführbarer Block" - -#: parser.cpp:137 parse_constants.h:336 -msgid "unknown/invalid block" -msgstr "unbekannter/ungültiger Block" - -#: parser.cpp:474 -#, c-format -msgid "Could not write profiling information to file '%s'" -msgstr "Konnte Profilierungsinformationen nicht in Datei '%s' schreiben" - -#: parser.cpp:480 -msgid "Time\tSum\tCommand\n" -msgstr "Zeit\tSum\tBefehl\n" - -#: parser.cpp:562 -#, c-format -msgid "in event handler: %ls\n" -msgstr "" - -#: parser.cpp:590 -#, c-format -msgid "from sourcing file %ls\n" -msgstr "" - -#: parser.cpp:597 -#, fuzzy, c-format -msgid "in function '%ls'\n" -msgstr "Unbekannte Funktion '%ls'" - -#: parser.cpp:602 -#, fuzzy -msgid "in command substitution\n" -msgstr "Befehlsersetzungsblock" - -#: parser.cpp:615 -#, c-format -msgid "\tcalled on line %d of file %ls\n" -msgstr "" - -#: parser.cpp:621 -msgid "\tcalled during startup\n" -msgstr "" - -#: parser.cpp:625 -msgid "\tcalled on standard input\n" -msgstr "" - -#: parser.cpp:642 -#, c-format -msgid "\twith parameter list '%ls'\n" -msgstr "" - -#: parser.cpp:756 -#, c-format -msgid "%ls (line %d): " -msgstr "%ls (Zeile %d): " - -#: parser.cpp:760 -msgid "Startup" -msgstr "" - -#: parser.cpp:803 -msgid "Job inconsistency" -msgstr "Jobinkonsistenz" - -#: parser.cpp:956 -msgid "End of block mismatch. Program terminating." -msgstr "Unpassendes Blockende. Programm wird beendet." - -#: parser.cpp:1047 -#, fuzzy, c-format -msgid "%ls (line %lu): " -msgstr "%ls (Zeile %d): " - -#: parser.cpp:1051 -#, c-format -msgid "%ls: " -msgstr "" - -#: path.cpp:24 -#, c-format -msgid "Error while searching for command '%ls'" -msgstr "Fehler beim Suchen des Befehls '%ls'" - -#: proc.cpp:690 +#: src/proc.cpp:500 #, fuzzy, c-format msgid "'%ls' has %ls" -msgstr "Job %d, '%ls' hat %ls" +msgstr "'%ls' hat %ls" -#: proc.cpp:694 +#: src/proc.cpp:502 #, c-format msgid "Job %d, '%ls' has %ls" msgstr "Job %d, '%ls' hat %ls" -#: proc.cpp:786 +#: src/proc.cpp:599 #, fuzzy, c-format msgid "%ls: %ls'%ls' terminated by signal %ls (%ls)" msgstr "%ls: Job %d, '%ls' durch Signal %ls (%ls) beendet" -#: proc.cpp:797 +#: src/proc.cpp:606 #, fuzzy, c-format msgid "%ls: Process %d, '%ls' %ls'%ls' terminated by signal %ls (%ls)" msgstr "" "%ls: Prozess %d, '%ls' aus job %d, '%ls' durch Signal %ls (%ls) beendet" -#: proc.cpp:828 +#: src/proc.cpp:629 msgid "ended" msgstr "beendet" -#: proc.cpp:1065 +#: src/proc.cpp:639 src/builtin_jobs.cpp:68 +msgid "stopped" +msgstr "gestoppt" + +#: src/proc.cpp:778 msgid "An error occured while reading output from code block" msgstr "Fehler während des Lesens der Ausgabe aus Codeblock" -#: proc.cpp:1094 proc.cpp:1106 +#: src/proc.cpp:797 src/proc.cpp:804 #, c-format msgid "Could not send job %d ('%ls') to foreground" msgstr "Konnte Job %d ('%ls') nicht in den Vordergrund schicken" -#: proc.cpp:1126 proc.cpp:1136 proc.cpp:1151 +#: src/proc.cpp:816 src/proc.cpp:824 src/proc.cpp:836 msgid "Could not return shell to foreground" msgstr "Konnte Shell nicht wieder in Vordergrund zurückholen" -#: proc.cpp:1354 proc.cpp:1380 +#: src/proc.cpp:987 src/proc.cpp:1005 msgid "Process list pointer" msgstr "Zeiger auf Prozessliste" -#: proc.cpp:1365 +#: src/proc.cpp:992 #, c-format msgid "More than one job in foreground: job 1: '%ls' job 2: '%ls'" msgstr "Mehr als ein Job im Vordergrund: Job 1: '%ls' Job 2: '%ls'" -#: proc.cpp:1378 +#: src/proc.cpp:1003 msgid "Process argument list" msgstr "Prozessargumentliste" -#: proc.cpp:1379 +#: src/proc.cpp:1004 msgid "Process name" msgstr "Prozessname" -#: proc.cpp:1385 +#: src/proc.cpp:1008 #, c-format msgid "Job '%ls', process '%ls' has inconsistent state 'stopped'=%d" msgstr "Job '%ls', Prozess '%ls' hat inkonsistenten Status 'stopped'=%d" -#: proc.cpp:1395 +#: src/proc.cpp:1014 #, c-format msgid "Job '%ls', process '%ls' has inconsistent state 'completed'=%d" msgstr "Job '%ls', Prozess '%ls' hat inkonsistenten Status 'completed'=%d" -#: reader.cpp:478 +#: src/parse_util.cpp:28 +#, fuzzy, c-format +msgid "The '%ls' command can not be used in a pipeline" +msgstr "Befehl '%ls' kann nicht in einer Pipe benutzt werden" + +#: src/parse_util.cpp:32 +#, fuzzy, c-format +msgid "The '%ls' command can not be used immediately after a backgrounded job" +msgstr "Befehl '%ls' kann nicht direkt nach einem Hintergrundjob benutzt werden" + +#: src/parse_util.cpp:36 +#, fuzzy +msgid "Backgrounded commands can not be used as conditionals" +msgstr "Hintergrundkommandos können nicht als Bedingung verwendet werden" + +#: src/wutil.cpp:137 +#, c-format +msgid "getcwd() failed with errno %d/%s" +msgstr "getcwd() schlug mit errno %s/%s fehl" + +#: src/reader.cpp:323 msgid "Could not set terminal mode for new job" msgstr "Konnte Terminalmodus für neuen Job nicht festlegen" -#: reader.cpp:525 +#: src/reader.cpp:352 msgid "Could not set terminal mode for shell" msgstr "Konnte Terminalmodus für neue Shell nicht festlegen" -#: reader.cpp:2059 +#: src/reader.cpp:1621 msgid "No TTY for interactive shell (tcgetpgrp failed)" -msgstr "" +msgstr "Kein TTY für interaktive Shell (tcgetpgrp schlug fehl)" -#: reader.cpp:2074 +#: src/reader.cpp:1630 #, c-format msgid "" "I appear to be an orphaned process, so I am quitting politely. My pid is %d." msgstr "" +"Ich scheine ein verwaister Prozess zu sein, also beende ich mich höflich. Meine PID ist %d." -#: reader.cpp:2105 +#: src/reader.cpp:1655 msgid "Couldn't put the shell in its own process group" msgstr "Konnte Shell nicht in ihre eigene Prozessgruppe verschieben" -#: reader.cpp:2115 +#: src/reader.cpp:1663 msgid "Couldn't grab control of terminal" msgstr "Konnte Terminalsteuerung nicht übernehmen" -#: reader.cpp:2616 +#: src/reader.cpp:2042 msgid "Pop null reader block" msgstr "" -#: reader.cpp:2882 -msgid "" -"There are stopped jobs. A second attempt to exit will enforce their " -"termination.\n" -msgstr "" +#: src/reader.cpp:2254 +msgid "There are still jobs active (use the jobs command to see them).\n" +msgstr "Es gibt noch aktive jobs (benutzen sie den 'jobs' Befehl um sie zu sehen.\n" -#: reader.cpp:4115 +#: src/reader.cpp:2255 +msgid "A second attempt to exit will terminate them.\n" +msgstr "Ein zweites 'exit' wird sie beenden.\n" + +#: src/reader.cpp:3250 #, c-format msgid "Unknown key binding 0x%X" msgstr "Unbekannte Tastenkombination 0x%X" -#: reader.cpp:4226 +#: src/reader.cpp:3339 #, fuzzy msgid "Error while reading from file descriptor" -msgstr "Fehler beim Lesen der Befehle" +msgstr "Fehler beim Lesen von Dateideskriptor" -#: reader.cpp:4243 +#: src/reader.cpp:3353 msgid "Error while closing input stream" msgstr "Fehler beim Schließen des Eingabestroms" -#: reader.cpp:4270 +#: src/reader.cpp:3374 msgid "Error while opening input stream" msgstr "Fehler beim Öffnen des Eingabestroms" -#: sanity.cpp:37 -#, fuzzy -msgid "Errors detected, shutting down. Break on sanity_lose() to debug." -msgstr "Fehler gefunden, Programmabbruch" - -#: sanity.cpp:65 +#: src/exec.cpp:42 #, c-format -msgid "The pointer '%ls' is invalid" -msgstr "Der Zeiger '%ls' ist ungültig" +msgid "An error occurred while redirecting file descriptor %d" +msgstr "Fehler beim Umleiten des Dateideskriptors %d" -#: sanity.cpp:71 +#: src/exec.cpp:45 +#, fuzzy +msgid "An error occurred while writing output" +msgstr "Fehler beim Schreiben der Ausgabe" + +#: src/exec.cpp:48 +#, fuzzy, c-format +msgid "An error occurred while redirecting file '%s'" +msgstr "Fehler beim Umleiten der Datei '%ls'" + +#: src/exec.cpp:634 #, c-format -msgid "The pointer '%ls' is null" -msgstr "Der Zeiger '%ls' ist null" +msgid "Unknown function '%ls'" +msgstr "Unbekannte Funktion '%ls'" -#: signal.cpp:69 -msgid "Terminal hung up" -msgstr "Terminal getrennt" +#: src/exec.cpp:750 +#, c-format +msgid "Unknown input redirection type %d" +msgstr "Unbekannter Typ %d bei Eingabeumleitung " -#: signal.cpp:77 -msgid "Quit request from job control (^C)" -msgstr "Quit-Anforderung über Jobsteuerung (^C)" +#: src/parse_execution.cpp:548 +#, fuzzy, c-format +msgid "switch: Expected exactly one argument, got %lu\n" +msgstr "switch: Erwartete genau ein Argument, erhielt %lu\n" -#: signal.cpp:85 -msgid "Quit request from job control with core dump (^\\)" -msgstr "Quit-Anforderung über Jobsteuerung mit Speicherauszug (^\\)" +#: src/parse_execution.cpp:785 +#, c-format +msgid "" +"Variables may not be used as commands. In fish, please define a function or " +"use 'eval %ls'." +msgstr "" +"Variablen dürfen nicht als Befehl verwendet werden. In fish, benutzen sie " +"eine Funktion oder 'eval %ls'." -#: signal.cpp:93 -msgid "Illegal instruction" -msgstr "Illegale Instruktion" +#: src/parse_execution.cpp:789 +#, c-format +msgid "The file '%ls' is not executable by this user" +msgstr "Die Datei '%ls' kann von diesem Benutzer nicht ausgeführt werden" -#: signal.cpp:101 -msgid "Trace or breakpoint trap" -msgstr "Verfolgungs- oder Haltepunkt erreicht" +#: src/parse_execution.cpp:1005 +#, fuzzy, c-format +msgid "Invalid redirection target: %ls" +msgstr "Ungültiges Umleitungsziel: %ls" -#: signal.cpp:109 -msgid "Abort" -msgstr "Abbruch" +#: src/parse_execution.cpp:1019 +#, fuzzy, c-format +msgid "Requested redirection to '%ls', which is not a valid file descriptor" +msgstr "Angeforderte Umleitung auf etwas, das kein Dateideskriptor ist %ls" -#: signal.cpp:117 -msgid "Misaligned address error" -msgstr "Fehler: nicht ausgerichtete Adresse" +#: src/env_universal_common.cpp:476 +#, fuzzy, c-format +msgid "Unable to write to universal variables file '%ls': %s" +msgstr "Konnte nicht in die Datei für universelle Variablen '%ls' schreiben: %s" -#: signal.cpp:125 -msgid "Floating point exception" -msgstr "Fließkomma-Ausnahmefehler" +#: src/env_universal_common.cpp:496 +#, c-format +msgid "Unable to rename file from '%ls' to '%ls': %s" +msgstr "Konnte Datei '%ls' nicht zu '%ls' umbenennen: %s" -#: signal.cpp:133 -msgid "Forced quit" -msgstr "Erzwungene Beendigung" +#: src/env_universal_common.cpp:548 +#, fuzzy, c-format +msgid "Unable to open temporary file '%ls': %s" +msgstr "Konnte temporäre Datei '%ls' nicht öffnen: %s" -#: signal.cpp:141 -msgid "User defined signal 1" -msgstr "Benutzerdefiniertes Signal 1" +#: src/env_universal_common.cpp:558 +#, c-format +msgid "Locking the universal var file took too long (%.3f seconds)." +msgstr "Die Datei für universelle Variablen zu sperren dauerte zu lange (%.3f Sekunden)" -#: signal.cpp:148 -msgid "User defined signal 2" -msgstr "Benutzerdefiniertes Signal 2" +#: src/env_universal_common.cpp:610 +#, fuzzy, c-format +msgid "Unable to open universal variable file '%ls': %s" +msgstr "Konnte die Datei für universelle Variablen '%ls' nicht öffnen: %s" -#: signal.cpp:156 -msgid "Address boundary error" -msgstr "Adressbereichsfehler" +#: src/env_universal_common.cpp:983 +#, c-format +msgid "Unable to open shared memory with path '%s': %s" +msgstr "Konnte geteilten Speicher '%s' nicht öffnen: %s" -#: signal.cpp:164 -msgid "Broken pipe" -msgstr "zerstörte Pipe" +#: src/env_universal_common.cpp:993 +#, c-format +msgid "Unable to fstat shared memory object with path '%s': %s" +msgstr "Konnte fstat auf geteilten Speicher '%s' nicht ausführen: %s" -#: signal.cpp:172 -msgid "Timer expired" -msgstr "Zeitgeber abgelaufen" +#: src/env_universal_common.cpp:1004 +#, c-format +msgid "Unable to truncate shared memory object with path '%s': %s" +msgstr "Konnte geteilten Speicher '%s' nicht kürzen: %s" -#: signal.cpp:180 -msgid "Polite quit request" -msgstr "Höfliche Beendigungsanforderung" - -#: signal.cpp:188 -msgid "Child process status changed" -msgstr "Kindprozessstatus geändert" - -#: signal.cpp:196 -msgid "Continue previously stopped process" -msgstr "Vorher gestoppten Prozess fortsetzen" - -#: signal.cpp:204 -msgid "Forced stop" -msgstr "Erzwungener Stopp" - -#: signal.cpp:212 -msgid "Stop request from job control (^Z)" -msgstr "Stoppanforderung über Jobsteuerung (^Z)" - -#: signal.cpp:220 -msgid "Stop from terminal input" -msgstr "Stopp durch Terminaleingabe" - -#: signal.cpp:228 -msgid "Stop from terminal output" -msgstr "Stopp durch Terminalausgabe" - -#: signal.cpp:236 -msgid "Urgent socket condition" -msgstr "Vorrangige Socket-Bedingung" - -#: signal.cpp:244 -msgid "CPU time limit exceeded" -msgstr "CPU-Zeitbegrenzung überschritten" - -#: signal.cpp:252 -msgid "File size limit exceeded" -msgstr "Dateigrößenbegrenzung überschritten" - -#: signal.cpp:260 -msgid "Virtual timer expired" -msgstr "Virtueller Zeitgeber abgelaufen" - -#: signal.cpp:268 -msgid "Profiling timer expired" -msgstr "Profilierungszeitgeber abgelaufen" - -#: signal.cpp:276 signal.cpp:284 -msgid "Window size change" -msgstr "Änderung der Fenstergröße" - -#: signal.cpp:292 -msgid "I/O on asynchronous file descriptor is possible" -msgstr "E/A auf asynchronem Dateideskriptor ist möglich" - -#: signal.cpp:300 -msgid "Power failure" -msgstr "Stromausfall" - -#: signal.cpp:308 -msgid "Bad system call" -msgstr "Fehlerhafter Systemaufruf" - -#: signal.cpp:316 -msgid "Information request" +#: src/env_universal_common.cpp:1014 +#, c-format +msgid "Unable to memory map shared memory object with path '%s': %s" msgstr "" -#: signal.cpp:324 -msgid "Stack fault" +#: src/env_universal_common.cpp:1411 +#, fuzzy, c-format +msgid "Unable to make a pipe for universal variables using '%ls': %s" +msgstr "Konnte keine Pipe für universelle Variablen mit '%ls' erstellen: %s" + +#: src/env_universal_common.cpp:1420 +#, fuzzy, c-format +msgid "Unable to open a pipe for universal variables using '%ls': %s" +msgstr "Konnte keine Pipe für universelle Variablen mit '%ls' öffnen: %s" + +#: src/builtin_set.cpp:130 +#, fuzzy, c-format +msgid "%ls: Tried to change the read-only variable '%ls'\n" +msgstr "%ls: Versuchte read-only Variable '%ls' zu ändern\n" + +#: src/builtin_set.cpp:137 +#, fuzzy, c-format +msgid "%ls: Tried to set the special variable '%ls' with the wrong scope\n" +msgstr "%ls: Versuchte spezielle Variable '%ls' mit falscher Gültigkeit zu setzen\n" + +#: src/builtin_set.cpp:144 +#, fuzzy, c-format +msgid "%ls: Tried to set the special variable '%ls' to an invalid value\n" +msgstr "%ls: Versuchte spezielle Variable '%ls' auf ungültigen Wert zu setzen\n" + +#: src/builtin_set.cpp:186 +#, c-format +msgid "%ls: Multiple variable names specified in single call (%ls and %.*ls)\n" +msgstr "%ls: Mehrere Variablennamen in einem Aufruf angegeben (%ls und %.*ls)\n" + +#: src/builtin_set.cpp:198 +#, c-format +msgid "%ls: Invalid index starting at '%ls'\n" +msgstr "%ls: Ungültiger Indexstart bei '%ls'\n" + +#: src/builtin_set.cpp:502 +#, fuzzy, c-format +msgid "%ls: Erase needs a variable name\n" +msgstr "%ls: Erase benötigt einen Variablennamen\n" + +#: src/builtin_set.cpp:595 +#, fuzzy, c-format +msgid "%ls: Values cannot be specfied with erase\n" +msgstr "%ls: Bei erase können keine Werte angegeben werden\n" + +#: src/builtin_set.cpp:614 +#, c-format +msgid "" +"%ls: Warning: universal scope selected, but a global variable '%ls' exists.\n" msgstr "" +"%ls: Warnung: Universelle Gültigkeit gewählt, aber eine globale Variable '%ls' existiert.\n" -#: signal.cpp:332 -msgid "Emulator trap" +#: src/output.cpp:553 +#, c-format +msgid "" +"Tried to use terminfo string %s on line %ld of %s, which is undefined in " +"terminal of type \"%ls\". Please report this error to %s" msgstr "" +"Versuchte terminfo string %s auf Zeile %ld von %s zu verwenden, welches in " +"Terminals vom Typ \"%ls\" undefiniert ist\". Bitte melden sie diesen Fehler %s" -#: signal.cpp:340 -msgid "Abort (Alias for SIGABRT)" +#: src/history.cpp:136 +#, c-format +msgid "Locking the history file took too long (%.3f seconds)." +msgstr "Sperren der Geschichts-Datei dauerte zu lang (%.3f Sekunden)." + +#: src/path.cpp:25 +#, c-format +msgid "Error while searching for command '%ls'" +msgstr "Fehler beim Suchen des Befehls '%ls'" + +#: src/path.cpp:234 +#, fuzzy, c-format +msgid "Unable to locate the %ls directory." +msgstr "Konnte Verzeichnis %ls nicht finden." + +#: src/path.cpp:235 +#, c-format +msgid "Please set the %ls or HOME environment variable before starting fish." +msgstr "Bitte setzen sie %ls oder die HOME Umgebungsvariable bevor sie fish starten." + +#: src/path.cpp:240 +#, c-format +msgid "Unable to locate %ls directory derived from $%ls: '%ls'." +msgstr "Konnte Verzeichnis %ls abgeleitet von %ls nicht finden: '%ls'." + +#: src/path.cpp:242 +#, fuzzy, c-format +msgid "The error was '%s'." +msgstr "Der Fehler war: '%s'." + +#: src/path.cpp:243 +#, c-format +msgid "Please set $%ls to a directory where you have write access." +msgstr "Bitte setzen sie $%ls auf ein Verzeichnis in das sie schreiben können." + +#: src/path.cpp:294 +msgid "Your personal settings will not be saved." +msgstr "Ihre persönlichen Einstellungen werden NICHT gespeichert." + +#: src/path.cpp:309 +msgid "Your history will not be saved." +msgstr "Ihre Geschichte wird nicht gespeichert." + +#: src/builtin_test.cpp:648 +#, fuzzy, c-format +msgid "invalid integer '%ls'" +msgstr "Ungültige Ganzzahl '%ls'" + +#: src/builtin_set_color.cpp:140 src/builtin_set_color.cpp:158 +#, fuzzy, c-format +msgid "%ls: Unknown color '%ls'\n" +msgstr "%ls: Unbekannte Farbe '%ls'\n" + +#: src/builtin_set_color.cpp:147 +#, fuzzy, c-format +msgid "%ls: Expected an argument\n" +msgstr "%ls: Argument erwartet\n" + +#: src/builtin_set_color.cpp:164 +#, fuzzy, c-format +msgid "%ls: Could not set up terminal\n" +msgstr "%ls: Konnte Terminal nicht einrichten\n" + +#: src/fish_indent.cpp:392 +#, c-format +msgid "%ls, version %s\n" +msgstr "%ls, Version %s\n" + +#: src/fish_indent.cpp:456 +#, c-format +msgid "" +"Expected file path to read/write for -w:\n" +"\n" +" $ %ls -w foo.fish\n" msgstr "" +"Erwartete Datepfad zum Lesen/Schreiben für -w:\n" +"\n" +" $ %ls -w foo.fish\n" -#: signal.cpp:348 +#: src/fish_indent.cpp:468 src/fish_indent.cpp:498 +#, c-format +msgid "Opening \"%s\" failed: %s\n" +msgstr "Öffnen von \"%s\" fehlgeschlagen: %s\n" + +#: src/fish_indent.cpp:472 #, fuzzy -msgid "Unused signal" -msgstr "Benutzerdefiniertes Signal 1" +msgid "Too many arguments\n" +msgstr "%ls: Zu viele Argumente\n" -#: signal.cpp:684 -msgid "Signal block mismatch" -msgstr "" - -#: tokenizer.cpp:32 -#, fuzzy -msgid "Unexpected end of string, quotes are not balanced" -msgstr "Unerwartetes Zeichenende" - -#: tokenizer.cpp:37 -msgid "Unexpected end of string, parenthesis do not match" -msgstr "" - -#: tokenizer.cpp:42 -msgid "Unexpected end of string, square brackets do not match" -msgstr "" - -#: tokenizer.cpp:48 -#, fuzzy -msgid "Invalid input/output redirection" -msgstr "Ungültige Umleitung" - -#: tokenizer.cpp:53 -#, fuzzy -msgid "Cannot use stdin (fd 0) as pipe output" -msgstr "Kann FD 0 nicht als Pipe-Ausgabe verwenden" - -#: tokenizer.cpp:65 -msgid "Tokenizer not yet initialized" -msgstr "Tokenizer noch nicht initialisiert" - -#: tokenizer.cpp:66 -msgid "Tokenizer error" -msgstr "Tokenizer-Fehler" - -#: tokenizer.cpp:67 -msgid "String" -msgstr "Zeichenkette" - -#: tokenizer.cpp:68 -msgid "Pipe" -msgstr "Pipe" - -#: tokenizer.cpp:69 -msgid "End of command" -msgstr "Ende des Befehls" - -#: tokenizer.cpp:70 -msgid "Redirect output to file" -msgstr "Ausgabe auf Datei umleiten" - -#: tokenizer.cpp:71 -msgid "Append output to file" -msgstr "Ausgabe an Datei anhängen" - -#: tokenizer.cpp:72 -msgid "Redirect input to file" -msgstr "Eingabe auf Datei umleiten" - -#: tokenizer.cpp:73 -msgid "Redirect to file descriptor" -msgstr "Auf Dateideskriptor umleiten" - -#: tokenizer.cpp:74 -#, fuzzy -msgid "Redirect output to file if file does not exist" -msgstr "Ausgabe auf Datei umleiten" - -#: tokenizer.cpp:75 -msgid "Run job in background" -msgstr "Job im Hintergrund ausführen" - -#: tokenizer.cpp:76 -msgid "Comment" -msgstr "Kommentar" - -#: tokenizer.cpp:561 -#, fuzzy -msgid "Invalid token type" -msgstr "Ungültiges Zeichen" - -#: wgetopt.cpp:536 -#, fuzzy, c-format -msgid "%ls: Option '%ls' is ambiguous\n" -msgstr "%ls: Funktion '%ls' existiert nicht\n" - -#: wgetopt.cpp:560 -#, fuzzy, c-format -msgid "%ls: Option '--%ls' doesn't allow an argument\n" -msgstr "%ls: Funktion '%ls' existiert nicht\n" - -#: wgetopt.cpp:565 -#, fuzzy, c-format -msgid "%ls: Option '%lc%ls' doesn't allow an argument\n" -msgstr "%ls: Funktion '%ls' existiert nicht\n" - -#: wgetopt.cpp:579 -#, fuzzy, c-format -msgid "%ls: Option '%ls' requires an argument\n" -msgstr "%ls: Funktion '%ls' existiert nicht\n" - -#: wgetopt.cpp:607 -#, fuzzy, c-format -msgid "%ls: Unrecognized option '--%ls'\n" -msgstr "%ls: Unbekannte Option '%ls'\n" - -#: wgetopt.cpp:611 -#, fuzzy, c-format -msgid "%ls: Unrecognized option '%lc%ls'\n" -msgstr "%ls: Unbekannte Option '%ls'\n" - -#: wgetopt.cpp:636 -#, fuzzy, c-format -msgid "%ls: Illegal option -- %lc\n" -msgstr "%ls: Ungültiger Funktionsname '%ls'\n" - -#: wgetopt.cpp:638 -#, fuzzy, c-format -msgid "%ls: Invalid option -- %lc\n" -msgstr "%ls: Ungültige Prozesskennung %ls\n" - -#: wgetopt.cpp:676 -#, fuzzy, c-format -msgid "%ls: Option requires an argument -- %lc\n" -msgstr "%ls: Erwartete ein Argument, erhielt %d\n" - -#: wildcard.cpp:58 -msgid "Executable" -msgstr "Programm" - -#: wildcard.cpp:62 -msgid "Executable link" -msgstr "Programmlink" - -#: wildcard.cpp:67 share/completions/git.fish:178 -msgid "File" -msgstr "Datei" - -#: wildcard.cpp:71 -msgid "Character device" -msgstr "zeichenorientiertes Gerät" - -#: wildcard.cpp:75 -msgid "Block device" -msgstr "blockorientiertes Gerät" - -#: wildcard.cpp:79 -msgid "Fifo" -msgstr "Fifo" - -#: wildcard.cpp:83 -msgid "Symbolic link" -msgstr "Symbolischer Link" - -#: wildcard.cpp:87 -#, fuzzy -msgid "Symbolic link to directory" -msgstr "Schleife bei symbolischem Link" - -#: wildcard.cpp:91 -msgid "Rotten symbolic link" -msgstr "zerstörter symbolischer Link" - -#: wildcard.cpp:95 -msgid "Symbolic link loop" -msgstr "Schleife bei symbolischem Link" - -#: wildcard.cpp:99 -msgid "Socket" -msgstr "Socket" - -#: wildcard.cpp:103 share/completions/ruby.fish:23 -#: share/functions/__fish_complete_directories.fish:8 -msgid "Directory" -msgstr "Verzeichnis" - -#: builtin.h:27 +#: src/builtin_string.cpp:33 #, c-format msgid "%ls: Expected argument\n" msgstr "%ls: Argument erwartet\n" -#: builtin.h:37 +#: src/builtin_string.cpp:362 +#, c-format +msgid "%ls: Regular expression compile error: %ls\n" +msgstr "%ls: Fehler beim Kompilieren von Regulärem Ausdruck: %ls\n" + +#: src/builtin_string.cpp:403 +#, c-format +msgid "%ls: Regular expression match error: %ls\n" +msgstr "%ls: Fehler beim Zuordnen von Regulärem Ausdruck: %ls\n" + +#: src/builtin_string.cpp:408 +#, c-format +msgid "%ls: Regular expression internal error\n" +msgstr "%ls: Interner Fehler\n" + +#: src/builtin_string.cpp:730 +#, c-format +msgid "%ls: Regular expression substitute error: %ls\n" +msgstr "%ls: Fehler beim Ersetzen von Regulärem Ausdruck: %ls\n" + +#: src/builtin_string.cpp:984 +#, fuzzy, c-format +msgid "%ls: Invalid length value '%ls'\n" +msgstr "%ls: Ungültiger Längenwert '%ls'\n" + +#: src/builtin_string.cpp:1000 +#, fuzzy, c-format +msgid "%ls: Invalid start value '%ls'\n" +msgstr "%ls: Ungültiger Anfangswert '%ls'\n" + +#: src/builtin_string.cpp:1173 +#, fuzzy +msgid "string: Expected subcommand\n" +msgstr "string: Erwartete Unterbefehl\n" + +#: src/builtin_string.cpp:1188 +#, fuzzy, c-format +msgid "string: Unknown subcommand '%ls'\n" +msgstr "Unbekannter Befehl '%ls'" + +#: src/sanity.cpp:18 +#, fuzzy +msgid "Errors detected, shutting down. Break on sanity_lose() to debug." +msgstr "Fehler gefunden, Programmabbruch" + +#: src/sanity.cpp:34 +#, c-format +msgid "The pointer '%ls' is invalid" +msgstr "Der Zeiger '%ls' ist ungültig" + +#: src/sanity.cpp:39 +#, c-format +msgid "The pointer '%ls' is null" +msgstr "Der Zeiger '%ls' ist null" + +#: src/io.cpp:57 +#, c-format +msgid "" +"An error occured while reading output from code block on file descriptor %d" +msgstr "Fehler beim Lesen der Ausgabe des Codeblocks auf Dateideskriptor %d" + +#: src/builtin_commandline.cpp:366 +#, fuzzy, c-format +msgid "%ls: Unknown input function '%ls'\n" +msgstr "%ls: Unbekannte Eingabefunktion '%ls'\n" + +#: src/builtin_ulimit.cpp:285 +#, fuzzy, c-format +msgid "%ls: New limit cannot be an empty string\n" +msgstr "%ls: Neues Limit kann nicht leer sein\n" + +#: src/builtin_ulimit.cpp:297 +#, fuzzy, c-format +msgid "%ls: Invalid limit '%ls'\n" +msgstr "%ls: Ungültiges Limit '%ls'\n" + +#: src/parser.cpp:30 +#, c-format +msgid "Tried to evaluate commands using invalid block type '%ls'" +msgstr "Versuchte, Befehle mittels des ungültigen Blocktyps '%ls' auszuwerten" + +#: src/parser.cpp:33 +msgid "'while' block" +msgstr "'while'-Block" + +#: src/parser.cpp:36 +msgid "'for' block" +msgstr "'for'-Block" + +#: src/parser.cpp:39 +msgid "block created by breakpoint" +msgstr "Von 'breakpoint' erstellter Block" + +#: src/parser.cpp:42 +msgid "'if' conditional block" +msgstr "'if'-Bedingungsblock" + +#: src/parser.cpp:45 +msgid "function definition block" +msgstr "Funktionsdefinitonsblock" + +#: src/parser.cpp:48 +msgid "function invocation block" +msgstr "Funktionsausführungsblock" + +#: src/parser.cpp:51 +#, fuzzy +msgid "function invocation block with no variable shadowing" +msgstr "Funktionsausführungsblock ohne Variablenverdeckung" + +#: src/parser.cpp:54 +msgid "'switch' block" +msgstr "'switch'-Block" + +#: src/parser.cpp:57 +msgid "unexecutable block" +msgstr "nicht ausführbarer Block" + +#: src/parser.cpp:60 +msgid "global root block" +msgstr "globaler Root-Block" + +#: src/parser.cpp:63 +msgid "command substitution block" +msgstr "Befehlsersetzungsblock" + +#: src/parser.cpp:66 +msgid "'begin' unconditional block" +msgstr "'begin' unbedingter Block" + +#: src/parser.cpp:69 +msgid "block created by the . builtin" +msgstr "Vom '.' builtin erstellter Block" + +#: src/parser.cpp:72 +#, fuzzy +msgid "event handler block" +msgstr "Ereignisbehandler-Block" + +#: src/parser.cpp:75 +msgid "unknown/invalid block" +msgstr "unbekannter/ungültiger Block" + +#: src/parser.cpp:320 +#, c-format +msgid "Could not write profiling information to file '%s'" +msgstr "Konnte Profilinformationen nicht in Datei '%s' schreiben" + +#: src/parser.cpp:322 +msgid "Time\tSum\tCommand\n" +msgstr "Zeit\tSum\tBefehl\n" + +#: src/parser.cpp:380 +#, c-format +msgid "in event handler: %ls\n" +msgstr "" + +#: src/parser.cpp:399 +#, c-format +msgid "from sourcing file %ls\n" +msgstr "" + +#: src/parser.cpp:406 +#, fuzzy, c-format +msgid "in function '%ls'\n" +msgstr "Unbekannte Funktion '%ls'" + +#: src/parser.cpp:410 +#, fuzzy +msgid "in command substitution\n" +msgstr "Befehlsersetzungsblock" + +#: src/parser.cpp:421 +#, c-format +msgid "\tcalled on line %d of file %ls\n" +msgstr "" + +#: src/parser.cpp:424 +msgid "\tcalled during startup\n" +msgstr "" + +#: src/parser.cpp:426 +msgid "\tcalled on standard input\n" +msgstr "" + +#: src/parser.cpp:439 +#, c-format +msgid "\twith parameter list '%ls'\n" +msgstr "" + +#: src/parser.cpp:528 +#, c-format +msgid "%ls (line %d): " +msgstr "%ls (Zeile %d): " + +#: src/parser.cpp:531 +msgid "Startup" +msgstr "" + +#: src/parser.cpp:568 +msgid "Job inconsistency" +msgstr "Jobinkonsistenz" + +#: src/parser.cpp:696 +msgid "End of block mismatch. Program terminating." +msgstr "Unpassendes Blockende. Programm wird beendet." + +#: src/parser.cpp:777 +#, fuzzy, c-format +msgid "%ls (line %lu): " +msgstr "%ls (Zeile %d): " + +#: src/parser.cpp:780 +#, c-format +msgid "%ls: " +msgstr "" + +#: src/env.cpp:322 +msgid "" +"Could not determine current working directory. Is your locale set correctly?" +msgstr "" + +#: src/env.cpp:938 +msgid "Tried to pop empty environment stack." +msgstr "Versuchte, einen leeren Umgebungsstack zu poppen." + +#: src/pager.cpp:39 +#, fuzzy +msgid "search: " +msgstr "Suche: " + +#: src/pager.cpp:476 +#, c-format +msgid "%lsand %lu more rows" +msgstr "%lsund %lu mehr Zeilen" + +#: src/pager.cpp:483 +#, c-format +msgid "rows %lu to %lu of %lu" +msgstr "Zeilen %lu bis %lu von %lu" + +#: src/pager.cpp:486 +#, fuzzy +msgid "(no matches)" +msgstr "(Keine Treffer)" + +#: src/builtin_complete.cpp:180 +#, fuzzy, c-format +msgid "%ls: Invalid token '%ls'\n" +msgstr "%ls: Ungültiges Token '%ls'\n" + +#: src/builtin_complete.cpp:192 src/builtin_complete.cpp:202 +#, c-format +msgid "" +"%ls: Please update your completion scripts by removing -u / --" +"unauthoritative / -A / --authoritative flags." +msgstr "" + +#: src/builtin_complete.cpp:212 +#, fuzzy, c-format +msgid "%ls: -s requires a non-empty string\n" +msgstr "%ls: -s benötigt einen nicht-leeren String\n" + +#: src/builtin_complete.cpp:220 +#, fuzzy, c-format +msgid "%ls: -l requires a non-empty string\n" +msgstr "%ls: -l benötigt einen nicht-leeren String\n" + +#: src/builtin_complete.cpp:228 +#, fuzzy, c-format +msgid "%ls: -o requires a non-empty string\n" +msgstr "%ls: -o benötigt einen nicht-leeren String\n" + +#: src/event.cpp:118 +#, c-format +msgid "signal handler for %ls (%ls)" +msgstr "Signalbehandler für %ls (%ls)" + +#: src/event.cpp:123 +#, fuzzy, c-format +msgid "handler for variable '%ls'" +msgstr "Behandler für Variable '%ls'" + +#: src/event.cpp:128 +#, c-format +msgid "exit handler for process %d" +msgstr "" + +#: src/event.cpp:132 src/event.cpp:143 +#, c-format +msgid "exit handler for job %d, '%ls'" +msgstr "" + +#: src/event.cpp:135 +#, c-format +msgid "exit handler for job with process group %d" +msgstr "" + +#: src/event.cpp:146 +#, c-format +msgid "exit handler for job with job id %d" +msgstr "" + +#: src/event.cpp:151 +#, c-format +msgid "handler for generic event '%ls'" +msgstr "" + +#: src/event.cpp:155 +#, fuzzy, c-format +msgid "Unknown event type '0x%x'" +msgstr "Unbekannter Ereignistyp '0x%x'" + +#: src/event.cpp:447 +msgid "Signal list overflow. Signals have been ignored." +msgstr "Signallistenüberlauf. Signale wurden ignoriert." + +#: src/autoload.cpp:104 +#, c-format +msgid "" +"Could not autoload item '%ls', it is already being autoloaded. This is a " +"circular dependency in the autoloading scripts, please remove it." +msgstr "" +"Konnte '%ls' nicht automatisch laden, weil es schon automatisch geladen wird" +"Dies ist eine Abhängigkeitsschleife in den Skripten. Bitte entfernen sie es." + +#: src/signal.cpp:36 +msgid "Terminal hung up" +msgstr "Terminal getrennt" + +#: src/signal.cpp:39 +msgid "Quit request from job control (^C)" +msgstr "Quit-Anforderung über Jobsteuerung (^C)" + +#: src/signal.cpp:42 +msgid "Quit request from job control with core dump (^\\)" +msgstr "Quit-Anforderung über Jobsteuerung mit Speicherauszug (^\\)" + +#: src/signal.cpp:45 +msgid "Illegal instruction" +msgstr "Illegale Instruktion" + +#: src/signal.cpp:48 +msgid "Trace or breakpoint trap" +msgstr "Verfolgungs- oder Haltepunkt erreicht" + +#: src/signal.cpp:51 +msgid "Abort" +msgstr "Abbruch" + +#: src/signal.cpp:54 +msgid "Misaligned address error" +msgstr "Fehler: nicht ausgerichtete Adresse" + +#: src/signal.cpp:57 +msgid "Floating point exception" +msgstr "Fließkomma-Ausnahmefehler" + +#: src/signal.cpp:60 +msgid "Forced quit" +msgstr "Erzwungene Beendigung" + +#: src/signal.cpp:63 +msgid "User defined signal 1" +msgstr "Benutzerdefiniertes Signal 1" + +#: src/signal.cpp:66 +msgid "User defined signal 2" +msgstr "Benutzerdefiniertes Signal 2" + +#: src/signal.cpp:69 +msgid "Address boundary error" +msgstr "Adressbereichsfehler" + +#: src/signal.cpp:72 +msgid "Broken pipe" +msgstr "zerstörte Pipe" + +#: src/signal.cpp:75 +msgid "Timer expired" +msgstr "Zeitgeber abgelaufen" + +#: src/signal.cpp:78 +msgid "Polite quit request" +msgstr "Höfliche Beendigungsanforderung" + +#: src/signal.cpp:81 +msgid "Child process status changed" +msgstr "Kindprozessstatus geändert" + +#: src/signal.cpp:84 +msgid "Continue previously stopped process" +msgstr "Vorher gestoppten Prozess fortsetzen" + +#: src/signal.cpp:87 +msgid "Forced stop" +msgstr "Erzwungener Stopp" + +#: src/signal.cpp:90 +msgid "Stop request from job control (^Z)" +msgstr "Stoppanforderung über Jobsteuerung (^Z)" + +#: src/signal.cpp:93 +msgid "Stop from terminal input" +msgstr "Stopp durch Terminaleingabe" + +#: src/signal.cpp:96 +msgid "Stop from terminal output" +msgstr "Stopp durch Terminalausgabe" + +#: src/signal.cpp:99 +msgid "Urgent socket condition" +msgstr "Vorrangige Socket-Bedingung" + +#: src/signal.cpp:102 +msgid "CPU time limit exceeded" +msgstr "CPU-Zeitbegrenzung überschritten" + +#: src/signal.cpp:105 +msgid "File size limit exceeded" +msgstr "Dateigrößenbegrenzung überschritten" + +#: src/signal.cpp:108 +msgid "Virtual timer expired" +msgstr "Virtueller Zeitgeber abgelaufen" + +#: src/signal.cpp:111 +msgid "Profiling timer expired" +msgstr "Profilierungszeitgeber abgelaufen" + +#: src/signal.cpp:114 src/signal.cpp:117 +msgid "Window size change" +msgstr "Änderung der Fenstergröße" + +#: src/signal.cpp:120 +msgid "I/O on asynchronous file descriptor is possible" +msgstr "E/A auf asynchronem Dateideskriptor ist möglich" + +#: src/signal.cpp:123 +msgid "Power failure" +msgstr "Stromausfall" + +#: src/signal.cpp:126 +msgid "Bad system call" +msgstr "Fehlerhafter Systemaufruf" + +#: src/signal.cpp:129 +msgid "Information request" +msgstr "" + +#: src/signal.cpp:132 +msgid "Stack fault" +msgstr "" + +#: src/signal.cpp:135 +msgid "Emulator trap" +msgstr "" + +#: src/signal.cpp:138 +msgid "Abort (Alias for SIGABRT)" +msgstr "" + +#: src/signal.cpp:141 +#, fuzzy +msgid "Unused signal" +msgstr "Benutzerdefiniertes Signal 1" + +#: src/signal.cpp:173 src/signal.cpp:185 +#, fuzzy +msgid "Unknown" +msgstr "Unbekannt" + +#: src/signal.cpp:389 +msgid "Signal block mismatch" +msgstr "" + +#: src/builtin_jobs.cpp:56 +msgid "Job\tGroup\t" +msgstr "Job\tGruppe\t" + +#: src/builtin_jobs.cpp:58 +msgid "CPU\t" +msgstr "CPU\t" + +#: src/builtin_jobs.cpp:60 +msgid "State\tCommand\n" +msgstr "Status\tBefehl\n" + +#: src/builtin_jobs.cpp:68 +msgid "running" +msgstr "aktiv" + +#: src/builtin_jobs.cpp:77 +msgid "Group\n" +msgstr "Gruppe\n" + +#: src/builtin_jobs.cpp:85 +#, fuzzy +msgid "Process\n" +msgstr "Prozess\n" + +#: src/builtin_jobs.cpp:96 +msgid "Command\n" +msgstr "Befehl\n" + +#: src/builtin_jobs.cpp:191 src/builtin.cpp:2781 src/builtin.cpp:2878 +#, c-format +msgid "%ls: '%ls' is not a job\n" +msgstr "%ls: '%ls' ist kein Job\n" + +#: src/builtin_jobs.cpp:201 src/builtin.cpp:2796 +#, c-format +msgid "%ls: No suitable job: %d\n" +msgstr "%ls: Kein passender Job: %d\n" + +#: src/builtin_jobs.cpp:221 +#, c-format +msgid "%ls: There are no jobs\n" +msgstr "%ls: Es gibt keine Jobs\n" + +#: src/builtin.cpp:246 +#, c-format +msgid "" +"%ls: Type 'help %ls' for related documentation\n" +"\n" +msgstr "" +"%ls: Benutzen sie 'help %ls' für mehr Information\n" +"\n" + +#: src/builtin.cpp:374 +#, c-format +msgid "%ls: No key with name '%ls' found\n" +msgstr "%ls: Kein Schlüssel mit Name '%ls' gefunden\n" + +#: src/builtin.cpp:376 +#, fuzzy, c-format +msgid "%ls: Key with name '%ls' does not have any mapping\n" +msgstr "%ls: Schlüssel '%ls' hat keine Zuordnung\n" + +#: src/builtin.cpp:379 +#, fuzzy, c-format +msgid "%ls: Unknown error trying to bind to key named '%ls'\n" +msgstr "%ls: Unbekannte Fehler beim Zuordnen von Schlüssel '%ls'\n" + +#: src/builtin.cpp:565 +#, fuzzy, c-format +msgid "%ls: No binding found for key '%ls'\n" +msgstr "%ls: Keine Zuordnung für Taste '%ls'\n" + +#: src/builtin.cpp:568 +#, c-format +msgid "%ls: No binding found for sequence '%ls'\n" +msgstr "%ls: Keine Zuordnung für Sequenz '%ls'\n" + +#: src/builtin.cpp:592 +#, fuzzy, c-format +msgid "%ls: Invalid state\n" +msgstr "%ls: Ungültiger Zustand\n" + +#: src/builtin.cpp:663 +#, c-format +msgid "%ls: Can not specify scope when removing block\n" +msgstr "%ls: Bei Blocklöschung kann keine Gültigkeit angegeben werden\n" + +#: src/builtin.cpp:669 +#, c-format +msgid "%ls: No blocks defined\n" +msgstr "%ls: Keine Blöcke definiert\n" + +#: src/builtin.cpp:1124 src/builtin.h:40 +#, c-format +msgid "%ls: Invalid combination of options\n" +msgstr "%ls: Ungültige Kombination der Optionen\n" + +#: src/builtin.cpp:1139 +#, c-format +msgid "%ls: Expected exactly one function name\n" +msgstr "%ls: Erwartete genau einen Funktionsnamen\n" + +#: src/builtin.cpp:1146 src/builtin.cpp:1193 +#, c-format +msgid "%ls: Function '%ls' does not exist\n" +msgstr "%ls: Funktion '%ls' existiert nicht\n" + +#: src/builtin.cpp:1182 +#, fuzzy, c-format +msgid "" +"%ls: Expected exactly two names (current function name, and new function " +"name)\n" +msgstr "%ls: Erwartete genau zwei Funktionsnamen (den aktuellen und den neuen)\n" + +#: src/builtin.cpp:1201 +#, c-format +msgid "%ls: Illegal function name '%ls'\n" +msgstr "%ls: Ungültiger Funktionsname '%ls'\n" + +#: src/builtin.cpp:1210 +#, fuzzy, c-format +msgid "%ls: Function '%ls' already exists. Cannot create copy '%ls'\n" +msgstr "%ls: Funktion '%ls' existiert schon. Kann keine Kopie '%ls' anlegen\n" + +#: src/builtin.cpp:1521 +#, fuzzy, c-format +msgid "%ls: Expected function name" +msgstr "%ls: Erwartete einen Funktionsnamen\n" + +#: src/builtin.cpp:1527 +#, fuzzy, c-format +msgid "%ls: Illegal function name '%ls'" +msgstr "%ls: Ungültiger Funktionsname '%ls'\n" + +#: src/builtin.cpp:1534 +#, fuzzy, c-format +msgid "" +"%ls: The name '%ls' is reserved,\n" +"and can not be used as a function name" +msgstr "" +"%ls: Der Name '%ls' ist reserviert,\n" +"und kann nicht als Funktionsname benutzt werden\n" + +#: src/builtin.cpp:1603 +#, fuzzy, c-format +msgid "%ls: Unknown signal '%ls'" +msgstr "%ls: Unbekanntes Signal '%ls'\n" + +#: src/builtin.cpp:1611 src/builtin.cpp:1681 +#, fuzzy, c-format +msgid "%ls: Invalid variable name '%ls'" +msgstr "%ls: Ungültiger Variablenname '%ls'\n" + +#: src/builtin.cpp:1648 +#, fuzzy, c-format +msgid "%ls: Cannot find calling job for event handler" +msgstr "%ls: Kann aufrufenden Job zur Ereignisbehandlung nicht finden\n" + +#: src/builtin.cpp:1656 +#, fuzzy, c-format +msgid "%ls: Invalid process id '%ls'" +msgstr "%ls: Ungültige Prozesskennung %ls\n" + +#: src/builtin.cpp:1713 +#, fuzzy, c-format +msgid "%ls: Unexpected positional argument '%ls'" +msgstr "%ls: Unerwartetes Argument '%ls'" + +#: src/builtin.cpp:1989 +#, fuzzy, c-format +msgid "%ls: Argument '%ls' is out of range\n" +msgstr "%ls: Argument '%ls' ist ausserhalb des Gültigkeitsbereichs\n" + +#: src/builtin.cpp:1995 src/builtin.cpp:2525 src/builtin.cpp:2958 +#, c-format +msgid "%ls: Argument '%ls' must be an integer\n" +msgstr "%ls: Argument '%ls' muss eine Ganzzahl sein\n" + +#: src/builtin.cpp:2046 +#, fuzzy, c-format +msgid "%ls: --array option requires a single variable name.\n" +msgstr "%ls: --array option benötigt einen Variablennamen.\n" + +#: src/builtin.cpp:2248 src/builtin.cpp:3004 +#, c-format +msgid "you cannot do both '%ls' and '%ls' in the same invocation" +msgstr "'%ls' und '%ls' im selben Aufruf ungültig" + +#: src/builtin.cpp:2418 +#, fuzzy +msgid "This is a login shell\n" +msgstr "Dies ist eine Login-Shell\n" + +#: src/builtin.cpp:2420 +#, fuzzy +msgid "This is not a login shell\n" +msgstr "Dies ist keine Login-Shell\n" + +#: src/builtin.cpp:2424 +#, c-format +msgid "Job control: %ls\n" +msgstr "Jobsteuerung: %ls\n" + +#: src/builtin.cpp:2426 +#, fuzzy +msgid "Only on interactive jobs" +msgstr "Nur bei interaktiven Jobs" + +#: src/builtin.cpp:2427 +msgid "Never" +msgstr "Nie" + +#: src/builtin.cpp:2427 +msgid "Always" +msgstr "Immer" + +#: src/builtin.cpp:2514 src/builtin.h:68 +#, c-format +msgid "%ls: Too many arguments\n" +msgstr "%ls: Zu viele Argumente\n" + +#: src/builtin.cpp:2546 +#, c-format +msgid "%ls: Could not find home directory\n" +msgstr "%ls: Konnte Heimordner nicht finden\n" + +#: src/builtin.cpp:2560 src/builtin.cpp:2587 +#, c-format +msgid "%ls: '%ls' is not a directory\n" +msgstr "%ls: '%ls' ist kein Verzeichnis\n" + +#: src/builtin.cpp:2563 +#, fuzzy, c-format +msgid "%ls: The directory '%ls' does not exist\n" +msgstr "%ls: Verzeichnis '%ls' existiert nicht\n" + +#: src/builtin.cpp:2566 +#, fuzzy, c-format +msgid "%ls: '%ls' is a rotten symlink\n" +msgstr "%ls: '%ls' ist defekter symbolischer Link\n" + +#: src/builtin.cpp:2569 +#, fuzzy, c-format +msgid "%ls: Unknown error trying to locate directory '%ls'\n" +msgstr "%ls: Unbekannter Fehler beim Suchen von Verzeichnis '%ls'\n" + +#: src/builtin.cpp:2584 +#, fuzzy, c-format +msgid "%ls: Permission denied: '%ls'\n" +msgstr "%ls: Keine Erlaubnis: '%ls'\n" + +#: src/builtin.cpp:2598 +#, c-format +msgid "%ls: Could not set PWD variable\n" +msgstr "%ls: Konnte PWD-Variable nicht setzen\n" + +#: src/builtin.cpp:2667 +#, fuzzy, c-format +msgid "%ls: Key not specified\n" +msgstr "%s: Schlüssel nicht angegeben\\n" + +#: src/builtin.cpp:2697 src/builtin.cpp:2705 +#, fuzzy, c-format +msgid "%ls: Error encountered while sourcing file '%ls':\n" +msgstr "%ls: Fehler beim Lesen der Datei '%ls'\n" + +#: src/builtin.cpp:2713 +#, c-format +msgid "%ls: '%ls' is not a file\n" +msgstr "%ls: '%ls' ist keine Datei\n" + +#: src/builtin.cpp:2730 +#, c-format +msgid "%ls: Error while reading file '%ls'\n" +msgstr "%ls: Fehler beim Lesen der Datei '%ls'\n" + +#: src/builtin.cpp:2763 src/builtin.cpp:2866 +#, fuzzy, c-format +msgid "%ls: There are no suitable jobs\n" +msgstr "%ls: Es gibt keine passenden Jobs\n" + +#: src/builtin.cpp:2779 +#, c-format +msgid "%ls: Ambiguous job\n" +msgstr "%ls: Mehrdeutiger Job\n" + +#: src/builtin.cpp:2799 +#, c-format +msgid "" +"%ls: Can't put job %d, '%ls' to foreground because it is not under job " +"control\n" +msgstr "" +"%ls: Kann job %d, '%ls' nicht in den Vordergrund schicken weil er nicht " +"der Jobsteuerung unterliegt\n" + +#: src/builtin.cpp:2833 +#, c-format +msgid "%ls: Unknown job '%ls'\n" +msgstr "%ls: Unbekannter Job '%ls'\n" + +#: src/builtin.cpp:2838 +#, c-format +msgid "" +"%ls: Can't put job %d, '%ls' to background because it is not under job " +"control\n" +msgstr "" +"%ls: Kann job %d, '%ls' nicht in den Hintergrund schicken weil er nicht " +"der Jobsteuerung unterliegt\n" + +#: src/builtin.cpp:2844 +#, c-format +msgid "Send job %d '%ls' to background\n" +msgstr "Sende Job %d '%ls' in den Hintergrund\n" + +#: src/builtin.cpp:2869 +msgid "(default)" +msgstr "(Standard)" + +#: src/builtin.cpp:2910 +#, c-format +msgid "%ls: Not inside of loop\n" +msgstr "%ls: Nicht innerhalb einer Schleife\n" + +#: src/builtin.cpp:2975 +#, c-format +msgid "%ls: Not inside of function\n" +msgstr "%ls: Nicht innerhalb einer Funktion\n" + +#: src/builtin.cpp:3017 +#, c-format +msgid "%ls: you cannot use any options with the %ls command\n" +msgstr "%ls: Sie können keine Option mit dem %ls Befehl verwenden\n" + +#: src/builtin.cpp:3127 src/builtin.cpp:3163 +#, fuzzy, c-format +msgid "%ls: max value '%ls' is not a valid number\n" +msgstr "%ls: Maximalwert '%ls' ist keine gültige Zahl\n" + +#: src/builtin.cpp:3206 +msgid "builtin history delete only supports --exact\n" +msgstr "'builtin history delete' unterstützt nur --exact\n" + +#: src/builtin.cpp:3212 +msgid "builtin history delete only supports --case-sensitive\n" +msgstr "'builtin history delete' unterstützt nur --case-sensitive\n" + +#: src/builtin.cpp:3336 +#, fuzzy, c-format +msgid "%ls: Invalid path: %ls\n" +msgstr "%ls: Ungültiger Indexstart bei '%ls'\n" + +#: src/builtin.cpp:3351 src/builtin.cpp:3402 +#, fuzzy +msgid "Test a condition" +msgstr "Eine Bedingung testen" + +#: src/builtin.cpp:3354 +msgid "Try out the new parser" +msgstr "Zum Testen des neuen Parsers" + +#: src/builtin.cpp:3356 +msgid "Execute command if previous command suceeded" +msgstr "Befehl ausführen, wenn vorheriger Befehl erfolgreich war" + +#: src/builtin.cpp:3357 +msgid "Create a block of code" +msgstr "Codeblock erstellen" + +#: src/builtin.cpp:3358 +msgid "Send job to background" +msgstr "Job in Hintergrund schicken" + +#: src/builtin.cpp:3359 +msgid "Handle fish key bindings" +msgstr "Fish-Tastenbelegungen bearbeiten" + +#: src/builtin.cpp:3360 +msgid "Temporarily block delivery of events" +msgstr "Ereignisweitergabe vorübergehend blockieren" + +#: src/builtin.cpp:3361 +msgid "Stop the innermost loop" +msgstr "Innerste Schleife beenden" + +#: src/builtin.cpp:3363 +msgid "" +"Temporarily halt execution of a script and launch an interactive debug prompt" +msgstr "" +"Temporär Ausführung eines Skripts anhalten und einen interaktiven Debugprompt starten" + +#: src/builtin.cpp:3364 +msgid "Run a builtin command instead of a function" +msgstr "Internen Befehl anstatt einer Funktion ausführen" + +#: src/builtin.cpp:3365 src/builtin.cpp:3401 +msgid "Conditionally execute a block of commands" +msgstr "Befehlsblock bedingt ausführen" + +#: src/builtin.cpp:3366 +msgid "Change working directory" +msgstr "Arbeitsverzeichnis wechseln" + +#: src/builtin.cpp:3367 +msgid "Run a program instead of a function or builtin" +msgstr "Programm statt Funktion oder internem Befehl ausführen" + +#: src/builtin.cpp:3368 +msgid "Set or get the commandline" +msgstr "Festlegen oder Abrufen der Befehlszeile" + +#: src/builtin.cpp:3369 +msgid "Edit command specific completions" +msgstr "Befehlsspezifische Erweiterungen bearbeiten" + +#: src/builtin.cpp:3370 +msgid "Search for a specified string in a list" +msgstr "Nach einem String in einer Liste suchen" + +#: src/builtin.cpp:3372 +msgid "Skip the rest of the current lap of the innermost loop" +msgstr "Rest des aktuellen Durchlaufs der innersten Schleife überspringen" + +#: src/builtin.cpp:3373 +#, fuzzy +msgid "Count the number of arguments" +msgstr "Anzahl der Argumente zählen" + +#: src/builtin.cpp:3374 +#, fuzzy +msgid "Print arguments" +msgstr "Argumente ausgeben" + +#: src/builtin.cpp:3375 +msgid "Evaluate block if condition is false" +msgstr "Werte Block aus, wenn die Bedingung falsch ist" + +#: src/builtin.cpp:3376 +#, fuzzy +msgid "Emit an event" +msgstr "Ein Ereignis auslösen" + +#: src/builtin.cpp:3377 +msgid "End a block of commands" +msgstr "Befehlsblock beenden" + +#: src/builtin.cpp:3378 +msgid "Run command in current process" +msgstr "Befehl im aktuellen Prozess ausführen" + +#: src/builtin.cpp:3379 +msgid "Exit the shell" +msgstr "Shell verlassen" + +#: src/builtin.cpp:3380 +msgid "Return an unsuccessful result" +msgstr "Ein erfolgloses Resultat zurückgeben" + +#: src/builtin.cpp:3381 +msgid "Send job to foreground" +msgstr "Job in Vordergrund schicken" + +#: src/builtin.cpp:3382 +msgid "Perform a set of commands multiple times" +msgstr "Eine Befehlsfolge mehrmals ausführen" + +#: src/builtin.cpp:3383 +msgid "Define a new function" +msgstr "Neue Funktion definieren" + +#: src/builtin.cpp:3384 +msgid "List or remove functions" +msgstr "Funktionen auflisten oder entfernen" + +#: src/builtin.cpp:3385 +msgid "History of commands executed by user" +msgstr "Befehlsgeschichte" + +#: src/builtin.cpp:3386 +msgid "Evaluate block if condition is true" +msgstr "Block auswerten, wenn Bedingung wahr ist" + +#: src/builtin.cpp:3387 +msgid "Print currently running jobs" +msgstr "Derzeit laufende Jobs ausgeben" + +#: src/builtin.cpp:3388 +msgid "Negate exit status of job" +msgstr "Exit-Status des Jobs verneinen" + +#: src/builtin.cpp:3389 +msgid "Execute command if previous command failed" +msgstr "Befehl ausführen, wenn vorheriger Befehl fehlerhaft war" + +#: src/builtin.cpp:3390 +#, fuzzy +msgid "Prints formatted text" +msgstr "Befehlstyp ausgeben" + +#: src/builtin.cpp:3391 +#, fuzzy +msgid "Print the working directory" +msgstr "Arbeitsverzeichnis ausgeben" + +#: src/builtin.cpp:3392 +msgid "Generate random number" +msgstr "Zufallszahl generieren" + +#: src/builtin.cpp:3393 +msgid "Read a line of input into variables" +msgstr "Eine Eingabezeile in Variablen einlesen" + +#: src/builtin.cpp:3394 +msgid "Convert path to absolute path without symlinks" +msgstr "Pfad zu absolutem Pfad ohne Symlinks konvertieren" + +#: src/builtin.cpp:3395 +msgid "Stop the currently evaluated function" +msgstr "Derzeit ausgewertete Funktion stoppen" + +#: src/builtin.cpp:3396 +msgid "Handle environment variables" +msgstr "Behandlung von Umgebungsvariablen" + +#: src/builtin.cpp:3397 +msgid "Set the terminal color" +msgstr "Setzen der Terminalfarbe" + +#: src/builtin.cpp:3398 +msgid "Evaluate contents of file" +msgstr "Inhalt einer Datei auswerten" + +#: src/builtin.cpp:3399 +msgid "Return status information about fish" +msgstr "Statusinformation über Fish zurückgeben" + +#: src/builtin.cpp:3400 +msgid "Manipulate strings" +msgstr "Strings manipulieren" + +#: src/builtin.cpp:3403 +msgid "Return a successful result" +msgstr "Ein erfolgreiches Resultat zurückgeben" + +#: src/builtin.cpp:3404 +msgid "Set or get the shells resource usage limits" +msgstr "Die Ressourcengrenzen der Shell festlegen/abrufen" + +#: src/builtin.cpp:3405 +msgid "Perform a command multiple times" +msgstr "Einen Befehl mehrmals ausführen" + +#: src/tokenizer.cpp:25 +#, fuzzy +msgid "Unexpected end of string, quotes are not balanced" +msgstr "Unerwartetes Zeichenende" + +#: src/tokenizer.cpp:28 +msgid "Unexpected end of string, parenthesis do not match" +msgstr "Unerwartetes Stringende, Klammern passen nicht" + +#: src/tokenizer.cpp:31 +msgid "Unexpected end of string, square brackets do not match" +msgstr "Unerwartetes Stringende, eckige Klammern passen nicht" + +#: src/tokenizer.cpp:34 +#, fuzzy +msgid "Unexpected end of string, incomplete escape sequence" +msgstr "Unerwartetes Zeichenende, unvollständige Escapesequenz" + +#: src/tokenizer.cpp:37 +#, fuzzy +msgid "Invalid input/output redirection" +msgstr "Ungültige Umleitung" + +#: src/tokenizer.cpp:40 +#, fuzzy +msgid "Cannot use stdin (fd 0) as pipe output" +msgstr "Kann FD 0 nicht als Pipe-Ausgabe verwenden" + +#: src/fish_key_reader.cpp:249 +#, c-format +msgid "signal #%d (%ls) received\n" +msgstr "Signal #%d (%ls) erhalten\n" + +#: src/builtin_printf.cpp:244 +#, fuzzy, c-format +msgid "%ls: expected a numeric value" +msgstr "%ls: erwartete Zahl\n" + +#: src/builtin_printf.cpp:246 +#, c-format +msgid "%ls: value not completely converted" +msgstr "%ls: Wert nicht vollständig konvertiert" + +#: src/builtin_printf.cpp:358 +msgid "missing hexadecimal number in escape" +msgstr "fehlende Hexzahl in Escapesequenz" + +#: src/builtin_printf.cpp:378 +msgid "Missing hexadecimal number in Unicode escape" +msgstr "fehlende Hexzahl in Unicode-Escapesequenz" + +#: src/builtin_printf.cpp:395 +#, c-format +msgid "Unicode character out of range: \\%c%0*x" +msgstr "Unicodezeichen ausserhalb der Gültigkeit: \\%c%0*x" + +#: src/builtin_printf.cpp:639 +#, c-format +msgid "invalid field width: %ls" +msgstr "Ungültige Feldlänge: %ls" + +#: src/builtin_printf.cpp:666 +#, fuzzy, c-format +msgid "invalid precision: %ls" +msgstr "Ungültige Genauigkeit: %ls\n" + +#: src/builtin_printf.cpp:691 +#, fuzzy, c-format +msgid "%.*ls: invalid conversion specification" +msgstr "%.*ls: Ungültige Umwandlungsspezifikation" + +#: src/builtin_printf.cpp:723 +#, fuzzy +msgid "printf: not enough arguments" +msgstr "printf: Nicht genug Argumente" + +#: src/expand.h:100 +msgid "Array index out of bounds" +msgstr "Arrayindex ausserhalb der Grenzen" + +#: src/exec.h:11 +msgid "An error occurred while setting up pipe" +msgstr "Fehler beim Einrichten der Pipe aufgetreten" + +#: src/parse_constants.h:225 +#, c-format +msgid "" +"The function '%ls' calls itself immediately, which would result in an " +"infinite loop." +msgstr "" +"Die Funktion '%ls' ruft sich sofort selbst auf. Dies wäre eine Endlosschleife." + +#: src/parse_constants.h:229 +msgid "" +"The function call stack limit has been exceeded. Do you have an accidental " +"infinite loop?" +msgstr "" +"Zu viele verschachtelte Funktionsaufrufe. Gibt es eine Endlosschleife?" + +#: src/parse_constants.h:233 +#, c-format +msgid "Illegal command name '%ls'" +msgstr "Ungültiger Befehlsname '%ls'" + +#: src/parse_constants.h:236 +#, c-format +msgid "Unknown builtin '%ls'" +msgstr "unbekannter interner Befehl '%ls'" + +#: src/parse_constants.h:239 +#, fuzzy, c-format +msgid "Unable to expand variable name '%ls'" +msgstr "%ls: Ungültiger Variablenname '%ls'\n" + +#: src/parse_constants.h:242 +#, fuzzy, c-format +msgid "Unable to find a process '%ls'" +msgstr "Konnte Prozess '%ls' nicht ausführen" + +#: src/parse_constants.h:245 +#, c-format +msgid "Illegal file descriptor in redirection '%ls'" +msgstr "" + +#: src/parse_constants.h:249 +#, c-format +msgid "" +"No matches for wildcard '%ls'. (Tip: empty matches are allowed in 'set', " +"'count', 'for'.)" +msgstr "" + +#: src/parse_constants.h:253 +#, fuzzy +msgid "'break' while not inside of loop" +msgstr "Schleifensteuerungsbefehl 'while' nicht innerhalb einer Schleife" + +#: src/parse_constants.h:256 +#, fuzzy +msgid "'continue' while not inside of loop" +msgstr "Schleifensteuerungsbefehl 'while' nicht innerhalb einer Schleife" + +#: src/parse_constants.h:259 +#, fuzzy +msgid "'return' outside of function definition" +msgstr "Internen Befehl anstatt einer Funktion ausführen" + +#: src/parse_constants.h:264 +#, fuzzy, c-format +msgid "$%lc is not a valid variable in fish." +msgstr "%ls: '%ls' ist kein gültiger Variablenname\n" + +#: src/parse_constants.h:267 +#, c-format +msgid "Variables cannot be bracketed. In fish, please use {$%ls}." +msgstr "" + +#: src/parse_constants.h:271 +#, c-format +msgid "Variables cannot be bracketed. In fish, please use \"$%ls\"." +msgstr "" + +#: src/parse_constants.h:274 +msgid "$? is not the exit status. In fish, please use $status." +msgstr "" + +#: src/parse_constants.h:277 +#, c-format +msgid "$$ is not the pid. In fish, please use %%self." +msgstr "" + +#: src/parse_constants.h:280 +msgid "$# is not supported. In fish, please use 'count $argv'." +msgstr "" + +#: src/parse_constants.h:283 +msgid "$@ is not supported. In fish, please use $argv." +msgstr "" + +#: src/parse_constants.h:286 +#, c-format +msgid "$(...) is not supported. In fish, please use '(%ls)'." +msgstr "" + +#: src/parse_constants.h:289 +msgid "$* is not supported. In fish, please use $argv." +msgstr "" + +#: src/parse_constants.h:292 +msgid "Expected a variable name after this $." +msgstr "" + +#: src/parse_constants.h:295 +msgid "Unsupported use of '||'. In fish, please use 'COMMAND; or COMMAND'." +msgstr "" + +#: src/parse_constants.h:298 +msgid "Unsupported use of '&&'. In fish, please use 'COMMAND; and COMMAND'." +msgstr "" + +#: src/parse_constants.h:302 +#, c-format +msgid "" +"Unsupported use of '='. To run '%ls' with a modified environment, please use " +"'env %ls=%ls %ls%ls'" +msgstr "" + +#: src/parse_constants.h:307 +#, c-format +msgid "Unsupported use of '='. In fish, please use 'set %ls %ls'." +msgstr "" + +#: src/builtin.h:37 +#, fuzzy, c-format +msgid "%ls: Expected argument for option %ls\n" +msgstr "%ls: Erwartete ein Argument, erhielt %d\n" + +#: src/builtin.h:43 #, c-format msgid "" "%ls: Invalid combination of options,\n" @@ -1653,26 +1901,36 @@ msgstr "" "%ls: Ungültige Kombination von Optionen,\n" "%ls\n" -#: builtin.h:42 +#: src/builtin.h:47 #, fuzzy, c-format msgid "%ls: Variable scope can only be one of universal, global and local\n" msgstr "" "%ls: Variablenbereich kann nur universell, global oder lokal sein\n" "%ls\n" -#: builtin.h:47 +#: src/builtin.h:50 #, fuzzy, c-format msgid "%ls: Variable can't be both exported and unexported\n" msgstr "" "%ls: Variable kann nicht gleichzeitig exportiert und nicht exportiert sein\n" "%ls\n" -#: builtin.h:52 +#: src/builtin.h:53 #, c-format msgid "%ls: Unknown option '%ls'\n" msgstr "%ls: Unbekannte Option '%ls'\n" -#: builtin.h:57 +#: src/builtin.h:56 +#, fuzzy, c-format +msgid "%ls: expected %d args, got %d\n" +msgstr "%ls: Erwartete ein Argument, erhielt %d\n" + +#: src/builtin.h:57 +#, fuzzy, c-format +msgid "%ls: %ls expected %d args, got %d\n" +msgstr "%ls: Erwartete ein Argument, erhielt %d\n" + +#: src/builtin.h:61 #, c-format msgid "" "%ls: Invalid character '%lc' in variable name. Only alphanumerical " @@ -1681,7238 +1939,3974 @@ msgstr "" "%ls: Ungültiges Zeichen '%lc' im Variablenname. Nur alphanumerische Zeichen " "und Unterstriche sind in einem Variablennamen gültig.\n" -#: builtin.h:62 +#: src/builtin.h:65 #, c-format msgid "%ls: Variable name can not be the empty string\n" msgstr "%ls: Variablenname kann nicht leer sein\n" -#: builtin.h:67 -#, c-format -msgid "%ls: Second argument must be 'in'\n" -msgstr "%ls: Zweites Argument muss 'in' sein'\n" - -#: builtin.h:72 -#, fuzzy, c-format -msgid "%ls: Expected at least two arguments, got %d\n" -msgstr "%ls: Erwartete mindestens zwei Argumente\n" - -#: builtin.h:74 -#, c-format -msgid "%ls: '%ls' is not a valid variable name\n" -msgstr "%ls: '%ls' ist kein gültiger Variablenname\n" - -#: builtin.h:77 -#, c-format -msgid "%ls: can only take 'if' and then another command as an argument\n" -msgstr "" - -#: builtin.h:78 -#, fuzzy, c-format -msgid "%ls: any second argument must be 'if'\n" -msgstr "%ls: Zweites Argument muss 'in' sein'\n" - -#: builtin.h:88 -#, c-format -msgid "%ls: Block mismatch: '%ls' vs. '%ls'\n" -msgstr "" - -#: builtin.h:93 -#, fuzzy, c-format -msgid "%ls: Unknown block type '%ls'\n" -msgstr "%ls: Unbekannter Job '%ls'\n" - -#: builtin.h:95 +#: src/builtin.h:71 #, fuzzy, c-format msgid "%ls: Argument '%ls' is not a number\n" msgstr "%ls: Argument '%ls' muss eine Ganzzahl sein\n" -#: exec.h:21 -msgid "An error occurred while setting up pipe" -msgstr "Fehler beim Einrichten der Pipe aufgetreten" - -#: expand.h:135 -msgid "Array index out of bounds" -msgstr "" - -#: parse_constants.h:185 +#: src/builtin.h:74 #, c-format -msgid "" -"The function '%ls' calls itself immediately, which would result in an " -"infinite loop." -msgstr "" - -#: parse_constants.h:189 -msgid "" -"The function call stack limit has been exceeded. Do you have an accidental " -"infinite loop?" -msgstr "" - -#: parse_constants.h:192 -#, fuzzy -msgid "" -"Expected a command, but instead found a pipe. Did you mean 'COMMAND; or " -"COMMAND'? See the help section for the 'or' builtin command by typing 'help " -"or'." -msgstr "" -"Erwartete einen Befehlsnamen, bekam Zeichen des Typs '%ls'. Meinten Sie " -"'Befehl; or Befehl'? Zu weiteren Informationen über den eingebauten Befehl " -"'or' schauen Sie in der Hilfe zu 'or' nach oder geben Sie 'help or' ein." - -#: parse_constants.h:195 -#, fuzzy -msgid "" -"Expected a command, but instead found an '&'. Did you mean 'COMMAND; and " -"COMMAND'? See the help section for the 'and' builtin command by typing 'help " -"and'." -msgstr "" -"Erwartete einen Befehlsnamen, bekam Zeichen des Typs '%ls'. Meinten Sie " -"'Befehl; and Befehl'? Zu weiteren Informationen über den eingebauten Befehl " -"'and' schauen Sie in der Hilfe zu 'and' nach oder geben Sie 'help and' ein." - -#: parse_constants.h:198 -#, c-format -msgid "Illegal command name '%ls'" -msgstr "Ungültiger Befehlsname '%ls'" - -#: parse_constants.h:201 -#, c-format -msgid "Unknown builtin '%ls'" -msgstr "unbekannter interner Befehl '%ls'" - -#: parse_constants.h:204 -#, fuzzy, c-format -msgid "Unable to expand variable name '%ls'" -msgstr "%ls: Ungültiger Variablenname '%ls'\n" - -#: parse_constants.h:207 -#, fuzzy, c-format -msgid "Unable to find a process '%ls'" -msgstr "Konnte Prozess '%ls' nicht ausführen" - -#: parse_constants.h:210 -#, c-format -msgid "Illegal file descriptor in redirection '%ls'" -msgstr "" - -#: parse_constants.h:213 -#, c-format -msgid "No matches for wildcard '%ls'." -msgstr "" - -#: parse_constants.h:216 -#, fuzzy -msgid "break command while not inside of loop" -msgstr "Schleifensteuerungsbefehl 'while' nicht innerhalb einer Schleife" - -#: parse_constants.h:219 -#, fuzzy -msgid "continue command while not inside of loop" -msgstr "Schleifensteuerungsbefehl 'while' nicht innerhalb einer Schleife" - -#: parse_constants.h:222 -#, fuzzy -msgid "'return' builtin command outside of function definition" -msgstr "Internen Befehl anstatt einer Funktion ausführen" - -#: parse_constants.h:225 -#, fuzzy, c-format -msgid "" -"Unknown command '%ls'. Did you mean 'set %ls %ls'? See the help section on " -"the set command by typing 'help set'." -msgstr "" -"Unbekannter Befehl '%ls'. Meinten Sie 'set VARIABLE WERT'? Zu Informationen " -"zum Festlegen von Variablenwerten schauen Sie in der Hilfe zum set-Befehl " -"nach oder geben Sie 'help set' ein." - -#: parse_constants.h:230 -#, c-format -msgid "" -"The '$' character begins a variable name. The character '%lc', which " -"directly followed a '$', is not allowed as a part of a variable name, and " -"variable names may not be zero characters long. To learn more about variable " -"expansion in fish, type 'help expand-variable'." -msgstr "" - -#: parse_constants.h:235 -msgid "" -"$? is not a valid variable in fish. If you want the exit status of the last " -"command, try $status." -msgstr "" - -#: parse_constants.h:240 -msgid "" -"The '$' begins a variable name. It was given at the end of an argument. " -"Variable names may not be zero characters long. To learn more about variable " -"expansion in fish, type 'help expand-variable'." -msgstr "" - -#: parse_constants.h:245 -#, c-format -msgid "" -"Did you mean %ls{$%ls}%ls? The '$' character begins a variable name. A " -"bracket, which directly followed a '$', is not allowed as a part of a " -"variable name, and variable names may not be zero characters long. To learn " -"more about variable expansion in fish, type 'help expand-variable'." -msgstr "" - -#: parse_constants.h:250 -msgid "" -"Did you mean (COMMAND)? In fish, the '$' character is only used for " -"accessing variables. To learn more about command substitution in fish, type " -"'help expand-command-substitution'." -msgstr "" - -#: share/completions/adb.fish:3 -#, fuzzy -msgid "Test if adb has yet to be given the subcommand" -msgstr "Test, ob an apt noch ein Unterbefehl gegeben werden muss" - -#: share/completions/adb.fish:12 -msgid "Run adb devices and parse output" -msgstr "" - -#: share/completions/adb.fish:24 -msgid "Runs adb with any -s parameters already given on the command line" -msgstr "" - -#: share/completions/apm.fish:2 share/completions/apropos.fish:20 -#: share/completions/apt-build.fish:29 share/completions/apt-cache.fish:28 -#: share/completions/apt-cdrom.fish:11 share/completions/apt-config.fish:5 -#: share/completions/apt-file.fish:12 share/completions/apt-ftparchive.fish:15 -#: share/completions/apt-proxy-import.fish:3 -#: share/completions/apt-rdepends.fish:12 -#: share/completions/apt-show-source.fish:8 -#: share/completions/apt-sortpkgs.fish:4 share/completions/apt-zip-inst.fish:3 -#: share/completions/apt-zip-list.fish:3 share/completions/at.fish:2 -#: share/completions/atq.fish:2 share/completions/atrm.fish:2 -#: share/completions/perl.fish:41 share/functions/__fish_complete_diff.fish:26 -#: share/functions/__fish_complete_grep.fish:44 -#: share/functions/__fish_complete_ls.fish:96 -#: share/functions/__fish_complete_python.fish:15 -#: share/functions/__fish_complete_tex.fish:5 -msgid "Display version and exit" -msgstr "Version anzeigen und beenden" - -#: share/completions/apm.fish:3 -msgid "Print APM info" -msgstr "APM-Informationen ausgeben" - -#: share/completions/apm.fish:4 -msgid "Print time remaining" -msgstr "Verbleibende Zeit ausgeben" - -#: share/completions/apm.fish:5 -msgid "Monitor status info" -msgstr "Statusinformation beobachten" - -#: share/completions/apm.fish:6 -msgid "Request APM standby mode" -msgstr "APM-Standby-Modus anfordern" - -#: share/completions/apm.fish:7 -msgid "Request APM suspend mode" -msgstr "APM-Suspend-Modus anfordern" - -#: share/completions/apm.fish:8 -msgid "APM status debugging info" -msgstr "APM-Status Debug-Informationen" - -#: share/completions/apropos.fish:12 -msgid "Print debugging info" -msgstr "Debug-Informationen ausgeben" - -#: share/completions/apropos.fish:13 share/completions/apt-file.fish:8 -#: share/completions/apt-listchanges.fish:4 -#: share/completions/apt-proxy-import.fish:4 -#: share/completions/apt-show-source.fish:10 -#: share/functions/__fish_complete_python.fish:14 -#: share/functions/__fish_complete_ssh.fish:59 -#: share/functions/__fish_complete_vi.fish:98 -msgid "Verbose mode" -msgstr "Ausführlicher Modus" - -#: share/completions/apropos.fish:14 -msgid "Keyword as regex" -msgstr "Schlüsselwort als regulärer Ausdruck" - -#: share/completions/apropos.fish:15 -#, fuzzy -msgid "Keyword as wildcards" -msgstr "Schlüsselwort als Muster" - -#: share/completions/apropos.fish:16 -msgid "Keyword as exactly match" -msgstr "Schlüsselwort als genaue Übereinstimmung" - -#: share/completions/apropos.fish:17 -msgid "Search for other system" -msgstr "Nach anderem System suchen" - -#: share/completions/apropos.fish:18 -msgid "Specify man path" -msgstr "Man-Pfad angeben" - -#: share/completions/apropos.fish:19 -msgid "Specify a configuration file" -msgstr "Eine Konfigurationsdatei angeben" - -#: share/completions/apt-build.fish:4 -msgid "Update list of packages" -msgstr "Paketliste aktualisieren" - -#: share/completions/apt-build.fish:5 -msgid "Upgrade packages" -msgstr "Pakete aktualisieren" - -#: share/completions/apt-build.fish:6 -msgid "Rebuild your system" -msgstr "Ihr Sytem neu erstellen" - -#: share/completions/apt-build.fish:7 -msgid "Build and install a new package" -msgstr "Ein neues Paket erstellen und installieren" - -#: share/completions/apt-build.fish:8 -msgid "Download and extract a source" -msgstr "Eine Quelle herunterladen und extrahieren" - -#: share/completions/apt-build.fish:9 -msgid "Info on a package" -msgstr "Informationen über ein Paket" - -#: share/completions/apt-build.fish:10 share/completions/zypper.fish:45 -msgid "Remove packages" -msgstr "Pakete entfernen" - -#: share/completions/apt-build.fish:11 -msgid "Erase built packages" -msgstr "Erstellte Pakete löschen" - -#: share/completions/apt-build.fish:12 -msgid "Build source without install" -msgstr "Quelle ohne Installation erstellen" +msgid "Send job %d, '%ls' to foreground\n" +msgstr "Job %d, '%ls' in den Vordergrund schicken\n" -#: share/completions/apt-build.fish:13 -msgid "Clean source directories" -msgstr "Quellverzeichnisse bereinigen" - -#: share/completions/apt-build.fish:14 -msgid "Update source and rebuild" -msgstr "Quelle aktualisieren und erneut erstellen" - -#: share/completions/apt-build.fish:15 -msgid "Update the repository" -msgstr "Paketdepot aktualisieren" - -#: share/completions/apt-build.fish:16 -msgid "Do not use gcc wrapper" -msgstr "Nicht die gcc-Ummantelung benutzen" - -#: share/completions/apt-build.fish:17 -msgid "Remove build-dep" -msgstr "Erstellungsabhängigkeiten entfernen" - -#: share/completions/apt-build.fish:18 -msgid "Do not download source" -msgstr "Quelle nicht herunterladen" - -#: share/completions/apt-build.fish:19 -msgid "Specify build-dir" -msgstr "Erstellungsverzeichnis angeben" - -#: share/completions/apt-build.fish:20 -msgid "Rebuild a package" -msgstr "Ein Paket neu erstellen" - -#: share/completions/apt-build.fish:21 -msgid "Rebuild and install an installed package" -msgstr "Ein installiertes Paket neu erstellen und installieren" - -#: share/completions/apt-build.fish:23 -msgid "Apply patch" -msgstr "-Patch anwenden" - -#: share/completions/apt-build.fish:28 -msgid "Specify sources.list file" -msgstr "Sources.list-Datei angeben" +#, fuzzy +#~ msgid "%ls: No function name given\n" +#~ msgstr "%ls: Ungültiger Funktionsname '%ls'\n" -#: share/completions/apt-cache.fish:3 -msgid "Build apt cache" -msgstr "Apt-Zwischenspeicher erstellen" +#~ msgid "%ls: Expected zero or one argument, got %d\n" +#~ msgstr "%ls: Erwartete kein oder ein Argument, erhielt %d\n" -#: share/completions/apt-cache.fish:4 -msgid "Show package info" -msgstr "Paketinformation anzeigen" +#~ msgid "Unknown option: " +#~ msgstr "Unbekannte Option: " -#: share/completions/apt-cache.fish:5 -msgid "Show cache statistics" -msgstr "Zwischenspeicherstatistik anzeigen" - -#: share/completions/apt-cache.fish:6 -msgid "Show source package" -msgstr "Quellpaket anzeigen" - -#: share/completions/apt-cache.fish:7 -msgid "Show packages in cache" -msgstr "Pakete im Zwischenspeicher anzeigen" - -#: share/completions/apt-cache.fish:8 -msgid "Print available list" -msgstr "Verfügbare Liste ausgeben" - -#: share/completions/apt-cache.fish:9 -msgid "List unmet dependencies in cache" -msgstr "Nicht aufgelöste Abhängigkeiten im Zwischenspeicher auflisten" - -#: share/completions/apt-cache.fish:10 -msgid "Display package record" -msgstr "Paketsatz anzeigen" - -#: share/completions/apt-cache.fish:11 -msgid "Search packagename by REGEX" -msgstr "Paketname mittels regulärem Ausdruck suchen" - -#: share/completions/apt-cache.fish:13 -msgid "Search packagename only" -msgstr "Nur Paketname suchen" - -#: share/completions/apt-cache.fish:14 -msgid "List dependencies for the package" -msgstr "Abhängigkeiten für dieses Paket auflisten" - -#: share/completions/apt-cache.fish:15 -msgid "List reverse dependencies for the package" -msgstr "Umgekehrte Abhängigkeiten für das Paket auflisten" - -#: share/completions/apt-cache.fish:16 -msgid "Print package name by prefix" -msgstr "Paketname nach Präfix ausgeben" - -#: share/completions/apt-cache.fish:17 -msgid "Generate dotty output for packages" -msgstr "Punktierte Ausgabe für Pakete erzeugen" - -#: share/completions/apt-cache.fish:18 -msgid "Debug preferences file" -msgstr "Einstellungsdatei prüfen" - -#: share/completions/apt-cache.fish:19 -msgid "Select file to store package cache" -msgstr "Datei zum Speichern des Paketzwischenspeichers auswählen" - -#: share/completions/apt-cache.fish:20 -msgid "Select file to store source cache" -msgstr "Datei zum Speichern des Quellenzwischenspeichers auswählen" - -#: share/completions/apt-cache.fish:21 -#: share/completions/apt-ftparchive.fish:10 -msgid "Quiet mode" -msgstr "Stiller Modus" - -#: share/completions/apt-cache.fish:22 -msgid "Print important dependencies" -msgstr "Wichtige Abhängigkeiten ausgeben" - -#: share/completions/apt-cache.fish:23 -msgid "Print full records" -msgstr "Vollständige Datensätze ausgeben" - -#: share/completions/apt-cache.fish:24 -msgid "Auto-gen package cache" -msgstr "Paketcache automatisch generieren" - -#: share/completions/apt-cache.fish:25 -msgid "Print all names" -msgstr "Alle Namen ausgeben" - -#: share/completions/apt-cache.fish:26 -msgid "Dep and rdep recursive" -msgstr "Dep und rdep rekursiv" - -#: share/completions/apt-cache.fish:27 -msgid "Limit to installed" -msgstr "Auf Installierte begrenzen" - -#: share/completions/apt-cache.fish:29 share/completions/apt-cdrom.fish:12 -#: share/completions/apt-config.fish:6 -msgid "Specify config file" -msgstr "Konfigurationsdatei angeben" - -#: share/completions/apt-cache.fish:30 share/completions/apt-cdrom.fish:13 -#: share/completions/apt-config.fish:7 -#: share/completions/apt-extracttemplates.fish:6 -msgid "Specify options" -msgstr "Optionen angeben" - -#: share/completions/apt-cache.fish:32 share/completions/apt-get.fish:12 -#: share/completions/apt-mark.fish:12 -msgid "Test if apt command should have packages as potential completion" -msgstr "" -"Testen, ob der apt-Befehl Pakete zur möglichen Fertigstellung haben sollte" - -#: share/completions/apt-cdrom.fish:3 -msgid "Add new disc to source list" -msgstr "Neue Platte zur Quellenliste hinzufügen" - -#: share/completions/apt-cdrom.fish:4 -msgid "Report identity of disc" -msgstr "Kennung der Platte anzeigen" - -#: share/completions/apt-cdrom.fish:5 share/completions/mount.fish:7 -msgid "Mount point" -msgstr "Einhängepunkt" - -#: share/completions/apt-cdrom.fish:6 -msgid "Rename a disc" -msgstr "Eine Platte umbenennen" - -#: share/completions/apt-cdrom.fish:7 -msgid "No mounting" -msgstr "Nicht einhängen" - -#: share/completions/apt-cdrom.fish:8 -msgid "Fast copy" -msgstr "Schnelle Kopie" - -#: share/completions/apt-cdrom.fish:9 -msgid "Thorough package scan" -msgstr "Gründlicher Paketscan" - -#: share/completions/apt-cdrom.fish:10 -msgid "No changes" -msgstr "Keine Änderungen" - -#: share/completions/apt-config.fish:4 -msgid "Dump contents of config file" -msgstr "Inhalt der Konfigurationsdatei ausgeben" - -#: share/completions/apt-extracttemplates.fish:4 -msgid "Set temp dir" -msgstr "temp-Verzeichnis festlegen" - -#: share/completions/apt-extracttemplates.fish:5 -msgid "Specifiy config file" -msgstr "Konfigurationsdatei angeben" - -#: share/completions/apt-file.fish:3 -msgid "Resync package contents from source" -msgstr "Paketinhalte aus der Quelle neu synchronisieren" - -#: share/completions/apt-file.fish:4 -msgid "Search package containing pattern" -msgstr "Paket entsprechend Muster suchen" - -#: share/completions/apt-file.fish:5 -msgid "List contents of a package matching pattern" -msgstr "Inhalte eines Paketes auflisten, das dem Muster entspricht" - -#: share/completions/apt-file.fish:6 -msgid "Remove all gz files from cache" -msgstr "Alle gz-Dateien aus dem Zwischenspeicher entfernen" - -#: share/completions/apt-file.fish:7 -msgid "Set cache dir" -msgstr "Verzeichnis für Zwischenspeicher festlegen" - -#: share/completions/apt-file.fish:10 share/completions/apt-file.fish:16 -msgid "Do not expand pattern" -msgstr "Erweitern Sie das Muster nicht" - -#: share/completions/apt-file.fish:11 -msgid "Pattern is regexp" -msgstr "Muster ist ein regulärer Ausdruck" - -#: share/completions/apt-file.fish:13 -msgid "Set arch" -msgstr "Architektur festlegen" - -#: share/completions/apt-file.fish:14 -msgid "Set sources.list file" -msgstr "sources.list-Datei angeben" - -#: share/completions/apt-file.fish:15 -msgid "Only display package name" -msgstr "Nur Paketnamen anzeigen" - -#: share/completions/apt-file.fish:17 -msgid "Run in dummy mode" -msgstr "Im Dummy-Modus ausführen" +#~ msgid "Multiple matches for option: " +#~ msgstr "Mehrere Treffer für Option: " -#: share/completions/apt-ftparchive.fish:3 -msgid "Generate package from source" -msgstr "Paket aus Quelle generieren" +#~ msgid "Changing language to English" +#~ msgstr "Sprachwechsel zu Deutsch" -#: share/completions/apt-ftparchive.fish:4 -msgid "Generate source index file" -msgstr "Quellindexdatei erstellen" +#, fuzzy +#~ msgid "%s: Unknown error in munge()\n" +#~ msgstr "%ls: Unbekannte Option '%ls'\n" -#: share/completions/apt-ftparchive.fish:5 -msgid "Generate contents file" -msgstr "Inhaltsdatei erstellen" +#, fuzzy +#~ msgid "%s: Locale string too long\n" +#~ msgstr "%ls: Parameter '%ls' ist zu lang\n" -#: share/completions/apt-ftparchive.fish:6 -msgid "Generate release file" -msgstr "Veröffentlichungsdatei erstellen" +#, fuzzy +#~ msgid "%s: No description for type %s\n" +#~ msgstr "Beschreibung des mime-Typs ausgeben" -#: share/completions/apt-ftparchive.fish:7 -msgid "Remove records" -msgstr "Sätze entfernen" +#, fuzzy +#~ msgid "%s: Could not parse launcher string '%s'\n" +#~ msgstr "Konnte Zeichenkette '%ls' nicht erweitern" -#: share/completions/apt-ftparchive.fish:8 -msgid "Generate MD5 sums" -msgstr "MD5-Summen erstellen" +#, fuzzy +#~ msgid "%s: Could not parse mimetype from argument '%s'\n" +#~ msgstr "Konnte Sequenz '%ls' nicht auswerten" -#: share/completions/apt-ftparchive.fish:9 -msgid "Use a binary db" -msgstr "Eine Binärdatenbank benutzen" +#, fuzzy +#~ msgid "" +#~ "Unknown command '%ls'. Did you mean to run %ls with a modified " +#~ "environment? Try 'env %ls=%ls %ls%ls'. See the help section on the set " +#~ "command by typing 'help set'." +#~ msgstr "" +#~ "Unbekannter Befehl '%ls'. Meinten Sie 'set VARIABLE WERT'? Zu " +#~ "Informationen zum Festlegen von Variablenwerten schauen Sie in der Hilfe " +#~ "zum set-Befehl nach oder geben Sie 'help set' ein." -#: share/completions/apt-ftparchive.fish:11 -msgid "Perform delinking" -msgstr "Trennung ausführen" +#, fuzzy +#~ msgid "" +#~ "Commands may not contain variables. Use the eval builtin instead, like " +#~ "'eval %ls'. See the help section for the eval command by typing 'help " +#~ "eval'." +#~ msgstr "" +#~ "Unbekannter Befehl '%ls'. Meinten Sie 'set VARIABLE WERT'? Zu " +#~ "Informationen zum Festlegen von Variablenwerten schauen Sie in der Hilfe " +#~ "zum set-Befehl nach oder geben Sie 'help set' ein." -#: share/completions/apt-ftparchive.fish:12 -msgid "Perform contents generation" -msgstr "Inhaltsgenerierung durchführen" +#~ msgid "Unexpected token of type '%ls'" +#~ msgstr "Unerwartetes Zeichen des Typs '%ls'" -#: share/completions/apt-ftparchive.fish:14 -msgid "Make caching db readonly" -msgstr "Zwischenspeicherdatenbank schreibschützen" +#~ msgid "Tokenizer not yet initialized" +#~ msgstr "Tokenizer noch nicht initialisiert" -#: share/completions/apt-ftparchive.fish:16 -msgid "Use config file" -msgstr "Konfigurationsdatei benutzen" +#~ msgid "Tokenizer error" +#~ msgstr "Tokenizer-Fehler" -#: share/completions/apt-ftparchive.fish:17 -msgid "Set config options" -msgstr "Konfigurationsoptionen festlegen" +#~ msgid "String" +#~ msgstr "Zeichenkette" -#: share/completions/apt-get.fish:3 share/completions/apt-mark.fish:3 -msgid "Test if apt has yet to be given the subcommand" -msgstr "Test, ob an apt noch ein Unterbefehl gegeben werden muss" +#~ msgid "Pipe" +#~ msgstr "Pipe" -#: share/completions/apt-get.fish:24 -msgid "Update sources" -msgstr "Quellen aktualisieren" +#~ msgid "End of command" +#~ msgstr "Ende des Befehls" -#: share/completions/apt-get.fish:25 -msgid "Upgrade or install newest packages" -msgstr "Neueste Pakete aktualisieren oder installieren" +#~ msgid "Redirect output to file" +#~ msgstr "Ausgabe auf Datei umleiten" -#: share/completions/apt-get.fish:26 -msgid "Use with dselect front-end" -msgstr "Mit dselect-Oberfläche verwenden" +#~ msgid "Append output to file" +#~ msgstr "Ausgabe an Datei anhängen" -#: share/completions/apt-get.fish:27 -msgid "Distro upgrade" -msgstr "Aktualisierung der Distribution" +#~ msgid "Redirect input to file" +#~ msgstr "Eingabe auf Datei umleiten" -#: share/completions/apt-get.fish:28 -msgid "Install one or more packages" -msgstr "Ein oder mehrere Paket(e) installieren" +#~ msgid "Redirect to file descriptor" +#~ msgstr "Auf Dateideskriptor umleiten" -#: share/completions/apt-get.fish:29 #, fuzzy -msgid "Remove and purge one or more packages" -msgstr "Ein oder mehrere Paket(e) entfernen" - -#: share/completions/apt-get.fish:30 -msgid "Remove one or more packages" -msgstr "Ein oder mehrere Paket(e) entfernen" - -#: share/completions/apt-get.fish:31 -msgid "Fetch source packages" -msgstr "Quellpakete abrufen" +#~ msgid "Redirect output to file if file does not exist" +#~ msgstr "Ausgabe auf Datei umleiten" -#: share/completions/apt-get.fish:32 -msgid "Install/remove packages for dependencies" -msgstr "Pakete für Abhängigkeiten installieren/entfernen" +#~ msgid "Run job in background" +#~ msgstr "Job im Hintergrund ausführen" -#: share/completions/apt-get.fish:33 -msgid "Update cache and check dependencies" -msgstr "Zwischenspeicher aktualisieren und Abhängigkeiten prüfen" +#~ msgid "Comment" +#~ msgstr "Kommentar" -#: share/completions/apt-get.fish:34 -msgid "Clean local caches and packages" -msgstr "Lokalen Zwischenspeicher und Pakete bereinigen" - -#: share/completions/apt-get.fish:35 -msgid "Clean packages no longer be downloaded" -msgstr "Pakete, die nicht länger heruntergeladen werden, bereinigen" - -#: share/completions/apt-get.fish:36 #, fuzzy -msgid "Remove automatically installed packages" -msgstr "Alle installierten Pakete abfragen" +#~ msgid "Invalid token type" +#~ msgstr "Ungültiges Zeichen" -#: share/completions/apt-get.fish:65 share/completions/apt-mark.fish:32 -msgid "Specify a config file" -msgstr "Konfigurationsdatei angeben" - -#: share/completions/apt-get.fish:66 share/completions/apt-mark.fish:33 -msgid "Set a config option" -msgstr "Konfigurationsoption festlegen" +#, fuzzy +#~ msgid "%ls: Illegal option -- %lc\n" +#~ msgstr "%ls: Ungültiger Funktionsname '%ls'\n" -#: share/completions/apt-key.fish:2 -msgid "Add a new key" -msgstr "Neuen Schlüssel hinzufügen" +#~ msgid "%ls: Second argument must be 'in'\n" +#~ msgstr "%ls: Zweites Argument muss 'in' sein'\n" -#: share/completions/apt-key.fish:3 -msgid "Remove a key" -msgstr "Schlüssel entfernen" +#, fuzzy +#~ msgid "%ls: Expected at least two arguments, got %d\n" +#~ msgstr "%ls: Erwartete mindestens zwei Argumente\n" -#: share/completions/apt-key.fish:4 -msgid "List trusted keys" -msgstr "Vertraute Schlüssel auflisten" +#, fuzzy +#~ msgid "%ls: any second argument must be 'if'\n" +#~ msgstr "%ls: Zweites Argument muss 'in' sein'\n" -#: share/completions/apt-listbugs.fish:3 -msgid "Set severity" -msgstr "Schwere festlegen" +#, fuzzy +#~ msgid "%ls: Unknown block type '%ls'\n" +#~ msgstr "%ls: Unbekannter Job '%ls'\n" -#: share/completions/apt-listbugs.fish:4 -msgid "Tags you want to see" -msgstr "Markierungen, die Sie sehen möchten" +#, fuzzy +#~ msgid "" +#~ "Expected a command, but instead found a pipe. Did you mean 'COMMAND; or " +#~ "COMMAND'? See the help section for the 'or' builtin command by typing " +#~ "'help or'." +#~ msgstr "" +#~ "Erwartete einen Befehlsnamen, bekam Zeichen des Typs '%ls'. Meinten Sie " +#~ "'Befehl; or Befehl'? Zu weiteren Informationen über den eingebauten " +#~ "Befehl 'or' schauen Sie in der Hilfe zu 'or' nach oder geben Sie 'help " +#~ "or' ein." -#: share/completions/apt-listbugs.fish:5 -msgid "Bug-status you want to see" -msgstr "Fehlerstatus, den Sie sehen möchten" +#, fuzzy +#~ msgid "" +#~ "Expected a command, but instead found an '&'. Did you mean 'COMMAND; and " +#~ "COMMAND'? See the help section for the 'and' builtin command by typing " +#~ "'help and'." +#~ msgstr "" +#~ "Erwartete einen Befehlsnamen, bekam Zeichen des Typs '%ls'. Meinten Sie " +#~ "'Befehl; and Befehl'? Zu weiteren Informationen über den eingebauten " +#~ "Befehl 'and' schauen Sie in der Hilfe zu 'and' nach oder geben Sie 'help " +#~ "and' ein." -#: share/completions/apt-listbugs.fish:6 -msgid "Ignore bugs in your system" -msgstr "Fehler in Ihrem System ignorieren" +#, fuzzy +#~ msgid "" +#~ "Unknown command '%ls'. Did you mean 'set %ls %ls'? See the help section " +#~ "on the set command by typing 'help set'." +#~ msgstr "" +#~ "Unbekannter Befehl '%ls'. Meinten Sie 'set VARIABLE WERT'? Zu " +#~ "Informationen zum Festlegen von Variablenwerten schauen Sie in der Hilfe " +#~ "zum set-Befehl nach oder geben Sie 'help set' ein." -#: share/completions/apt-listbugs.fish:7 -msgid "Ignore newer bugs than upgrade packages" -msgstr "Fehler, die neuer sind als Aktualisierungspakete, ignorieren" +#, fuzzy +#~ msgid "Test if adb has yet to be given the subcommand" +#~ msgstr "Test, ob an apt noch ein Unterbefehl gegeben werden muss" -#: share/completions/apt-listbugs.fish:8 -msgid "Bugs for downgrade packages" -msgstr "Fehler bei Downgrade-Paketen" +#~ msgid "Display version and exit" +#~ msgstr "Version anzeigen und beenden" -#: share/completions/apt-listbugs.fish:9 -msgid "Bug Tracking system" -msgstr "Fehlerverfolgungssystem" +#~ msgid "Print APM info" +#~ msgstr "APM-Informationen ausgeben" -#: share/completions/apt-listbugs.fish:10 -msgid "Specify port for web interface" -msgstr "Port für Weboberfläche angeben" +#~ msgid "Print time remaining" +#~ msgstr "Verbleibende Zeit ausgeben" -#: share/completions/apt-listbugs.fish:11 -msgid "Use daily bug report" -msgstr "Täglichen Fehlerbericht verwenden" +#~ msgid "Monitor status info" +#~ msgstr "Statusinformation beobachten" -#: share/completions/apt-listbugs.fish:12 -msgid "Use the raw index.db" -msgstr "Die rohe index.db verwenden" +#~ msgid "Request APM standby mode" +#~ msgstr "APM-Standby-Modus anfordern" -#: share/completions/apt-listbugs.fish:13 -msgid "Specify index dir" -msgstr "Indexverzeichnis angeben" +#~ msgid "Request APM suspend mode" +#~ msgstr "APM-Suspend-Modus anfordern" -#: share/completions/apt-listbugs.fish:14 -msgid "Specify Pin-Priority value" -msgstr "Pin-Prioritätswert angeben" +#~ msgid "APM status debugging info" +#~ msgstr "APM-Status Debug-Informationen" -#: share/completions/apt-listbugs.fish:15 -msgid "Specify the title of rss" -msgstr "Geben Sie einen Titel für rss an" +#~ msgid "Print debugging info" +#~ msgstr "Debug-Informationen ausgeben" -#: share/completions/apt-listbugs.fish:16 -msgid "Retrieve fresh bugs" -msgstr "Neue Bugs abrufen" +#~ msgid "Verbose mode" +#~ msgstr "Ausführlicher Modus" -#: share/completions/apt-listbugs.fish:17 -msgid "Do not display progress bar" -msgstr "Keinen Fortschrittsbalken anzeigen" +#~ msgid "Keyword as regex" +#~ msgstr "Schlüsselwort als regulärer Ausdruck" -#: share/completions/apt-listbugs.fish:18 -msgid "Specify local cache dir" -msgstr "Verzeichnis für lokalen Zwischenspeicher angeben" +#, fuzzy +#~ msgid "Keyword as wildcards" +#~ msgstr "Schlüsselwort als Muster" -#: share/completions/apt-listbugs.fish:19 -msgid "Specify the expire cache timer" -msgstr "Zeitablauf für Zwischenspeicher angeben" +#~ msgid "Keyword as exactly match" +#~ msgstr "Schlüsselwort als genaue Übereinstimmung" -#: share/completions/apt-listbugs.fish:21 -msgid "Assume yes to all questions" -msgstr "Bei allen Fragen ja annehmen" +#~ msgid "Search for other system" +#~ msgstr "Nach anderem System suchen" -#: share/completions/apt-listbugs.fish:22 -msgid "Assume no to all questions" -msgstr "Für alle Fragen nein annehmen" +#~ msgid "Specify man path" +#~ msgstr "Man-Pfad angeben" -#: share/completions/apt-listchanges.fish:5 -#, fuzzy -msgid "Select frontend interface" -msgstr "Benutzerschnittstelle auswählen" +#~ msgid "Specify a configuration file" +#~ msgstr "Eine Konfigurationsdatei angeben" -#: share/completions/apt-listchanges.fish:7 -msgid "Ask confirmation" -msgstr "Bestätigung erfragen" +#~ msgid "Update list of packages" +#~ msgstr "Paketliste aktualisieren" -#: share/completions/apt-listchanges.fish:8 -msgid "Display all changelogs" -msgstr "Alle Änderungsprotokolle anzeigen" +#~ msgid "Upgrade packages" +#~ msgstr "Pakete aktualisieren" -#: share/completions/apt-listchanges.fish:9 -msgid "Avoid changelogs from db in named file" -msgstr "Änderungsprotokolle aus der Datenbank der benannten Datei vermeiden" +#~ msgid "Rebuild your system" +#~ msgstr "Ihr Sytem neu erstellen" -#: share/completions/apt-listchanges.fish:11 -msgid "Insert header" -msgstr "Kopfzeile einfügen" +#~ msgid "Build and install a new package" +#~ msgstr "Ein neues Paket erstellen und installieren" -#: share/completions/apt-listchanges.fish:12 -msgid "Display debug info" -msgstr "Debug-Informationen anzeigen" +#~ msgid "Download and extract a source" +#~ msgstr "Eine Quelle herunterladen und extrahieren" -#: share/completions/apt-listchanges.fish:13 -msgid "Select an option profile" -msgstr "Optionsprofil auswählen" +#~ msgid "Info on a package" +#~ msgstr "Informationen über ein Paket" -#: share/completions/apt-mark.fish:24 -#, fuzzy -msgid "Mark a package as automatically installed" -msgstr "Paket aktualisieren, wenn es bereits installiert ist" +#~ msgid "Remove packages" +#~ msgstr "Pakete entfernen" -#: share/completions/apt-mark.fish:25 -#, fuzzy -msgid "Mark a package as manually installed" -msgstr "Paket aktualisieren, wenn es bereits installiert ist" +#~ msgid "Erase built packages" +#~ msgstr "Erstellte Pakete löschen" -#: share/completions/apt-mark.fish:26 -msgid "Hold a package, prevent automatic installation or removal" -msgstr "" +#~ msgid "Build source without install" +#~ msgstr "Quelle ohne Installation erstellen" -#: share/completions/apt-mark.fish:27 -#, fuzzy -msgid "Cancel a hold on a package" -msgstr "Informationen über ein Paket" +#~ msgid "Clean source directories" +#~ msgstr "Quellverzeichnisse bereinigen" -#: share/completions/apt-mark.fish:28 -#, fuzzy -msgid "Show automatically installed packages" -msgstr "Alle installierten Pakete abfragen" +#~ msgid "Update source and rebuild" +#~ msgstr "Quelle aktualisieren und erneut erstellen" -#: share/completions/apt-mark.fish:29 -#, fuzzy -msgid "Show manually installed packages" -msgstr "Alle installierten Pakete abfragen" +#~ msgid "Update the repository" +#~ msgstr "Paketdepot aktualisieren" -#: share/completions/apt-mark.fish:30 -#, fuzzy -msgid "Show held packages" -msgstr "Aktualisierte Pakete anzeigen" +#~ msgid "Do not use gcc wrapper" +#~ msgstr "Nicht die gcc-Ummantelung benutzen" -#: share/completions/apt-mark.fish:34 -#, fuzzy -msgid "Write package statistics to a file" -msgstr "Prototypen in Datei schreiben" +#~ msgid "Remove build-dep" +#~ msgstr "Erstellungsabhängigkeiten entfernen" -#: share/completions/apt-move.fish:4 -msgid "Move packages to local tree" -msgstr "Pakete in lokalen Verzeichnisbaum verschieben" +#~ msgid "Do not download source" +#~ msgstr "Quelle nicht herunterladen" -#: share/completions/apt-move.fish:5 -msgid "Delete obsolete package files" -msgstr "Veraltete Paketdateien löschen" +#~ msgid "Specify build-dir" +#~ msgstr "Erstellungsverzeichnis angeben" -#: share/completions/apt-move.fish:6 -msgid "Build new local files" -msgstr "Neue lokale Dateien erstellen" +#~ msgid "Rebuild a package" +#~ msgstr "Ein Paket neu erstellen" -#: share/completions/apt-move.fish:7 -msgid "Rebuild index files" -msgstr "Indexdateien neu erstellen" +#~ msgid "Rebuild and install an installed package" +#~ msgstr "Ein installiertes Paket neu erstellen und installieren" -#: share/completions/apt-move.fish:8 -msgid "Move packages from cache to local mirror" -msgstr "Pakete aus Zwischenspeicher auf lokalen Spiegelserver verschieben" +#~ msgid "Apply patch" +#~ msgstr "-Patch anwenden" -#: share/completions/apt-move.fish:9 -msgid "Alias for 'move delete packages'" -msgstr "Alias für 'move delete packages' '" +#~ msgid "Specify sources.list file" +#~ msgstr "Sources.list-Datei angeben" -#: share/completions/apt-move.fish:10 -msgid "Alias for 'update'" -msgstr "Alias für 'update'" +#~ msgid "Build apt cache" +#~ msgstr "Apt-Zwischenspeicher erstellen" -#: share/completions/apt-move.fish:11 -msgid "Download package missing from mirror" -msgstr "Fehlende Pakete vom Spiegelserver herunterladen" +#~ msgid "Show package info" +#~ msgstr "Paketinformation anzeigen" -#: share/completions/apt-move.fish:12 -msgid "Sync packages installed" -msgstr "Installierte Pakete synchronisieren" +#~ msgid "Show cache statistics" +#~ msgstr "Zwischenspeicherstatistik anzeigen" -#: share/completions/apt-move.fish:15 -#, fuzzy -msgid "List packages that may serve as input to mirrorbin or mirrorsource" -msgstr "" -"Pakete auflisten, die als Quelle für mirrorbin oder mirrorsource dienen " -"können" +#~ msgid "Show source package" +#~ msgstr "Quellpaket anzeigen" -#: share/completions/apt-move.fish:16 -msgid "Fetch package from STDIN" -msgstr "Paket über Standardeingabe lesen" +#~ msgid "Show packages in cache" +#~ msgstr "Pakete im Zwischenspeicher anzeigen" -#: share/completions/apt-move.fish:17 -msgid "Fetch source package from STDIN" -msgstr "Quellpaket über Standardeingabe lesen" +#~ msgid "Print available list" +#~ msgstr "Verfügbare Liste ausgeben" -#: share/completions/apt-move.fish:18 -msgid "Process all packages" -msgstr "Alle Pakete verarbeiten" +#~ msgid "List unmet dependencies in cache" +#~ msgstr "Nicht aufgelöste Abhängigkeiten im Zwischenspeicher auflisten" -#: share/completions/apt-move.fish:20 -msgid "Force deletion" -msgstr "Löschung erzwingen" +#~ msgid "Display package record" +#~ msgstr "Paketsatz anzeigen" -#: share/completions/apt-move.fish:21 -msgid "Suppresses normal output" -msgstr "Normale Ausgabe unterdrücken" +#~ msgid "Search packagename by REGEX" +#~ msgstr "Paketname mittels regulärem Ausdruck suchen" -#: share/completions/apt-move.fish:22 -msgid "Test run" -msgstr "Testdurchlauf" +#~ msgid "Search packagename only" +#~ msgstr "Nur Paketname suchen" -#: share/completions/apt-proxy-import.fish:5 -msgid "No message to STDOUT" -msgstr "Keine Meldungen auf Standardausgabe" +#~ msgid "List dependencies for the package" +#~ msgstr "Abhängigkeiten für dieses Paket auflisten" -#: share/completions/apt-proxy-import.fish:6 -msgid "Recurse into subdir" -msgstr "in Unterverzeichnis verzweigen" +#~ msgid "List reverse dependencies for the package" +#~ msgstr "Umgekehrte Abhängigkeiten für das Paket auflisten" -#: share/completions/apt-proxy-import.fish:7 -msgid "Dir to import" -msgstr "Zu importierendes Verzeichnis" +#~ msgid "Print package name by prefix" +#~ msgstr "Paketname nach Präfix ausgeben" -#: share/completions/apt-proxy-import.fish:8 -msgid "Change to user" -msgstr "Wechsel zu Benutzer" +#~ msgid "Generate dotty output for packages" +#~ msgstr "Punktierte Ausgabe für Pakete erzeugen" -#: share/completions/apt-proxy-import.fish:9 -msgid "Debug level[default 0]" -msgstr "Debug-Grad [Standard 0]" +#~ msgid "Debug preferences file" +#~ msgstr "Einstellungsdatei prüfen" -#: share/completions/apt-rdepends.fish:3 -#, fuzzy -msgid "Show build dependencies" -msgstr "Erstellungsabhängigkeiten anzeigen" +#~ msgid "Select file to store package cache" +#~ msgstr "Datei zum Speichern des Paketzwischenspeichers auswählen" -#: share/completions/apt-rdepends.fish:4 -msgid "Generate a dotty graph" -msgstr "Gepunkteten Graph generieren" +#~ msgid "Select file to store source cache" +#~ msgstr "Datei zum Speichern des Quellenzwischenspeichers auswählen" -#: share/completions/apt-rdepends.fish:5 -msgid "Show state of dependencies" -msgstr "Status der Abhängigkeiten anzeigen" +#~ msgid "Quiet mode" +#~ msgstr "Stiller Modus" -#: share/completions/apt-rdepends.fish:6 -msgid "List packages depending on" -msgstr "Pakete auflisten, die abhängen von " +#~ msgid "Print important dependencies" +#~ msgstr "Wichtige Abhängigkeiten ausgeben" -#: share/completions/apt-rdepends.fish:11 -msgid "Display man page" -msgstr "Handbuchseite anzeigen" +#~ msgid "Print full records" +#~ msgstr "Vollständige Datensätze ausgeben" -#: share/completions/apt-show-source.fish:3 -#: share/completions/apt-show-source.fish:4 -#: share/completions/apt-show-versions.fish:10 -#: share/completions/apt-show-versions.fish:11 -msgid "Read package from file" -msgstr "Paket aus Datei lesen" +#~ msgid "Auto-gen package cache" +#~ msgstr "Paketcache automatisch generieren" -#: share/completions/apt-show-source.fish:5 -#: share/completions/apt-show-source.fish:6 -#: share/completions/apt-show-versions.fish:12 -#: share/completions/apt-show-versions.fish:13 -msgid "Specify APT list dir" -msgstr "APT-Listenverzeichnis angeben" +#~ msgid "Print all names" +#~ msgstr "Alle Namen ausgeben" -#: share/completions/apt-show-source.fish:7 -msgid "List PKG info" -msgstr "PKG-Information auflisten" +#~ msgid "Dep and rdep recursive" +#~ msgstr "Dep und rdep rekursiv" -#: share/completions/apt-show-source.fish:9 -msgid "Print all source packages with version" -msgstr "Alle Quellpakete mit Version ausgeben" +#~ msgid "Limit to installed" +#~ msgstr "Auf Installierte begrenzen" -#: share/completions/apt-show-versions.fish:3 -msgid "Print PKG versions" -msgstr "PKG-Versionen ausgeben" +#~ msgid "Specify config file" +#~ msgstr "Konfigurationsdatei angeben" -#: share/completions/apt-show-versions.fish:4 -msgid "Using regex" -msgstr "Regulären Ausdruck benutzen" +#~ msgid "Specify options" +#~ msgstr "Optionen angeben" -#: share/completions/apt-show-versions.fish:5 -msgid "Print only upgradeable packages" -msgstr "Nur aktualisierbare Pakete ausgeben" +#~ msgid "Test if apt command should have packages as potential completion" +#~ msgstr "" +#~ "Testen, ob der apt-Befehl Pakete zur möglichen Fertigstellung haben sollte" -#: share/completions/apt-show-versions.fish:6 -msgid "Print all versions" -msgstr "Alle Versionen ausgeben" +#~ msgid "Add new disc to source list" +#~ msgstr "Neue Platte zur Quellenliste hinzufügen" -#: share/completions/apt-show-versions.fish:7 -msgid "Print package name/distro" -msgstr "Paketname/Distribution ausgeben" +#~ msgid "Report identity of disc" +#~ msgstr "Kennung der Platte anzeigen" -#: share/completions/apt-show-versions.fish:8 -msgid "Print verbose info" -msgstr "Ausführliche Informationen ausgeben" +#~ msgid "Mount point" +#~ msgstr "Einhängepunkt" -#: share/completions/apt-show-versions.fish:9 -msgid "Init or update cache only" -msgstr "Nur Zwischenspeicher initialisieren oder aktualisieren" +#~ msgid "Rename a disc" +#~ msgstr "Eine Platte umbenennen" -#: share/completions/apt-sortpkgs.fish:3 -msgid "Use source index field" -msgstr "Indexfeld der Quelle verwenden" +#~ msgid "No mounting" +#~ msgstr "Nicht einhängen" -#: share/completions/apt-sortpkgs.fish:5 -msgid "Specify conffile" -msgstr "Konfigurationsdatei angeben" +#~ msgid "Fast copy" +#~ msgstr "Schnelle Kopie" -#: share/completions/apt-spy.fish:3 -#, fuzzy -msgid "Debian distribution" -msgstr "Debian-Distribution" +#~ msgid "Thorough package scan" +#~ msgstr "Gründlicher Paketscan" -#: share/completions/apt-spy.fish:4 -msgid "Servers in the areas" -msgstr "Server in diesem Bereich" +#~ msgid "No changes" +#~ msgstr "Keine Änderungen" -#: share/completions/apt-spy.fish:6 -msgid "Finish after number of servers" -msgstr "Nach Anzahl der Server beenden" +#~ msgid "Dump contents of config file" +#~ msgstr "Inhalt der Konfigurationsdatei ausgeben" -#: share/completions/apt-spy.fish:11 -msgid "Use proxy server" -msgstr "Proxy-Server verwenden" +#~ msgid "Set temp dir" +#~ msgstr "temp-Verzeichnis festlegen" -#: share/completions/apt-spy.fish:12 -msgid "Comma separated country list" -msgstr "Komma-getrennte Länderliste" +#~ msgid "Specifiy config file" +#~ msgstr "Konfigurationsdatei angeben" -#: share/completions/apt-spy.fish:13 -msgid "How long in sec to download" -msgstr "Dauer des Herunterladens in Sekunden" +#~ msgid "Resync package contents from source" +#~ msgstr "Paketinhalte aus der Quelle neu synchronisieren" -#: share/completions/apt-spy.fish:14 -msgid "Custom URL to get mirror list" -msgstr "Angepasste URL zum Abruf der Spiegelliste" +#~ msgid "Search package containing pattern" +#~ msgstr "Paket entsprechend Muster suchen" -#: share/completions/apt-spy.fish:16 -msgid "Number of top servers" -msgstr "Anzahl der Top-Server" +#~ msgid "List contents of a package matching pattern" +#~ msgstr "Inhalte eines Paketes auflisten, das dem Muster entspricht" -#: share/completions/apt-spy.fish:17 -msgid "Update mirror list" -msgstr "Spiegelliste aktualisieren" +#~ msgid "Remove all gz files from cache" +#~ msgstr "Alle gz-Dateien aus dem Zwischenspeicher entfernen" -#: share/completions/apt-spy.fish:18 -msgid "Version number" -msgstr "Versionsnummer" +#~ msgid "Set cache dir" +#~ msgstr "Verzeichnis für Zwischenspeicher festlegen" -#: share/completions/apt-src.fish:3 -msgid "Update list of source packages" -msgstr "Liste der Quellpakete aktualisieren" +#~ msgid "Do not expand pattern" +#~ msgstr "Erweitern Sie das Muster nicht" -#: share/completions/apt-src.fish:4 -msgid "Install source packages" -msgstr "Quellpakete installieren" +#~ msgid "Pattern is regexp" +#~ msgstr "Muster ist ein regulärer Ausdruck" -#: share/completions/apt-src.fish:5 -msgid "Upgrade source packages" -msgstr "Quellpakete aktualisieren" +#~ msgid "Set arch" +#~ msgstr "Architektur festlegen" -#: share/completions/apt-src.fish:6 -msgid "Remove source packages" -msgstr "Quellpakete entfernen" +#~ msgid "Set sources.list file" +#~ msgstr "sources.list-Datei angeben" -#: share/completions/apt-src.fish:7 share/completions/apt-src.fish:14 -msgid "Build source packages" -msgstr "Quellpakete erstellen" +#~ msgid "Only display package name" +#~ msgstr "Nur Paketnamen anzeigen" -#: share/completions/apt-src.fish:8 -msgid "Clean source packages" -msgstr "Quellpakete bereinigen" +#~ msgid "Run in dummy mode" +#~ msgstr "Im Dummy-Modus ausführen" -#: share/completions/apt-src.fish:9 -msgid "Detect known source tree" -msgstr "Bekannte Quellbäume entdecken" +#~ msgid "Generate package from source" +#~ msgstr "Paket aus Quelle generieren" -#: share/completions/apt-src.fish:10 -msgid "List installed source package\\(s\\)" -msgstr "Installierte(s) Quellpaket(e) auflisten" +#~ msgid "Generate source index file" +#~ msgstr "Quellindexdatei erstellen" -#: share/completions/apt-src.fish:11 -msgid "Root source tree" -msgstr "Ursprung des Quellbaumes" +#~ msgid "Generate contents file" +#~ msgstr "Inhaltsdatei erstellen" -#: share/completions/apt-src.fish:12 -msgid "Version of source package" -msgstr "Version des Quellpaketes" +#~ msgid "Generate release file" +#~ msgstr "Veröffentlichungsdatei erstellen" -#: share/completions/apt-src.fish:13 -msgid "Name of the source package" -msgstr "Name des Quellpaketes" +#~ msgid "Remove records" +#~ msgstr "Sätze entfernen" -#: share/completions/apt-src.fish:15 -msgid "Install after build" -msgstr "Nach Erstellung installieren" +#~ msgid "Generate MD5 sums" +#~ msgstr "MD5-Summen erstellen" -#: share/completions/apt-src.fish:16 -msgid "Patch local changes" -msgstr "Lokale Änderungen patchen" +#~ msgid "Use a binary db" +#~ msgstr "Eine Binärdatenbank benutzen" -#: share/completions/apt-src.fish:17 -msgid "Specify a dir" -msgstr "Verzeichnis angeben" +#~ msgid "Perform delinking" +#~ msgstr "Trennung ausführen" -#: share/completions/apt-src.fish:19 -msgid "Omit debian version" -msgstr "Debian-Version auslassen" +#~ msgid "Perform contents generation" +#~ msgstr "Inhaltsgenerierung durchführen" -#: share/completions/apt-src.fish:20 -msgid "Do not del built files" -msgstr "Erstellte Dateien nicht löschen" +#~ msgid "Make caching db readonly" +#~ msgstr "Zwischenspeicherdatenbank schreibschützen" -#: share/completions/apt-src.fish:21 -msgid "Do not del source files" -msgstr "Quelldateien nicht löschen" +#~ msgid "Use config file" +#~ msgstr "Konfigurationsdatei benutzen" -#: share/completions/apt-src.fish:22 -msgid "Source tree version" -msgstr "Version des Quellenbaumes" +#~ msgid "Set config options" +#~ msgstr "Konfigurationsoptionen festlegen" -#: share/completions/apt-src.fish:23 -msgid "Output to /dev/null" -msgstr "Ausgabe nach /dev/null" +#~ msgid "Test if apt has yet to be given the subcommand" +#~ msgstr "Test, ob an apt noch ein Unterbefehl gegeben werden muss" -#: share/completions/apt-src.fish:24 -msgid "Output trace" -msgstr "Ausgabeverfolgung" +#~ msgid "Update sources" +#~ msgstr "Quellen aktualisieren" -#: share/completions/apt-zip-inst.fish:5 share/completions/apt-zip-list.fish:5 -msgid "Select an action" -msgstr "Eine Aktion auswählen" +#~ msgid "Upgrade or install newest packages" +#~ msgstr "Neueste Pakete aktualisieren oder installieren" -#: share/completions/apt-zip-inst.fish:7 share/completions/apt-zip-list.fish:7 -msgid "Fix broken option" -msgstr "Kaputte Option bereinigen" +#~ msgid "Use with dselect front-end" +#~ msgstr "Mit dselect-Oberfläche verwenden" -#: share/completions/aptitude.fish:3 -#, fuzzy -msgid "Test if aptitude has yet to be given the subcommand" -msgstr "Test, ob an apt noch ein Unterbefehl gegeben werden muss" +#~ msgid "Distro upgrade" +#~ msgstr "Aktualisierung der Distribution" -#: share/completions/aptitude.fish:12 -#, fuzzy -msgid "Test if aptitude command should have packages as potential completion" -msgstr "" -"Testen, ob der apt-Befehl Pakete zur möglichen Fertigstellung haben sollte" +#~ msgid "Install one or more packages" +#~ msgstr "Ein oder mehrere Paket(e) installieren" -#: share/completions/aptitude.fish:24 #, fuzzy -msgid "Remove any cached packages which can no longer be downloaded" -msgstr "Pakete, die nicht länger heruntergeladen werden, bereinigen" +#~ msgid "Remove and purge one or more packages" +#~ msgstr "Ein oder mehrere Paket(e) entfernen" -#: share/completions/aptitude.fish:25 -msgid "Remove all downloaded .deb files from the package cache directory" -msgstr "" +#~ msgid "Remove one or more packages" +#~ msgstr "Ein oder mehrere Paket(e) entfernen" -#: share/completions/aptitude.fish:26 -msgid "Forget all internal information about what packages are \\new" -msgstr "" +#~ msgid "Fetch source packages" +#~ msgstr "Quellpakete abrufen" -#: share/completions/aptitude.fish:27 -msgid "Cancel all scheduled actions on all packages" -msgstr "" +#~ msgid "Install/remove packages for dependencies" +#~ msgstr "Pakete für Abhängigkeiten installieren/entfernen" -#: share/completions/aptitude.fish:28 -msgid "Update the list of available packages from the apt sources" -msgstr "" +#~ msgid "Update cache and check dependencies" +#~ msgstr "Zwischenspeicher aktualisieren und Abhängigkeiten prüfen" -#: share/completions/aptitude.fish:29 -#, fuzzy -msgid "Upgrade installed packages to their most recent version" -msgstr "Alle Quellpakete mit Version ausgeben" +#~ msgid "Clean local caches and packages" +#~ msgstr "Lokalen Zwischenspeicher und Pakete bereinigen" -#: share/completions/aptitude.fish:30 -#, fuzzy -msgid "Download and displays the Debian changelog for the packages" -msgstr "Zeigt Änderungsinformationen zu dem Paket an" +#~ msgid "Clean packages no longer be downloaded" +#~ msgstr "Pakete, die nicht länger heruntergeladen werden, bereinigen" -#: share/completions/aptitude.fish:31 #, fuzzy -msgid "Upgrade, removing or installing packages as necessary" -msgstr "Neueste Pakete aktualisieren oder installieren" +#~ msgid "Remove automatically installed packages" +#~ msgstr "Alle installierten Pakete abfragen" -#: share/completions/aptitude.fish:32 -#, fuzzy -msgid "Download the packages to the current directory" -msgstr "Nie ins übergeordnete Verzeichnis wechseln" +#~ msgid "Specify a config file" +#~ msgstr "Konfigurationsdatei angeben" -#: share/completions/aptitude.fish:33 -msgid "Forbid the upgrade to a particular version" -msgstr "" +#~ msgid "Set a config option" +#~ msgstr "Konfigurationsoption festlegen" -#: share/completions/aptitude.fish:34 -msgid "Ignore the packages by future upgrade commands" -msgstr "" +#~ msgid "Add a new key" +#~ msgstr "Neuen Schlüssel hinzufügen" -#: share/completions/aptitude.fish:35 -#, fuzzy -msgid "Install the packages" -msgstr "Neues Paket installieren" +#~ msgid "Remove a key" +#~ msgstr "Schlüssel entfernen" -#: share/completions/aptitude.fish:36 -#, fuzzy -msgid "Cancel any scheduled actions on the packages" -msgstr "Zeigt Änderungsinformationen zu dem Paket an" +#~ msgid "List trusted keys" +#~ msgstr "Vertraute Schlüssel auflisten" -#: share/completions/aptitude.fish:37 -#, fuzzy -msgid "Mark packages as automatically installed" -msgstr "Paket aktualisieren, wenn es bereits installiert ist" +#~ msgid "Set severity" +#~ msgstr "Schwere festlegen" -#: share/completions/aptitude.fish:38 -msgid "Remove and delete all associated configuration and data files" -msgstr "" +#~ msgid "Tags you want to see" +#~ msgstr "Markierungen, die Sie sehen möchten" -#: share/completions/aptitude.fish:39 -#, fuzzy -msgid "Reinstall the packages" -msgstr "Pakete erneut installieren" +#~ msgid "Bug-status you want to see" +#~ msgstr "Fehlerstatus, den Sie sehen möchten" -#: share/completions/aptitude.fish:40 -#, fuzzy -msgid "Remove the packages" -msgstr "Pakete entfernen" +#~ msgid "Ignore bugs in your system" +#~ msgstr "Fehler in Ihrem System ignorieren" -#: share/completions/aptitude.fish:41 -#, fuzzy -msgid "Display detailed information about the packages" -msgstr "Zeigt Änderungsinformationen zu dem Paket an" +#~ msgid "Ignore newer bugs than upgrade packages" +#~ msgstr "Fehler, die neuer sind als Aktualisierungspakete, ignorieren" -#: share/completions/aptitude.fish:42 -msgid "Consider the packages by future upgrade commands" -msgstr "" +#~ msgid "Bugs for downgrade packages" +#~ msgstr "Fehler bei Downgrade-Paketen" -#: share/completions/aptitude.fish:43 -#, fuzzy -msgid "Mark packages as manually installed" -msgstr "Paket aktualisieren, wenn es bereits installiert ist" +#~ msgid "Bug Tracking system" +#~ msgstr "Fehlerverfolgungssystem" -#: share/completions/aptitude.fish:44 -#, fuzzy -msgid "Search for packages matching one of the patterns" -msgstr "Paket entsprechend Muster suchen" +#~ msgid "Specify port for web interface" +#~ msgstr "Port für Weboberfläche angeben" -#: share/completions/aptitude.fish:45 -msgid "Display brief summary of the available commands and options" -msgstr "" +#~ msgid "Use daily bug report" +#~ msgstr "Täglichen Fehlerbericht verwenden" -#: share/completions/arp.fish:4 -msgid "Class of hw type" -msgstr "Klasse des Hardwaretyps" +#~ msgid "Use the raw index.db" +#~ msgstr "Die rohe index.db verwenden" -#: share/completions/arp.fish:5 -msgid "Show arp entries" -msgstr "Arp-Einträge anzeigen" +#~ msgid "Specify index dir" +#~ msgstr "Indexverzeichnis angeben" -#: share/completions/arp.fish:6 -msgid "Remove an entry for hostname" -msgstr "Eintrag für Hostname entfernen" +#~ msgid "Specify Pin-Priority value" +#~ msgstr "Pin-Prioritätswert angeben" -#: share/completions/arp.fish:8 -msgid "Select interface" -msgstr "Schnittstelle auswählen" +#~ msgid "Specify the title of rss" +#~ msgstr "Geben Sie einen Titel für rss an" -#: share/completions/arp.fish:9 -msgid "Manually create ARP address" -msgstr "ARP-Adresse manuell erzeugen" +#~ msgid "Retrieve fresh bugs" +#~ msgstr "Neue Bugs abrufen" -#: share/completions/arp.fish:10 -msgid "Take addr from filename, default /etc/ethers" -msgstr "Adresse aus Dateiname entnehmen, Standard /etc/ethers" +#~ msgid "Do not display progress bar" +#~ msgstr "Keinen Fortschrittsbalken anzeigen" -#: share/completions/at.fish:3 share/completions/atq.fish:3 -msgid "Use specified queue" -msgstr "Angegebene Warteschlange benutzen" +#~ msgid "Specify local cache dir" +#~ msgstr "Verzeichnis für lokalen Zwischenspeicher angeben" -#: share/completions/at.fish:4 -msgid "Send mail to user" -msgstr "Mail an Benutzer senden" +#~ msgid "Specify the expire cache timer" +#~ msgstr "Zeitablauf für Zwischenspeicher angeben" -#: share/completions/at.fish:5 -msgid "Read job from file" -msgstr "Job aus Datei lesen" +#~ msgid "Assume yes to all questions" +#~ msgstr "Bei allen Fragen ja annehmen" -#: share/completions/at.fish:6 -msgid "Alias for atq" -msgstr "Alias für atq" +#~ msgid "Assume no to all questions" +#~ msgstr "Für alle Fragen nein annehmen" -#: share/completions/at.fish:7 -msgid "Alias for atrm" -msgstr "Alias für atrm" +#, fuzzy +#~ msgid "Select frontend interface" +#~ msgstr "Benutzerschnittstelle auswählen" -#: share/completions/at.fish:8 -msgid "Show the time" -msgstr "Zeige Zeit" +#~ msgid "Ask confirmation" +#~ msgstr "Bestätigung erfragen" -#: share/completions/at.fish:9 -msgid "Print the jobs listed" -msgstr "Aufgelistete Jobs ausgeben" +#~ msgid "Display all changelogs" +#~ msgstr "Alle Änderungsprotokolle anzeigen" -#: share/completions/atd.fish:2 -msgid "Limiting load factor" -msgstr "Auslastungsbegrenzung" +#~ msgid "Avoid changelogs from db in named file" +#~ msgstr "Änderungsprotokolle aus der Datenbank der benannten Datei vermeiden" -#: share/completions/atd.fish:3 -msgid "Minimum interval in seconds" -msgstr "Minimalintervall in Sekunden" +#~ msgid "Insert header" +#~ msgstr "Kopfzeile einfügen" -#: share/completions/atd.fish:4 -msgid "Debug mode" -msgstr "Debug-Modus" +#~ msgid "Display debug info" +#~ msgstr "Debug-Informationen anzeigen" -#: share/completions/atd.fish:5 -msgid "Process at queue only once" -msgstr "at-Warteschlange nur einmal verarbeiten" +#~ msgid "Select an option profile" +#~ msgstr "Optionsprofil auswählen" -#: share/completions/bundle.fish:3 #, fuzzy -msgid "Test if bundle has been given no subcommand" -msgstr "Test, ob an apt noch ein Unterbefehl gegeben werden muss" +#~ msgid "Mark a package as automatically installed" +#~ msgstr "Paket aktualisieren, wenn es bereits installiert ist" -#: share/completions/bundle.fish:11 #, fuzzy -msgid "Test if bundle has been given a specific subcommand" -msgstr "Test, ob an apt noch ein Unterbefehl gegeben werden muss" +#~ msgid "Mark a package as manually installed" +#~ msgstr "Paket aktualisieren, wenn es bereits installiert ist" -#: share/completions/bundle.fish:31 #, fuzzy -msgid "Display a help page" -msgstr "Handbuchseite anzeigen" +#~ msgid "Cancel a hold on a package" +#~ msgstr "Informationen über ein Paket" -#: share/completions/bundle.fish:39 share/completions/bundle.fish:83 -msgid "Install the gems specified by the Gemfile or Gemfile.lock" -msgstr "" +#, fuzzy +#~ msgid "Show automatically installed packages" +#~ msgstr "Alle installierten Pakete abfragen" -#: share/completions/bundle.fish:40 share/completions/bundle.fish:106 -msgid "The location of the Gemfile bundler should use" -msgstr "" +#, fuzzy +#~ msgid "Show manually installed packages" +#~ msgstr "Alle installierten Pakete abfragen" -#: share/completions/bundle.fish:41 #, fuzzy -msgid "The location to install the gems in the bundle to" -msgstr "Prozesskennung jedes Prozesses im Job anzeigen" +#~ msgid "Show held packages" +#~ msgstr "Aktualisierte Pakete anzeigen" -#: share/completions/bundle.fish:42 #, fuzzy -msgid "Installs the gems in the bundle to the system location" -msgstr "Dateien in das Paketdepot übertragen" +#~ msgid "Write package statistics to a file" +#~ msgstr "Prototypen in Datei schreiben" -#: share/completions/bundle.fish:43 -msgid "A space-separated list of groups to skip installing" -msgstr "" +#~ msgid "Move packages to local tree" +#~ msgstr "Pakete in lokalen Verzeichnisbaum verschieben" -#: share/completions/bundle.fish:44 -msgid "Use cached gems instead of connecting to rubygems.org" -msgstr "" +#~ msgid "Delete obsolete package files" +#~ msgstr "Veraltete Paketdateien löschen" -#: share/completions/bundle.fish:45 -msgid "Switches bundler's defaults into deployment mode." -msgstr "" +#~ msgid "Build new local files" +#~ msgstr "Neue lokale Dateien erstellen" -#: share/completions/bundle.fish:46 -msgid "" -"Create a directory containing executabes that run in the context of the " -"bundle" -msgstr "" +#~ msgid "Rebuild index files" +#~ msgstr "Indexdateien neu erstellen" -#: share/completions/bundle.fish:47 -msgid "Specify a ruby executable to use with generated binstubs" -msgstr "" +#~ msgid "Move packages from cache to local mirror" +#~ msgstr "Pakete aus Zwischenspeicher auf lokalen Spiegelserver verschieben" -#: share/completions/bundle.fish:48 -msgid "Make a bundle that can work without RubyGems or Bundler at run-time" -msgstr "" +#~ msgid "Alias for 'move delete packages'" +#~ msgstr "Alias für 'move delete packages' '" -#: share/completions/bundle.fish:49 -msgid "Apply a RubyGems security policy: {High,Medium,Low,No}Security" -msgstr "" +#~ msgid "Alias for 'update'" +#~ msgstr "Alias für 'update'" -#: share/completions/bundle.fish:50 -msgid "Install gems parallely by starting size number of parallel workers" -msgstr "" +#~ msgid "Download package missing from mirror" +#~ msgstr "Fehlende Pakete vom Spiegelserver herunterladen" -#: share/completions/bundle.fish:51 -msgid "Do not update the cache in vendor/cache with the newly bundled gems" -msgstr "" +#~ msgid "Sync packages installed" +#~ msgstr "Installierte Pakete synchronisieren" -#: share/completions/bundle.fish:52 #, fuzzy -msgid "Do not print progress information to stdout" -msgstr "Keine Gruppeninformation ausgeben" +#~ msgid "List packages that may serve as input to mirrorbin or mirrorsource" +#~ msgstr "" +#~ "Pakete auflisten, die als Quelle für mirrorbin oder mirrorsource dienen " +#~ "können" -#: share/completions/bundle.fish:53 -#, fuzzy -msgid "Run bundle clean automatically after install" -msgstr "Paket aktualisieren, wenn es bereits installiert ist" +#~ msgid "Fetch package from STDIN" +#~ msgstr "Paket über Standardeingabe lesen" -#: share/completions/bundle.fish:54 share/completions/bundle.fish:63 -msgid "Use the rubygems modern index instead of the API endpoint" -msgstr "" +#~ msgid "Fetch source package from STDIN" +#~ msgstr "Quellpaket über Standardeingabe lesen" -#: share/completions/bundle.fish:55 share/completions/bundle.fish:164 -#, fuzzy -msgid "Do not remove stale gems from the cache" -msgstr "Alle gz-Dateien aus dem Zwischenspeicher entfernen" +#~ msgid "Process all packages" +#~ msgstr "Alle Pakete verarbeiten" -#: share/completions/bundle.fish:56 -msgid "Do not allow the Gemfile.lock to be updated after this install" -msgstr "" +#~ msgid "Force deletion" +#~ msgstr "Löschung erzwingen" -#: share/completions/bundle.fish:59 share/completions/bundle.fish:84 -#, fuzzy -msgid "Update dependencies to their latest versions" -msgstr "Abhängigkeiten an makefile anhängen" +#~ msgid "Suppresses normal output" +#~ msgstr "Normale Ausgabe unterdrücken" -#: share/completions/bundle.fish:60 -msgid "The name of a :git or :path source used in the Gemfile" -msgstr "" +#~ msgid "Test run" +#~ msgstr "Testdurchlauf" -#: share/completions/bundle.fish:61 -msgid "Do not attempt to fetch gems remotely and use the gem cache instead" -msgstr "" +#~ msgid "No message to STDOUT" +#~ msgstr "Keine Meldungen auf Standardausgabe" -#: share/completions/bundle.fish:62 -msgid "Only output warnings and errors" -msgstr "" +#~ msgid "Recurse into subdir" +#~ msgstr "in Unterverzeichnis verzweigen" -#: share/completions/bundle.fish:64 -#, fuzzy -msgid "Specify the number of jobs to run in parallel" -msgstr "Gibt die Anzahl zu sendender Bytes an" +#~ msgid "Dir to import" +#~ msgstr "Zu importierendes Verzeichnis" -#: share/completions/bundle.fish:65 -msgid "Update a specific group" -msgstr "" +#~ msgid "Change to user" +#~ msgstr "Wechsel zu Benutzer" -#: share/completions/bundle.fish:69 -msgid "" -"Package the .gem files required by your application into the vendor/cache " -"directory" -msgstr "" +#~ msgid "Debug level[default 0]" +#~ msgstr "Debug-Grad [Standard 0]" -#: share/completions/bundle.fish:72 #, fuzzy -msgid "Install the binstubs of the listed gem" -msgstr "Namen aller Signale anzeigen" +#~ msgid "Show build dependencies" +#~ msgstr "Erstellungsabhängigkeiten anzeigen" -#: share/completions/bundle.fish:73 -#, fuzzy -msgid "Binstub destination directory (default bin)" -msgstr "Dokumentationsdateien installieren (Standard)" +#~ msgid "Generate a dotty graph" +#~ msgstr "Gepunkteten Graph generieren" -#: share/completions/bundle.fish:74 -msgid "Overwrite existing binstubs if they exist" -msgstr "" +#~ msgid "Show state of dependencies" +#~ msgstr "Status der Abhängigkeiten anzeigen" -#: share/completions/bundle.fish:78 share/completions/bundle.fish:86 -msgid "Execute a script in the context of the current bundle" -msgstr "" +#~ msgid "List packages depending on" +#~ msgstr "Pakete auflisten, die abhängen von " -#: share/completions/bundle.fish:79 -msgid "Exec runs a command, providing it access to the gems in the bundle" -msgstr "" +#~ msgid "Display man page" +#~ msgstr "Handbuchseite anzeigen" -#: share/completions/bundle.fish:82 -msgid "Describe available tasks or one specific task" -msgstr "" +#~ msgid "Read package from file" +#~ msgstr "Paket aus Datei lesen" -#: share/completions/bundle.fish:85 -#, fuzzy -msgid "Package .gem files into the vendor/cache directory" -msgstr "Dateien in das Paketdepot übertragen" +#~ msgid "Specify APT list dir" +#~ msgstr "APT-Listenverzeichnis angeben" -#: share/completions/bundle.fish:87 -#, fuzzy -msgid "Specify and read configuration options for bundler" -msgstr "Eine Konfigurationsdatei angeben" - -#: share/completions/bundle.fish:88 -msgid "Check bundler requirements for your application" -msgstr "" - -#: share/completions/bundle.fish:89 -msgid "Show all of the gems in the current bundle" -msgstr "" - -#: share/completions/bundle.fish:90 -#, fuzzy -msgid "Show the source location of a particular gem in the bundle" -msgstr "Prozesskennung jedes Prozesses im Job anzeigen" +#~ msgid "List PKG info" +#~ msgstr "PKG-Information auflisten" -#: share/completions/bundle.fish:91 share/completions/bundle.fish:121 -msgid "Show all of the outdated gems in the current bundle" -msgstr "" +#~ msgid "Print all source packages with version" +#~ msgstr "Alle Quellpakete mit Version ausgeben" -#: share/completions/bundle.fish:92 share/completions/bundle.fish:129 -msgid "Start an IRB session in the context of the current bundle" -msgstr "" +#~ msgid "Print PKG versions" +#~ msgstr "PKG-Versionen ausgeben" -#: share/completions/bundle.fish:93 share/completions/bundle.fish:132 -#, sh-format -msgid "Open an installed gem in your $EDITOR" -msgstr "" +#~ msgid "Using regex" +#~ msgstr "Regulären Ausdruck benutzen" -#: share/completions/bundle.fish:94 share/completions/bundle.fish:136 -msgid "Generate a visual representation of your dependencies" -msgstr "" +#~ msgid "Print only upgradeable packages" +#~ msgstr "Nur aktualisierbare Pakete ausgeben" -#: share/completions/bundle.fish:95 -#, fuzzy -msgid "Generate a simple Gemfile" -msgstr "Masterdatei erstellen" +#~ msgid "Print all versions" +#~ msgstr "Alle Versionen ausgeben" -#: share/completions/bundle.fish:96 share/completions/bundle.fish:147 -msgid "Create a simple gem, suitable for development with bundler" -msgstr "" +#~ msgid "Print package name/distro" +#~ msgstr "Paketname/Distribution ausgeben" -#: share/completions/bundle.fish:97 share/completions/bundle.fish:154 -msgid "Displays platform compatibility information" -msgstr "" +#~ msgid "Print verbose info" +#~ msgstr "Ausführliche Informationen ausgeben" -#: share/completions/bundle.fish:98 share/completions/bundle.fish:158 -msgid "Cleans up unused gems in your bundler directory" -msgstr "" +#~ msgid "Init or update cache only" +#~ msgstr "Nur Zwischenspeicher initialisieren oder aktualisieren" -#: share/completions/bundle.fish:105 -msgid "" -"Determine whether the requirements for your application are installed and " -"available to bundler" -msgstr "" +#~ msgid "Use source index field" +#~ msgstr "Indexfeld der Quelle verwenden" -#: share/completions/bundle.fish:107 -msgid "Specify a path other than the system default (BUNDLE_PATH or GEM_HOME)" -msgstr "" +#~ msgid "Specify conffile" +#~ msgstr "Konfigurationsdatei angeben" -#: share/completions/bundle.fish:108 #, fuzzy -msgid "Lock the Gemfile" -msgstr "Log in Datei schreiben" +#~ msgid "Debian distribution" +#~ msgstr "Debian-Distribution" -#: share/completions/bundle.fish:111 share/completions/bundle.fish:116 -msgid "" -"Show lists the names and versions of all gems that are required by your " -"Gemfile" -msgstr "" +#~ msgid "Servers in the areas" +#~ msgstr "Server in diesem Bereich" -#: share/completions/bundle.fish:112 share/completions/bundle.fish:117 -msgid "List the paths of all gems required by your Gemfile" -msgstr "" +#~ msgid "Finish after number of servers" +#~ msgstr "Nach Anzahl der Server beenden" -#: share/completions/bundle.fish:122 -#, fuzzy -msgid "Check for newer pre-release gems" -msgstr "Test auf Speicher-Lecks" +#~ msgid "Use proxy server" +#~ msgstr "Proxy-Server verwenden" -#: share/completions/bundle.fish:123 -msgid "Check against a specific source" -msgstr "" +#~ msgid "Comma separated country list" +#~ msgstr "Komma-getrennte Länderliste" -#: share/completions/bundle.fish:124 -msgid "Use cached gems instead of attempting to fetch gems remotely" -msgstr "" +#~ msgid "How long in sec to download" +#~ msgstr "Dauer des Herunterladens in Sekunden" -#: share/completions/bundle.fish:125 -msgid "Only list newer versions allowed by your Gemfile requirements" -msgstr "" +#~ msgid "Custom URL to get mirror list" +#~ msgstr "Angepasste URL zum Abruf der Spiegelliste" -#: share/completions/bundle.fish:137 -msgid "The name to use for the generated file (see format option)" -msgstr "" +#~ msgid "Number of top servers" +#~ msgstr "Anzahl der Top-Server" -#: share/completions/bundle.fish:138 -#, fuzzy -msgid "Show each gem version" -msgstr "Version des Quellenbaumes" +#~ msgid "Update mirror list" +#~ msgstr "Spiegelliste aktualisieren" -#: share/completions/bundle.fish:139 -msgid "Show the version of each required dependency" -msgstr "" +#~ msgid "Version number" +#~ msgstr "Versionsnummer" -#: share/completions/bundle.fish:140 -msgid "Output a specific format (png, jpg, svg, dot, ...)" -msgstr "" +#~ msgid "Update list of source packages" +#~ msgstr "Liste der Quellpakete aktualisieren" -#: share/completions/bundle.fish:143 -#, fuzzy -msgid "Generate a simple Gemfile, placed in the current directory" -msgstr "Nie ins übergeordnete Verzeichnis wechseln" - -#: share/completions/bundle.fish:144 -msgid "Use a specified .gemspec to create the Gemfile" -msgstr "" +#~ msgid "Install source packages" +#~ msgstr "Quellpakete installieren" -#: share/completions/bundle.fish:148 -msgid "Generate a binary for your library" -msgstr "" +#~ msgid "Upgrade source packages" +#~ msgstr "Quellpakete aktualisieren" -#: share/completions/bundle.fish:149 -msgid "Generate a test directory for your library (rspec or minitest)" -msgstr "" +#~ msgid "Remove source packages" +#~ msgstr "Quellpakete entfernen" -#: share/completions/bundle.fish:150 -msgid "Path to your editor" -msgstr "" +#~ msgid "Build source packages" +#~ msgstr "Quellpakete erstellen" -#: share/completions/bundle.fish:151 -msgid "Generate the boilerplate for C extension code" -msgstr "" +#~ msgid "Clean source packages" +#~ msgstr "Quellpakete bereinigen" -#: share/completions/bundle.fish:155 -msgid "Only display Ruby directive information" -msgstr "" +#~ msgid "Detect known source tree" +#~ msgstr "Bekannte Quellbäume entdecken" -#: share/completions/bundle.fish:159 -msgid "Only print out changes, do not actually clean gems" -msgstr "" +#~ msgid "List installed source package\\(s\\)" +#~ msgstr "Installierte(s) Quellpaket(e) auflisten" -#: share/completions/bundle.fish:160 -msgid "Forces clean even if --path is not set" -msgstr "" +#~ msgid "Root source tree" +#~ msgstr "Ursprung des Quellbaumes" -#: share/completions/bundle.fish:163 -msgid "Cache all the gems to vendor/cache" -msgstr "" +#~ msgid "Version of source package" +#~ msgstr "Version des Quellpaketes" -#: share/completions/bundle.fish:165 -msgid "Include all sources (including path and git)" -msgstr "" +#~ msgid "Name of the source package" +#~ msgstr "Name des Quellpaketes" -#: share/completions/bundle.fish:168 -#, fuzzy -msgid "Prints the license of all gems in the bundle" -msgstr "Prozesskennung jedes Prozesses im Job anzeigen" +#~ msgid "Install after build" +#~ msgstr "Nach Erstellung installieren" -#: share/completions/bundle.fish:171 -msgid "Print information about the environment Bundler is running under" -msgstr "" +#~ msgid "Patch local changes" +#~ msgstr "Lokale Änderungen patchen" -#: share/completions/configure.fish:1 -#: share/functions/__fish_complete_diff.fish:27 -#: share/functions/__fish_complete_grep.fish:22 -#: share/functions/__fish_complete_ls.fish:95 -#: share/functions/__fish_complete_tex.fish:4 -msgid "Display help and exit" -msgstr "Hilfe anzeigen und beenden" +#~ msgid "Specify a dir" +#~ msgstr "Verzeichnis angeben" -#: share/completions/configure.fish:4 -msgid "Cache test results in specified file" -msgstr "Testergebnisse in angegebener Datei zwischenspeichern" +#~ msgid "Omit debian version" +#~ msgstr "Debian-Version auslassen" -#: share/completions/cp.fish:11 share/completions/mv.fish:6 -msgid "Backup suffix" -msgstr "Endung für Sicherung" +#~ msgid "Do not del built files" +#~ msgstr "Erstellte Dateien nicht löschen" -#: share/completions/cp.fish:20 -msgid "Preserve ATTRIBUTES if possible" -msgstr "" +#~ msgid "Do not del source files" +#~ msgstr "Quelldateien nicht löschen" -#: share/completions/cp.fish:29 -msgid "Set security context of copy to CONTEXT" -msgstr "" +#~ msgid "Source tree version" +#~ msgstr "Version des Quellenbaumes" -#: share/completions/cut.fish:2 -#, fuzzy -msgid "Output byte range" -msgstr "Bytebereich ausgeben" +#~ msgid "Output to /dev/null" +#~ msgstr "Ausgabe nach /dev/null" -#: share/completions/cut.fish:3 -msgid "Output character range" -msgstr "Zeichenbereich ausgeben" +#~ msgid "Output trace" +#~ msgstr "Ausgabeverfolgung" -#: share/completions/cut.fish:4 -msgid "Select field delimiter" -msgstr "Feldbegrenzer auswählen" +#~ msgid "Select an action" +#~ msgstr "Eine Aktion auswählen" -#: share/completions/cut.fish:5 -msgid "Select fields" -msgstr "Felder auswählen" +#~ msgid "Fix broken option" +#~ msgstr "Kaputte Option bereinigen" -#: share/completions/cvs.fish:26 #, fuzzy -msgid "Use \\tmpdir for temporary files." -msgstr "tmpdir für temporäre Dateien benutzen" +#~ msgid "Test if aptitude has yet to be given the subcommand" +#~ msgstr "Test, ob an apt noch ein Unterbefehl gegeben werden muss" -#: share/completions/cvs.fish:27 #, fuzzy -msgid "Use \\editor for editing log information." -msgstr "Editor zum Editieren der Loginformation verwenden" +#~ msgid "" +#~ "Test if aptitude command should have packages as potential completion" +#~ msgstr "" +#~ "Testen, ob der apt-Befehl Pakete zur möglichen Fertigstellung haben sollte" -#: share/completions/cvs.fish:28 -#, sh-format -msgid "Overrides $CVSROOT as the root of the CVS tree." -msgstr "" - -#: share/completions/cvs.fish:30 #, fuzzy -msgid "Request compression level \\# for net traffic." -msgstr "Komprimierungsgrad für Netzverkehr" +#~ msgid "Remove any cached packages which can no longer be downloaded" +#~ msgstr "Pakete, die nicht länger heruntergeladen werden, bereinigen" -#: share/completions/cvs.fish:35 #, fuzzy -msgid "Set CVS user variable." -msgstr "CVS-Benutzervariable festlegen" - -#: share/completions/cvs.fish:41 -msgid "Add a new file/directory to the repository" -msgstr "Neue/s Datei/Verzeichnis zum Paketdepot hinzufügen" - -#: share/completions/cvs.fish:42 -msgid "Administration front end for rcs" -msgstr "Administrationsoberfläche für rcs" +#~ msgid "Upgrade installed packages to their most recent version" +#~ msgstr "Alle Quellpakete mit Version ausgeben" -#: share/completions/cvs.fish:43 -msgid "Show last revision where each line was modified" -msgstr "Letzte Revision anzeigen, bei der jede Zeile verändert wurde" - -#: share/completions/cvs.fish:44 -msgid "Checkout sources for editing" -msgstr "Quellen zum Editieren auschecken" - -#: share/completions/cvs.fish:45 -msgid "Check files into the repository" -msgstr "Dateien in das Paketdepot übertragen" - -#: share/completions/cvs.fish:46 -msgid "Show differences between revisions" -msgstr "Unterschiede zwischen Revisionen anzeigen" - -#: share/completions/cvs.fish:47 -msgid "Get ready to edit a watched file" -msgstr "Vorbereitung zum Editieren einer beobachteten Datei" - -#: share/completions/cvs.fish:48 -msgid "See who is editing a watched file" -msgstr "Anzeigen, von wem eine beobachtete Datei editiert wird" - -#: share/completions/cvs.fish:49 -msgid "Export sources from CVS, similar to checkout" -msgstr "Quellen aus CVS exportieren, ähnelt checkout" - -#: share/completions/cvs.fish:50 -msgid "Show repository access history" -msgstr "Zugriffsverlauf des Paketdepots anzeigen" - -#: share/completions/cvs.fish:51 -msgid "Import sources into CVS, using vendor branches" -msgstr "Quellen in CVS importieren, verwende Herstellerzweige" - -#: share/completions/cvs.fish:52 #, fuzzy -msgid "Create a CVS repository if it doesn\\t" -msgstr "CVS-Paketdepot erstellen, wenn es nicht existiert" - -#: share/completions/cvs.fish:91 -msgid "Set comment leader." -msgstr "" +#~ msgid "Download and displays the Debian changelog for the packages" +#~ msgstr "Zeigt Änderungsinformationen zu dem Paket an" -#: share/completions/cvs.fish:94 #, fuzzy -msgid "Set keyword substitution mode:" -msgstr "Befehlsersetzungsblock" - -#: share/completions/cvs.fish:97 -msgid "Replace revision\\s" -msgstr "" - -#: share/completions/cvs.fish:135 -msgid "Check out revision or tag. (implies -P) (is sticky)" -msgstr "" - -#: share/completions/cvs.fish:136 -msgid "Check out revisions as of date. (implies -P) (is sticky)" -msgstr "" - -#: share/completions/cvs.fish:137 -msgid "Check out into dir instead of module name." -msgstr "" - -#: share/completions/cvs.fish:138 -msgid "Use RCS kopt -k option on checkout. (is sticky)" -msgstr "" +#~ msgid "Upgrade, removing or installing packages as necessary" +#~ msgstr "Neueste Pakete aktualisieren oder installieren" -#: share/completions/cvs.fish:139 -msgid "Merge in changes made between current revision and rev." -msgstr "" - -#: share/completions/cvs.fish:150 #, fuzzy -msgid "Read the log message from file." -msgstr "Paket aus Datei lesen" +#~ msgid "Download the packages to the current directory" +#~ msgstr "Nie ins übergeordnete Verzeichnis wechseln" -#: share/completions/cvs.fish:151 -msgid "Log message." -msgstr "" +#, fuzzy +#~ msgid "Install the packages" +#~ msgstr "Neues Paket installieren" -#: share/completions/cvs.fish:152 -msgid "Commit to this branch or trunk revision." -msgstr "" +#, fuzzy +#~ msgid "Cancel any scheduled actions on the packages" +#~ msgstr "Zeigt Änderungsinformationen zu dem Paket an" -#: share/completions/cvs.fish:161 #, fuzzy -msgid "Specify keyword expansion mode." -msgstr "Kernel-Version angeben" +#~ msgid "Mark packages as automatically installed" +#~ msgstr "Paket aktualisieren, wenn es bereits installiert ist" -#: share/completions/cvs.fish:162 -msgid "Diff revision for date against working file." -msgstr "" +#, fuzzy +#~ msgid "Reinstall the packages" +#~ msgstr "Pakete erneut installieren" -#: share/completions/cvs.fish:163 -msgid "Diff rev1/date1 against date2." -msgstr "" +#, fuzzy +#~ msgid "Remove the packages" +#~ msgstr "Pakete entfernen" -#: share/completions/cvs.fish:164 -msgid "Diff revision for rev1 against working file." -msgstr "" +#, fuzzy +#~ msgid "Display detailed information about the packages" +#~ msgstr "Zeigt Änderungsinformationen zu dem Paket an" -#: share/completions/cvs.fish:165 -msgid "Diff rev1/date1 against rev2." -msgstr "" +#, fuzzy +#~ msgid "Mark packages as manually installed" +#~ msgstr "Paket aktualisieren, wenn es bereits installiert ist" -#: share/completions/cvs.fish:170 #, fuzzy -msgid "--ignore-matching-lines=RE Ignore changes whose lines all match RE." -msgstr "Änderungen ignorieren, deren Zeilen dem reg. Ausdruck entsprechen" +#~ msgid "Search for packages matching one of the patterns" +#~ msgstr "Paket entsprechend Muster suchen" -#: share/completions/cvs.fish:176 -msgid "--label LABEL Use LABEL instead of file name." -msgstr "" +#~ msgid "Class of hw type" +#~ msgstr "Klasse des Hardwaretyps" -#: share/completions/cvs.fish:178 -msgid "--show-function-line=RE Show the most recent line matching RE." -msgstr "" +#~ msgid "Show arp entries" +#~ msgstr "Arp-Einträge anzeigen" -#: share/completions/cvs.fish:184 -msgid "--width=NUM Output at most NUM (default 130) characters per line." -msgstr "" +#~ msgid "Remove an entry for hostname" +#~ msgstr "Eintrag für Hostname entfernen" -#: share/completions/cvs.fish:228 -msgid "Export tagged revisions." -msgstr "" +#~ msgid "Select interface" +#~ msgstr "Schnittstelle auswählen" -#: share/completions/cvs.fish:229 -msgid "Export revisions as of date." -msgstr "" +#~ msgid "Manually create ARP address" +#~ msgstr "ARP-Adresse manuell erzeugen" -#: share/completions/cvs.fish:230 -msgid "Export into dir instead of module name." -msgstr "" +#~ msgid "Take addr from filename, default /etc/ethers" +#~ msgstr "Adresse aus Dateiname entnehmen, Standard /etc/ethers" -#: share/completions/cvs.fish:231 -msgid "Use RCS kopt -k option on checkout." -msgstr "" +#~ msgid "Use specified queue" +#~ msgstr "Angegebene Warteschlange benutzen" -#: share/completions/cvs.fish:241 -msgid "Look for specified module (repeatable)" -msgstr "" +#~ msgid "Send mail to user" +#~ msgstr "Mail an Benutzer senden" -#: share/completions/cvs.fish:242 -#, fuzzy -msgid "Extract by record type" -msgstr "Skript extrahieren" +#~ msgid "Read job from file" +#~ msgstr "Job aus Datei lesen" -#: share/completions/cvs.fish:247 -#, fuzzy -msgid "Since date (Many formats)" -msgstr "Profildatenformat" - -#: share/completions/cvs.fish:248 -msgid "Back to record with str in module/file/repos field" -msgstr "" +#~ msgid "Alias for atq" +#~ msgstr "Alias für atq" -#: share/completions/cvs.fish:249 -msgid "Specified file (same as command line) (repeatable)" -msgstr "" +#~ msgid "Alias for atrm" +#~ msgstr "Alias für atrm" -#: share/completions/cvs.fish:250 -msgid "In module (repeatable)" -msgstr "" +#~ msgid "Show the time" +#~ msgstr "Zeige Zeit" -#: share/completions/cvs.fish:251 -msgid "In repository (repeatable)" -msgstr "" +#~ msgid "Print the jobs listed" +#~ msgstr "Aufgelistete Jobs ausgeben" -#: share/completions/cvs.fish:252 -msgid "Since rev or tag (looks inside RCS files!)" -msgstr "" +#~ msgid "Limiting load factor" +#~ msgstr "Auslastungsbegrenzung" -#: share/completions/cvs.fish:253 -msgid "Since tag record placed in history file (by anyone)." -msgstr "" +#~ msgid "Minimum interval in seconds" +#~ msgstr "Minimalintervall in Sekunden" -#: share/completions/cvs.fish:254 -msgid "For user name (repeatable)" -msgstr "" +#~ msgid "Debug mode" +#~ msgstr "Debug-Modus" -#: share/completions/cvs.fish:255 -msgid "Output for time zone (e.g. -z -0700)" -msgstr "" +#~ msgid "Process at queue only once" +#~ msgstr "at-Warteschlange nur einmal verarbeiten" -#: share/completions/darcs.fish:19 #, fuzzy -msgid "Display help about darcs and darcs commands" -msgstr "Hilfe- und Debug-Optionen anzeigen" +#~ msgid "Test if bundle has been given no subcommand" +#~ msgstr "Test, ob an apt noch ein Unterbefehl gegeben werden muss" -#: share/completions/darcs.fish:20 -msgid "Add one or more new files or directories" -msgstr "Ein/mehrere neue Datei/en oder Verzeichnis/se hinzufügen" - -#: share/completions/darcs.fish:21 #, fuzzy -msgid "Remove files from version control" -msgstr "Dateien nach Archivierung entfernen" +#~ msgid "Test if bundle has been given a specific subcommand" +#~ msgstr "Test, ob an apt noch ein Unterbefehl gegeben werden muss" -#: share/completions/darcs.fish:22 #, fuzzy -msgid "Move or rename files" -msgstr "Datei nicht erstellen" - -#: share/completions/darcs.fish:23 -msgid "Substitute one word for another" -msgstr "" +#~ msgid "Display a help page" +#~ msgstr "Handbuchseite anzeigen" -#: share/completions/darcs.fish:24 #, fuzzy -msgid "Discard unrecorded changes" -msgstr "Nicht aufgezeichnete Änderungen in der Arbeitskopie anzeigen" +#~ msgid "The location to install the gems in the bundle to" +#~ msgstr "Prozesskennung jedes Prozesses im Job anzeigen" -#: share/completions/darcs.fish:25 -msgid "Undo the last revert (may fail if changes after the revert)" -msgstr "" -"Letzte Rücknahme rückgängig machen (kann versagen, falls nach der Rücknahme " -"Änderungen vorgenommen wurden)" +#, fuzzy +#~ msgid "Installs the gems in the bundle to the system location" +#~ msgstr "Dateien in das Paketdepot übertragen" -#: share/completions/darcs.fish:26 #, fuzzy -msgid "List unrecorded changes in the working tree" -msgstr "Nicht aufgezeichnete Änderungen in der Arbeitskopie anzeigen" +#~ msgid "Do not print progress information to stdout" +#~ msgstr "Keine Gruppeninformation ausgeben" -#: share/completions/darcs.fish:27 #, fuzzy -msgid "Create a patch from unrecorded changes" -msgstr "Komprimierte Patche erstellen" +#~ msgid "Run bundle clean automatically after install" +#~ msgstr "Paket aktualisieren, wenn es bereits installiert ist" -#: share/completions/darcs.fish:28 -msgid "Remove recorded patches without changing the working copy" -msgstr "Aufgezeichnete Patche ohne Änderung der Arbeitskopie entfernen" +#, fuzzy +#~ msgid "Do not remove stale gems from the cache" +#~ msgstr "Alle gz-Dateien aus dem Zwischenspeicher entfernen" -#: share/completions/darcs.fish:29 #, fuzzy -msgid "Improve a patch before it leaves your repository" -msgstr "Einen Eintrag aus dem Paketdepot entfernen" +#~ msgid "Update dependencies to their latest versions" +#~ msgstr "Abhängigkeiten an makefile anhängen" -#: share/completions/darcs.fish:30 #, fuzzy -msgid "Mark unresolved conflicts in working tree, for manual resolution" -msgstr "Alle Konflikte in der Arbeitskopie für manuelle Resolution markieren" +#~ msgid "Specify the number of jobs to run in parallel" +#~ msgstr "Gibt die Anzahl zu sendender Bytes an" -#: share/completions/darcs.fish:31 -msgid "Name the current repository state for future reference" -msgstr "" +#, fuzzy +#~ msgid "Install the binstubs of the listed gem" +#~ msgstr "Namen aller Signale anzeigen" -#: share/completions/darcs.fish:32 #, fuzzy -msgid "Set a preference (test, predist, boringfile or binariesfile)" -msgstr "Wert für eine Einstellung (test, predist, ...) festlegen" +#~ msgid "Binstub destination directory (default bin)" +#~ msgstr "Dokumentationsdateien installieren (Standard)" -#: share/completions/darcs.fish:33 -msgid "Create a diff between two versions of the repository" -msgstr "Diff zwischen zwei Versionen des Paketdepots erstellen" +#, fuzzy +#~ msgid "Package .gem files into the vendor/cache directory" +#~ msgstr "Dateien in das Paketdepot übertragen" -#: share/completions/darcs.fish:34 #, fuzzy -msgid "List patches in the repository" -msgstr "Paketdepot aktualisieren" +#~ msgid "Specify and read configuration options for bundler" +#~ msgstr "Eine Konfigurationsdatei angeben" -#: share/completions/darcs.fish:35 -msgid "Display which patch last modified something" -msgstr "Anzeigen, welcher Patch zuletzt etwas veränderte" +#, fuzzy +#~ msgid "Show the source location of a particular gem in the bundle" +#~ msgstr "Prozesskennung jedes Prozesses im Job anzeigen" -#: share/completions/darcs.fish:36 -msgid "Create a distribution tarball" -msgstr "Distributions-tarball erstellen" +#, fuzzy +#~ msgid "Generate a simple Gemfile" +#~ msgstr "Masterdatei erstellen" -#: share/completions/darcs.fish:37 -msgid "Locate the most recent version lacking an error" -msgstr "Die aktuellste Version ohne Fehler suchen" +#, fuzzy +#~ msgid "Lock the Gemfile" +#~ msgstr "Log in Datei schreiben" -#: share/completions/darcs.fish:38 -msgid "Show information which is stored by darcs" -msgstr "" +#, fuzzy +#~ msgid "Check for newer pre-release gems" +#~ msgstr "Test auf Speicher-Lecks" -#: share/completions/darcs.fish:39 -msgid "Copy and apply patches from another repository to this one" -msgstr "Patches von einem anderen Paketdepot auf dieses kopieren und anwenden" +#, fuzzy +#~ msgid "Show each gem version" +#~ msgstr "Version des Quellenbaumes" -#: share/completions/darcs.fish:40 -msgid "Delete selected patches from the repository. (UNSAFE!)" -msgstr "" +#, fuzzy +#~ msgid "Generate a simple Gemfile, placed in the current directory" +#~ msgstr "Nie ins übergeordnete Verzeichnis wechseln" -#: share/completions/darcs.fish:41 -msgid "Record a new patch reversing some recorded changes" -msgstr "" +#, fuzzy +#~ msgid "Prints the license of all gems in the bundle" +#~ msgstr "Prozesskennung jedes Prozesses im Job anzeigen" -#: share/completions/darcs.fish:42 -msgid "Copy and apply patches from this repository to another one" -msgstr "Patches von diesem Paketdepot auf ein anderes kopieren und anwenden" +#~ msgid "Display help and exit" +#~ msgstr "Hilfe anzeigen und beenden" -#: share/completions/darcs.fish:43 -msgid "Send by email a bundle of one or more patches" -msgstr "Zusammenfassung eines oder mehrerer Patches per E-Mail versenden" +#~ msgid "Cache test results in specified file" +#~ msgstr "Testergebnisse in angegebener Datei zwischenspeichern" -#: share/completions/darcs.fish:44 -msgid "" -"Apply a patch bundle created by `darcs send\\\n" -"complete -c darcs -n __fish_use_subcommand -x -a get --description Create" -msgstr "" +#~ msgid "Backup suffix" +#~ msgstr "Endung für Sicherung" -#: share/completions/darcs.fish:71 share/completions/darcs.fish:220 -#: share/completions/darcs.fish:283 share/completions/darcs.fish:439 -#: share/completions/darcs.fish:597 share/completions/darcs.fish:632 -#: share/completions/darcs.fish:663 share/completions/darcs.fish:688 -#: share/completions/darcs.fish:801 share/completions/darcs.fish:959 -#: share/completions/darcs.fish:1010 share/completions/darcs.fish:1054 -#: share/completions/darcs.fish:1095 share/completions/darcs.fish:1122 -#: share/completions/darcs.fish:1155 -msgid "Specify command to run before this darcs command" -msgstr "" +#, fuzzy +#~ msgid "Output byte range" +#~ msgstr "Bytebereich ausgeben" -#: share/completions/darcs.fish:101 share/completions/darcs.fish:127 -#: share/completions/darcs.fish:156 share/completions/darcs.fish:186 -#: share/completions/darcs.fish:244 share/completions/darcs.fish:324 -#: share/completions/darcs.fish:363 share/completions/darcs.fish:406 -#: share/completions/darcs.fish:467 share/completions/darcs.fish:492 -#: share/completions/darcs.fish:840 share/completions/darcs.fish:1004 -#: share/completions/darcs.fish:1207 -msgid "Specify umask to use when writing" -msgstr "" +#~ msgid "Output character range" +#~ msgstr "Zeichenbereich ausgeben" -#: share/completions/darcs.fish:102 share/completions/darcs.fish:128 -#: share/completions/darcs.fish:157 share/completions/darcs.fish:187 -#: share/completions/darcs.fish:245 share/completions/darcs.fish:326 -#: share/completions/darcs.fish:364 share/completions/darcs.fish:408 -#: share/completions/darcs.fish:468 share/completions/darcs.fish:493 -#: share/completions/darcs.fish:537 share/completions/darcs.fish:753 -#: share/completions/darcs.fish:841 share/completions/darcs.fish:893 -#: share/completions/darcs.fish:1183 share/completions/darcs.fish:1208 -#: share/completions/darcs.fish:1239 -msgid "Specify command to run after this darcs command" -msgstr "" - -#: share/completions/darcs.fish:116 share/completions/darcs.fish:146 -#: share/completions/darcs.fish:203 share/completions/darcs.fish:234 -#: share/completions/darcs.fish:264 share/completions/darcs.fish:352 -#: share/completions/darcs.fish:456 share/completions/darcs.fish:482 -#: share/completions/darcs.fish:525 share/completions/darcs.fish:725 -#: share/completions/darcs.fish:779 share/completions/darcs.fish:829 -#: share/completions/darcs.fish:870 share/completions/darcs.fish:985 -#: share/completions/darcs.fish:1073 share/completions/darcs.fish:1197 -msgid "Specify the repository directory in which to run" -msgstr "Das Paketdepotverzeichnis angeben, in dem gearbeitet wird" +#~ msgid "Select field delimiter" +#~ msgstr "Feldbegrenzer auswählen" -#: share/completions/darcs.fish:171 -#, fuzzy -msgid "Define token to contain these characters" -msgstr "Multibytezeichen nicht trennen" +#~ msgid "Select fields" +#~ msgstr "Felder auswählen" -#: share/completions/darcs.fish:340 share/completions/darcs.fish:554 -#: share/completions/darcs.fish:767 #, fuzzy -msgid "Select changes starting with a patch matching PATTERN" -msgstr "Patches entsprechend dem MUSTER auswählen" - -#: share/completions/darcs.fish:341 share/completions/darcs.fish:555 -#: share/completions/darcs.fish:768 -#, fuzzy -msgid "Select changes starting with a patch matching REGEXP" -msgstr "Dem REGEXP entsprechende Patche auswählen" - -#: share/completions/darcs.fish:342 share/completions/darcs.fish:556 -#: share/completions/darcs.fish:769 -#, fuzzy -msgid "Select changes starting with a tag matching REGEXP" -msgstr "Dem REGEXP entsprechende Markierungen auswählen" - -#: share/completions/darcs.fish:343 share/completions/darcs.fish:557 -#: share/completions/darcs.fish:770 -#, fuzzy -msgid "Select the last NUMBER patches" -msgstr "Lesen nach NUM Treffern beenden" - -#: share/completions/darcs.fish:344 share/completions/darcs.fish:559 -#: share/completions/darcs.fish:771 share/completions/darcs.fish:855 -#: share/completions/darcs.fish:907 -msgid "Select patches matching PATTERN" -msgstr "Patches entsprechend dem MUSTER auswählen" - -#: share/completions/darcs.fish:345 share/completions/darcs.fish:560 -#: share/completions/darcs.fish:772 share/completions/darcs.fish:856 -#: share/completions/darcs.fish:908 -msgid "Select patches matching REGEXP" -msgstr "Dem REGEXP entsprechende Patche auswählen" - -#: share/completions/darcs.fish:346 share/completions/darcs.fish:561 -#: share/completions/darcs.fish:773 share/completions/darcs.fish:857 -#: share/completions/darcs.fish:909 -msgid "Select tags matching REGEXP" -msgstr "Dem REGEXP entsprechende Markierungen auswählen" +#~ msgid "Use \\tmpdir for temporary files." +#~ msgstr "tmpdir für temporäre Dateien benutzen" -#: share/completions/darcs.fish:378 #, fuzzy -msgid "Select a single patch matching PATTERN" -msgstr "Patches entsprechend dem MUSTER auswählen" +#~ msgid "Use \\editor for editing log information." +#~ msgstr "Editor zum Editieren der Loginformation verwenden" -#: share/completions/darcs.fish:379 #, fuzzy -msgid "Select a single patch matching REGEXP" -msgstr "Dem REGEXP entsprechende Patche auswählen" +#~ msgid "Request compression level \\# for net traffic." +#~ msgstr "Komprimierungsgrad für Netzverkehr" -#: share/completions/darcs.fish:380 #, fuzzy -msgid "Select one patch" -msgstr "Eine Aktion auswählen" +#~ msgid "Set CVS user variable." +#~ msgstr "CVS-Benutzervariable festlegen" -#: share/completions/darcs.fish:387 share/completions/darcs.fish:916 -msgid "Specify author id" -msgstr "Autorkennung angeben" +#~ msgid "Add a new file/directory to the repository" +#~ msgstr "Neue/s Datei/Verzeichnis zum Paketdepot hinzufügen" -#: share/completions/darcs.fish:388 -msgid "Name of patch" -msgstr "Name des Patch" +#~ msgid "Administration front end for rcs" +#~ msgstr "Administrationsoberfläche für rcs" -#: share/completions/darcs.fish:501 -msgid "Shell command that runs regression tests" -msgstr "" - -#: share/completions/darcs.fish:502 -msgid "" -"Shell command to run before `darcs dist\\\n" -"complete -c darcs -n contains" -msgstr "" - -#: share/completions/darcs.fish:551 share/completions/darcs.fish:1025 -#, fuzzy -msgid "Select changes up to a patch matching PATTERN" -msgstr "Patches entsprechend dem MUSTER auswählen" +#~ msgid "Show last revision where each line was modified" +#~ msgstr "Letzte Revision anzeigen, bei der jede Zeile verändert wurde" -#: share/completions/darcs.fish:552 share/completions/darcs.fish:1026 -#, fuzzy -msgid "Select changes up to a patch matching REGEXP" -msgstr "Dem REGEXP entsprechende Patche auswählen" +#~ msgid "Checkout sources for editing" +#~ msgstr "Quellen zum Editieren auschecken" -#: share/completions/darcs.fish:553 -#, fuzzy -msgid "Select changes up to a tag matching REGEXP" -msgstr "Dem REGEXP entsprechende Markierungen auswählen" +#~ msgid "Check files into the repository" +#~ msgstr "Dateien in das Paketdepot übertragen" -#: share/completions/darcs.fish:558 -#, fuzzy -msgid "Select a range of patches" -msgstr "Schnittstelle auswählen" +#~ msgid "Show differences between revisions" +#~ msgstr "Unterschiede zwischen Revisionen anzeigen" -#: share/completions/darcs.fish:562 -msgid "Return only NUMBER results" -msgstr "" +#~ msgid "Get ready to edit a watched file" +#~ msgstr "Vorbereitung zum Editieren einer beobachteten Datei" -#: share/completions/darcs.fish:713 share/completions/darcs.fish:980 -msgid "Use external tool to merge conflicts" -msgstr "Externes Programm zum Mischen der Konflikte nutzen" +#~ msgid "See who is editing a watched file" +#~ msgstr "Anzeigen, von wem eine beobachtete Datei editiert wird" -#: share/completions/darcs.fish:752 share/completions/darcs.fish:892 -#: share/completions/darcs.fish:1238 -msgid "Name of the darcs executable on the remote server" -msgstr "" +#~ msgid "Export sources from CVS, similar to checkout" +#~ msgstr "Quellen aus CVS exportieren, ähnelt checkout" -#: share/completions/darcs.fish:864 share/completions/darcs.fish:923 -msgid "Sign the patch with a given keyid" -msgstr "Den Patch mit einer angegebenen Schlüsselkennung signieren" +#~ msgid "Show repository access history" +#~ msgstr "Zugriffsverlauf des Paketdepots anzeigen" -#: share/completions/darcs.fish:865 share/completions/darcs.fish:924 -msgid "Sign the patch using openssl with a given private key" -msgstr "" -"Den Patch unter Benutzung von openssl mit einem privaten Schlüssel signieren" +#~ msgid "Import sources into CVS, using vendor branches" +#~ msgstr "Quellen in CVS importieren, verwende Herstellerzweige" -#: share/completions/darcs.fish:886 #, fuzzy -msgid "Specify the remote repository URL to work with" -msgstr "Das Paketdepotverzeichnis angeben, in dem gearbeitet wird" - -#: share/completions/darcs.fish:915 -msgid "Specify email address" -msgstr "E-Mail-Adresse angeben" +#~ msgid "Create a CVS repository if it doesn\\t" +#~ msgstr "CVS-Paketdepot erstellen, wenn es nicht existiert" -#: share/completions/darcs.fish:917 -msgid "Specify destination email" -msgstr "Ziel-E-Mail-Adresse angeben" - -#: share/completions/darcs.fish:918 #, fuzzy -msgid "Mail results to additional EMAIL(s)" -msgstr "Ergebnisse an zusätzliche EMAIL(s) senden. Erfordert --reply" +#~ msgid "Set keyword substitution mode:" +#~ msgstr "Befehlsersetzungsblock" -#: share/completions/darcs.fish:919 #, fuzzy -msgid "Specify mail subject" -msgstr "makefile angeben" +#~ msgid "Read the log message from file." +#~ msgstr "Paket aus Datei lesen" -#: share/completions/darcs.fish:920 #, fuzzy -msgid "Specify in-reply-to header" -msgstr "Indexverzeichnis angeben" - -#: share/completions/darcs.fish:921 -msgid "Specify output filename" -msgstr "Ausgabedateiname angeben" +#~ msgid "Specify keyword expansion mode." +#~ msgstr "Kernel-Version angeben" -#: share/completions/darcs.fish:995 -msgid "Reply to email-based patch using FROM address" -msgstr "Auf E-Mail-basierten Patch mittels FROM-Adresse antworten" +#, fuzzy +#~ msgid "--ignore-matching-lines=RE Ignore changes whose lines all match RE." +#~ msgstr "Änderungen ignorieren, deren Zeilen dem reg. Ausdruck entsprechen" -#: share/completions/darcs.fish:996 -msgid "Mail results to additional EMAIL(s). Requires --reply" -msgstr "Ergebnisse an zusätzliche EMAIL(s) senden. Erfordert --reply" +#, fuzzy +#~ msgid "Extract by record type" +#~ msgstr "Skript extrahieren" -#: share/completions/darcs.fish:1027 #, fuzzy -msgid "Select tag matching REGEXP" -msgstr "Dem REGEXP entsprechende Markierungen auswählen" +#~ msgid "Since date (Many formats)" +#~ msgstr "Profildatenformat" -#: share/completions/darcs.fish:1028 #, fuzzy -msgid "Version specified by the context in FILENAME" -msgstr "Kontext im DATEINAMEN abgespeichert senden" +#~ msgid "Display help about darcs and darcs commands" +#~ msgstr "Hilfe- und Debug-Optionen anzeigen" -#: share/completions/darcs.fish:1083 -msgid "Apply patch as another user using sudo" -msgstr "" +#~ msgid "Add one or more new files or directories" +#~ msgstr "Ein/mehrere neue Datei/en oder Verzeichnis/se hinzufügen" -#: share/completions/darcs.fish:1222 -msgid "--repodir=DIRECTORY" -msgstr "" +#, fuzzy +#~ msgid "Remove files from version control" +#~ msgstr "Dateien nach Archivierung entfernen" -#: share/completions/dcop.fish:34 #, fuzzy -msgid "Show help about options" -msgstr "Hilfe- und Debug-Optionen anzeigen" +#~ msgid "Move or rename files" +#~ msgstr "Datei nicht erstellen" -#: share/completions/dcop.fish:35 -msgid "Connect to the given user's DCOP server" -msgstr "" +#, fuzzy +#~ msgid "Discard unrecorded changes" +#~ msgstr "Nicht aufgezeichnete Änderungen in der Arbeitskopie anzeigen" -#: share/completions/dcop.fish:36 -msgid "Send the same DCOP call to all users with a running DCOP server" -msgstr "" +#~ msgid "Undo the last revert (may fail if changes after the revert)" +#~ msgstr "" +#~ "Letzte Rücknahme rückgängig machen (kann versagen, falls nach der " +#~ "Rücknahme Änderungen vorgenommen wurden)" -#: share/completions/dcop.fish:37 -msgid "List all active KDE session for a user or all users" -msgstr "" +#, fuzzy +#~ msgid "List unrecorded changes in the working tree" +#~ msgstr "Nicht aufgezeichnete Änderungen in der Arbeitskopie anzeigen" -#: share/completions/dcop.fish:38 -msgid "Send to the given KDE session" -msgstr "" +#, fuzzy +#~ msgid "Create a patch from unrecorded changes" +#~ msgstr "Komprimierte Patche erstellen" -#: share/completions/dcop.fish:39 -msgid "Don't update the user activity timestamp in the called application" -msgstr "" +#~ msgid "Remove recorded patches without changing the working copy" +#~ msgstr "Aufgezeichnete Patche ohne Änderung der Arbeitskopie entfernen" -#: share/completions/dcop.fish:40 #, fuzzy -msgid "Call DCOP for each line read from stdin" -msgstr "Lesen über Standardeingabe verhindern" +#~ msgid "Improve a patch before it leaves your repository" +#~ msgstr "Einen Eintrag aus dem Paketdepot entfernen" -#: share/completions/dd.fish:5 #, fuzzy -msgid "Complete dd operands" -msgstr "Vergleiche FILE1 mit allen Operanden" +#~ msgid "Mark unresolved conflicts in working tree, for manual resolution" +#~ msgstr "" +#~ "Alle Konflikte in der Arbeitskopie für manuelle Resolution markieren" -#: share/completions/df.fish:17 #, fuzzy -msgid "Show file systems of specified type" -msgstr "Dateisysteme des angegebenen Typs anzeigen" +#~ msgid "Set a preference (test, predist, boringfile or binariesfile)" +#~ msgstr "Wert für eine Einstellung (test, predist, ...) festlegen" -#: share/completions/df.fish:22 -msgid "Block size" -msgstr "Blockgrösse" +#~ msgid "Create a diff between two versions of the repository" +#~ msgstr "Diff zwischen zwei Versionen des Paketdepots erstellen" -#: share/completions/docker.fish:19 #, fuzzy -msgid "Show all containers" -msgstr "Arp-Einträge anzeigen" +#~ msgid "List patches in the repository" +#~ msgstr "Paketdepot aktualisieren" -#: share/completions/docker.fish:24 -#, fuzzy -msgid "Show the running containers" -msgstr "Versteckte Funktionen anzeigen" - -#: share/completions/docker.fish:28 -#, fuzzy -msgid "Show the exited containers" -msgstr "Zeige Zeit" +#~ msgid "Display which patch last modified something" +#~ msgstr "Anzeigen, welcher Patch zuletzt etwas veränderte" -#: share/completions/docker.fish:70 share/completions/docker.fish:92 -msgid "Docker container" -msgstr "" +#~ msgid "Create a distribution tarball" +#~ msgstr "Distributions-tarball erstellen" -#: share/completions/docker.fish:82 -msgid "Stopped container" -msgstr "" +#~ msgid "Locate the most recent version lacking an error" +#~ msgstr "Die aktuellste Version ohne Fehler suchen" -#: share/completions/docker.fish:87 -msgid "Container running" -msgstr "" +#~ msgid "Copy and apply patches from another repository to this one" +#~ msgstr "" +#~ "Patches von einem anderen Paketdepot auf dieses kopieren und anwenden" -#: share/completions/du.fish:15 -#, fuzzy -msgid "Exclude files that match pattern in file" -msgstr "Den Mustern in der Datei entsprechende Dateien ausschliessen" +#~ msgid "Copy and apply patches from this repository to another one" +#~ msgstr "Patches von diesem Paketdepot auf ein anderes kopieren und anwenden" -#: share/completions/du.fish:16 -msgid "Exclude files that match pattern" -msgstr "Dem Muster entsprechende Dateien ausschliessen" +#~ msgid "Send by email a bundle of one or more patches" +#~ msgstr "Zusammenfassung eines oder mehrerer Patches per E-Mail versenden" -#: share/completions/du.fish:17 -msgid "Recursion limit" -msgstr "Rekursionsgrenze" +#~ msgid "Specify the repository directory in which to run" +#~ msgstr "Das Paketdepotverzeichnis angeben, in dem gearbeitet wird" -#: share/completions/duply.fish:3 #, fuzzy -msgid "Profile" -msgstr "Datei" - -#: share/completions/duply.fish:4 -msgid "Get usage help text" -msgstr "" +#~ msgid "Define token to contain these characters" +#~ msgstr "Multibytezeichen nicht trennen" -#: share/completions/duply.fish:7 #, fuzzy -msgid "Creates a configuration profile" -msgstr "Konfigurationsdatei festlegen" +#~ msgid "Select changes starting with a patch matching PATTERN" +#~ msgstr "Patches entsprechend dem MUSTER auswählen" -#: share/completions/duply.fish:8 -msgid "Backup with pre/post script execution" -msgstr "" - -#: share/completions/duply.fish:9 #, fuzzy -msgid "Backup without executing pre/post scripts" -msgstr "Keine post-Skripte ausführen" +#~ msgid "Select changes starting with a patch matching REGEXP" +#~ msgstr "Dem REGEXP entsprechende Patche auswählen" -#: share/completions/duply.fish:10 #, fuzzy -msgid "Execute /pre script" -msgstr "Keine pre-Skripte ausführen" +#~ msgid "Select changes starting with a tag matching REGEXP" +#~ msgstr "Dem REGEXP entsprechende Markierungen auswählen" -#: share/completions/duply.fish:11 #, fuzzy -msgid "Execute /post script" -msgstr "Keine post-Skripte ausführen" +#~ msgid "Select the last NUMBER patches" +#~ msgstr "Lesen nach NUM Treffern beenden" -#: share/completions/duply.fish:12 -msgid "Force full backup" -msgstr "" +#~ msgid "Select patches matching PATTERN" +#~ msgstr "Patches entsprechend dem MUSTER auswählen" -#: share/completions/duply.fish:13 -msgid "Force incremental backup" -msgstr "" +#~ msgid "Select patches matching REGEXP" +#~ msgstr "Dem REGEXP entsprechende Patche auswählen" -#: share/completions/duply.fish:14 -msgid "List all files in backup (as it was at , default: now)" -msgstr "" +#~ msgid "Select tags matching REGEXP" +#~ msgstr "Dem REGEXP entsprechende Markierungen auswählen" -#: share/completions/duply.fish:15 -msgid "Prints backup sets and chains currently in repository" -msgstr "" +#, fuzzy +#~ msgid "Select a single patch matching PATTERN" +#~ msgstr "Patches entsprechend dem MUSTER auswählen" -#: share/completions/duply.fish:16 -msgid "List files changed since latest backup" -msgstr "" +#, fuzzy +#~ msgid "Select a single patch matching REGEXP" +#~ msgstr "Dem REGEXP entsprechende Patche auswählen" -#: share/completions/duply.fish:17 -msgid "Shows outdated backup archives [--force, delete these files]" -msgstr "" +#, fuzzy +#~ msgid "Select one patch" +#~ msgstr "Eine Aktion auswählen" -#: share/completions/duply.fish:18 -msgid "Shows outdated backups [--force, delete these files]" -msgstr "" +#~ msgid "Specify author id" +#~ msgstr "Autorkennung angeben" -#: share/completions/duply.fish:19 -msgid "Shows broken backup archives [--force, delete these files]" -msgstr "" +#~ msgid "Name of patch" +#~ msgstr "Name des Patch" -#: share/completions/duply.fish:20 -msgid "Restore the backup to [as it was at ]" -msgstr "" +#, fuzzy +#~ msgid "Select changes up to a patch matching PATTERN" +#~ msgstr "Patches entsprechend dem MUSTER auswählen" -#: share/completions/duply.fish:21 -msgid "Restore single file/folder from backup [as it was at ]" -msgstr "" +#, fuzzy +#~ msgid "Select changes up to a patch matching REGEXP" +#~ msgstr "Dem REGEXP entsprechende Patche auswählen" -#: share/completions/duply.fish:24 -msgid "Really execute the commands: purge, purge-full, cleanup" -msgstr "" +#, fuzzy +#~ msgid "Select changes up to a tag matching REGEXP" +#~ msgstr "Dem REGEXP entsprechende Markierungen auswählen" + +#, fuzzy +#~ msgid "Select a range of patches" +#~ msgstr "Schnittstelle auswählen" -#: share/completions/duply.fish:25 -msgid "Do nothing but print out generated duplicity command lines" -msgstr "" +#~ msgid "Use external tool to merge conflicts" +#~ msgstr "Externes Programm zum Mischen der Konflikte nutzen" -#: share/completions/duply.fish:26 -msgid "Calculate what would be done, but dont perform any actions" -msgstr "" +#~ msgid "Sign the patch with a given keyid" +#~ msgstr "Den Patch mit einer angegebenen Schlüsselkennung signieren" -#: share/completions/duply.fish:27 -msgid "Dont abort when backup different dirs to the same backend" -msgstr "" +#~ msgid "Sign the patch using openssl with a given private key" +#~ msgstr "" +#~ "Den Patch unter Benutzung von openssl mit einem privaten Schlüssel " +#~ "signieren" -#: share/completions/duply.fish:28 #, fuzzy -msgid "Output verbosity level" -msgstr "Ausführlichkeitswert auf 0 zurücksetzen" +#~ msgid "Specify the remote repository URL to work with" +#~ msgstr "Das Paketdepotverzeichnis angeben, in dem gearbeitet wird" -#: share/completions/emerge.fish:5 share/completions/equery.fish:5 -msgid "" -"Prints completions for installed packages on the system from /var/db/pkg" -msgstr "" +#~ msgid "Specify email address" +#~ msgstr "E-Mail-Adresse angeben" -#: share/completions/emerge.fish:13 share/completions/equery.fish:12 -msgid "" -"Prints completions for all available packages on the system from /usr/portage" -msgstr "" +#~ msgid "Specify destination email" +#~ msgstr "Ziel-E-Mail-Adresse angeben" -#: share/completions/emerge.fish:22 #, fuzzy -msgid "" -"Tests if emerge command should have an installed package as potential " -"completion" -msgstr "" -"Testen, ob der apt-Befehl Pakete zur möglichen Fertigstellung haben sollte" +#~ msgid "Mail results to additional EMAIL(s)" +#~ msgstr "Ergebnisse an zusätzliche EMAIL(s) senden. Erfordert --reply" -#: share/completions/emerge.fish:32 -msgid "" -"Print completions for all packages including the version compare if that is " -"already typed" -msgstr "" +#, fuzzy +#~ msgid "Specify mail subject" +#~ msgstr "makefile angeben" -#: share/completions/env.fish:2 #, fuzzy -msgid "Redefine variable" -msgstr "Variable löschen" +#~ msgid "Specify in-reply-to header" +#~ msgstr "Indexverzeichnis angeben" -#: share/completions/equery.fish:19 -msgid "" -"Prints completions for all available categories on the system from /usr/" -"portage" -msgstr "" +#~ msgid "Specify output filename" +#~ msgstr "Ausgabedateiname angeben" -#: share/completions/equery.fish:38 -#, fuzzy -msgid "list all packages owning file(s)" -msgstr "Pakete auflisten, die abhängen von " +#~ msgid "Reply to email-based patch using FROM address" +#~ msgstr "Auf E-Mail-basierten Patch mittels FROM-Adresse antworten" -#: share/completions/equery.fish:39 -msgid "check MD5sums and timestamps of package" -msgstr "" +#~ msgid "Mail results to additional EMAIL(s). Requires --reply" +#~ msgstr "Ergebnisse an zusätzliche EMAIL(s) senden. Erfordert --reply" -#: share/completions/equery.fish:40 #, fuzzy -msgid "list all packages depending on specified package" -msgstr "Pakete auflisten, die abhängen von " +#~ msgid "Select tag matching REGEXP" +#~ msgstr "Dem REGEXP entsprechende Markierungen auswählen" -#: share/completions/equery.fish:41 #, fuzzy -msgid "display a dependency tree for package" -msgstr "Abhängigkeiten für dieses Paket auflisten" +#~ msgid "Version specified by the context in FILENAME" +#~ msgstr "Kontext im DATEINAMEN abgespeichert senden" -#: share/completions/equery.fish:42 #, fuzzy -msgid "list files owned by package" -msgstr "Dateien im Paket auflisten" +#~ msgid "Show help about options" +#~ msgstr "Hilfe- und Debug-Optionen anzeigen" -#: share/completions/equery.fish:43 #, fuzzy -msgid "list all packages with specified useflag" -msgstr "Ein (deinstalliertes) Paket in der angegebenen Datei abfragen" +#~ msgid "Call DCOP for each line read from stdin" +#~ msgstr "Lesen über Standardeingabe verhindern" -#: share/completions/equery.fish:44 #, fuzzy -msgid "list all packages matching pattern" -msgstr "Inhalte eines Paketes auflisten, das dem Muster entspricht" +#~ msgid "Complete dd operands" +#~ msgstr "Vergleiche FILE1 mit allen Operanden" -#: share/completions/equery.fish:45 #, fuzzy -msgid "print size of files contained in package" -msgstr "Die im Paket enthaltenen Auslöser-Skripte anzeigen" +#~ msgid "Show file systems of specified type" +#~ msgstr "Dateisysteme des angegebenen Typs anzeigen" -#: share/completions/equery.fish:46 -#, fuzzy -msgid "display USE flags for package" -msgstr "Zeigt Änderungsinformationen zu dem Paket an" +#~ msgid "Block size" +#~ msgstr "Blockgrösse" -#: share/completions/equery.fish:47 #, fuzzy -msgid "print full path to ebuild for package" -msgstr "Vollständigen Quellpfad ausgeben" +#~ msgid "Show all containers" +#~ msgstr "Arp-Einträge anzeigen" -#: share/completions/fusermount.fish:15 share/completions/sshfs.fish:27 #, fuzzy -msgid "Mount options" -msgstr "Einhäng-Option" +#~ msgid "Show the running containers" +#~ msgstr "Versteckte Funktionen anzeigen" -#: share/completions/gcc.fish:25 #, fuzzy -msgid "Set maximum template depth" -msgstr "Maximale Mustertiefe auf %s festlegen" +#~ msgid "Show the exited containers" +#~ msgstr "Zeige Zeit" -#: share/completions/gcc.fish:31 share/completions/gcc.fish:513 -msgid "Use dir as the logical root directory for headers and libraries" -msgstr "" +#, fuzzy +#~ msgid "Exclude files that match pattern in file" +#~ msgstr "Den Mustern in der Datei entsprechende Dateien ausschliessen" -#: share/completions/gcc.fish:261 -msgid "" -"Print the full absolute name of the library file library that would be used " -"when linking---and don\\t" -msgstr "" +#~ msgid "Exclude files that match pattern" +#~ msgstr "Dem Muster entsprechende Dateien ausschliessen" -#: share/completions/gcc.fish:512 -msgid "" -"Process file after the compiler reads in the standard specs file, in order " -"to override the defaults that the gcc driver program uses when determining " -"what switches to pass to cc1, cc1plus, as, ld, etc" -msgstr "" +#~ msgid "Recursion limit" +#~ msgstr "Rekursionsgrenze" -#: share/completions/gcc.fish:539 share/completions/gcc.fish:540 -#: share/completions/gcc.fish:541 -msgid "" -"This specifies what floating point hardware (or hardware emulation) is " -"available on the target" -msgstr "" +#, fuzzy +#~ msgid "Profile" +#~ msgstr "Datei" -#: share/completions/gcc.fish:542 -msgid "" -"The size of all structures and unions will be rounded up to a multiple of " -"the number of bits set by this option" -msgstr "" +#, fuzzy +#~ msgid "Creates a configuration profile" +#~ msgstr "Konfigurationsdatei festlegen" -#: share/completions/gcc.fish:548 -msgid "Specify the register to be used for PIC addressing" -msgstr "" +#, fuzzy +#~ msgid "Backup without executing pre/post scripts" +#~ msgstr "Keine post-Skripte ausführen" -#: share/completions/gcc.fish:556 -msgid "Specify the access model for the thread local storage pointer" -msgstr "" +#, fuzzy +#~ msgid "Execute /pre script" +#~ msgstr "Keine pre-Skripte ausführen" -#: share/completions/gcc.fish:557 -msgid "Specify ATMEL AVR instruction set or MCU type" -msgstr "" +#, fuzzy +#~ msgid "Execute /post script" +#~ msgstr "Keine post-Skripte ausführen" -#: share/completions/gcc.fish:559 -msgid "" -"Specify the initial stack address, which may be a symbol or numeric value, " -"__stack is the default" -msgstr "" +#, fuzzy +#~ msgid "Output verbosity level" +#~ msgstr "Ausführlichkeitswert auf 0 zurücksetzen" -#: share/completions/gcc.fish:574 -msgid "" -"Specified the identification number of the ID based shared library being " -"compiled" -msgstr "" +#, fuzzy +#~ msgid "" +#~ "Tests if emerge command should have an installed package as potential " +#~ "completion" +#~ msgstr "" +#~ "Testen, ob der apt-Befehl Pakete zur möglichen Fertigstellung haben sollte" -#: share/completions/gem.fish:12 -msgid "Build a gem from a gemspec" -msgstr "" +#, fuzzy +#~ msgid "Redefine variable" +#~ msgstr "Variable löschen" -#: share/completions/gem.fish:13 -msgid "Adjust RubyGems certificate settings" -msgstr "" +#, fuzzy +#~ msgid "list all packages owning file(s)" +#~ msgstr "Pakete auflisten, die abhängen von " -#: share/completions/gem.fish:14 #, fuzzy -msgid "Check installed gems" -msgstr "Installierte Pakete abfragen" +#~ msgid "list all packages depending on specified package" +#~ msgstr "Pakete auflisten, die abhängen von " -#: share/completions/gem.fish:15 -msgid "Cleanup old versions of installed gems in the local repository" -msgstr "" +#, fuzzy +#~ msgid "display a dependency tree for package" +#~ msgstr "Abhängigkeiten für dieses Paket auflisten" -#: share/completions/gem.fish:16 #, fuzzy -msgid "Display the contents of the installed gems" -msgstr "Namen aller Signale anzeigen" +#~ msgid "list files owned by package" +#~ msgstr "Dateien im Paket auflisten" -#: share/completions/gem.fish:17 #, fuzzy -msgid "Show the dependencies of an installed gem" -msgstr "Vor dem Deinstallieren der Pakete keine Abhängigkeiten prüfen" +#~ msgid "list all packages with specified useflag" +#~ msgstr "Ein (deinstalliertes) Paket in der angegebenen Datei abfragen" -#: share/completions/gem.fish:18 -msgid "Display RubyGems environmental information" -msgstr "" +#, fuzzy +#~ msgid "list all packages matching pattern" +#~ msgstr "Inhalte eines Paketes auflisten, das dem Muster entspricht" -#: share/completions/gem.fish:19 #, fuzzy -msgid "Provide help on the 'gem' command" -msgstr "Hilfe für den Befehl '%s'" +#~ msgid "print size of files contained in package" +#~ msgstr "Die im Paket enthaltenen Auslöser-Skripte anzeigen" -#: share/completions/gem.fish:20 #, fuzzy -msgid "Install a gem into the local repository" -msgstr "Dateien in das Paketdepot übertragen" +#~ msgid "display USE flags for package" +#~ msgstr "Zeigt Änderungsinformationen zu dem Paket an" -#: share/completions/gem.fish:21 -msgid "Display all gems whose name starts with STRING" -msgstr "" +#, fuzzy +#~ msgid "print full path to ebuild for package" +#~ msgstr "Vollständigen Quellpfad ausgeben" -#: share/completions/gem.fish:22 #, fuzzy -msgid "Query gem information in local or remote repositories" -msgstr "Einträge in .cvspass für entferntes Paketdepot entfernen" +#~ msgid "Mount options" +#~ msgstr "Einhäng-Option" -#: share/completions/gem.fish:23 -msgid "Generates RDoc for pre-installed gems" -msgstr "" +#, fuzzy +#~ msgid "Set maximum template depth" +#~ msgstr "Maximale Mustertiefe auf %s festlegen" -#: share/completions/gem.fish:24 -msgid "Display all gems whose name contains STRING" -msgstr "" +#, fuzzy +#~ msgid "Check installed gems" +#~ msgstr "Installierte Pakete abfragen" -#: share/completions/gem.fish:25 #, fuzzy -msgid "Display gem specification (in yaml)" -msgstr "Letzte Veränderungszeit der Datei anzeigen" +#~ msgid "Display the contents of the installed gems" +#~ msgstr "Namen aller Signale anzeigen" -#: share/completions/gem.fish:26 #, fuzzy -msgid "Uninstall a gem from the local repository" -msgstr "Einen Eintrag aus dem Paketdepot entfernen" +#~ msgid "Show the dependencies of an installed gem" +#~ msgstr "Vor dem Deinstallieren der Pakete keine Abhängigkeiten prüfen" -#: share/completions/gem.fish:27 #, fuzzy -msgid "Unpack an installed gem to the current directory" -msgstr "Nie ins übergeordnete Verzeichnis wechseln" +#~ msgid "Provide help on the 'gem' command" +#~ msgstr "Hilfe für den Befehl '%s'" -#: share/completions/gem.fish:28 -msgid "Update the named gem (or all installed gems) in the local repository" -msgstr "" +#, fuzzy +#~ msgid "Install a gem into the local repository" +#~ msgstr "Dateien in das Paketdepot übertragen" -#: share/completions/gem.fish:35 -msgid "Use URL as the remote source for gems" -msgstr "" +#, fuzzy +#~ msgid "Query gem information in local or remote repositories" +#~ msgstr "Einträge in .cvspass für entferntes Paketdepot entfernen" -#: share/completions/gem.fish:36 -msgid "Use the given HTTP proxy for remote operations" -msgstr "" +#, fuzzy +#~ msgid "Display gem specification (in yaml)" +#~ msgstr "Letzte Veränderungszeit der Datei anzeigen" -#: share/completions/gem.fish:37 #, fuzzy -msgid "Use no HTTP proxy for remote operations" -msgstr "root-Verzeichnis für rpm-Operationen angeben" +#~ msgid "Uninstall a gem from the local repository" +#~ msgstr "Einen Eintrag aus dem Paketdepot entfernen" -#: share/completions/gem.fish:38 #, fuzzy -msgid "Get help on this command" -msgstr "Hilfe für den Befehl '%s'" +#~ msgid "Unpack an installed gem to the current directory" +#~ msgstr "Nie ins übergeordnete Verzeichnis wechseln" -#: share/completions/gem.fish:39 #, fuzzy -msgid "Set the verbose level of output" -msgstr "Ausführlichkeitswert auf 0 zurücksetzen" +#~ msgid "Use no HTTP proxy for remote operations" +#~ msgstr "root-Verzeichnis für rpm-Operationen angeben" -#: share/completions/gem.fish:40 #, fuzzy -msgid "Use this config file instead of default" -msgstr "Angegebene Datei anstelle der Standardvertrauensdatenbank nutzen" +#~ msgid "Get help on this command" +#~ msgstr "Hilfe für den Befehl '%s'" -#: share/completions/gem.fish:41 -msgid "Show stack backtrace on errors" -msgstr "" +#, fuzzy +#~ msgid "Set the verbose level of output" +#~ msgstr "Ausführlichkeitswert auf 0 zurücksetzen" -#: share/completions/gem.fish:42 #, fuzzy -msgid "Turn on Ruby debugging" -msgstr "Entfernung der Zusatzinformationen abschalten" +#~ msgid "Use this config file instead of default" +#~ msgstr "Angegebene Datei anstelle der Standardvertrauensdatenbank nutzen" -#: share/completions/gem.fish:47 -msgid "Add a trusted certificate" -msgstr "" +#, fuzzy +#~ msgid "Turn on Ruby debugging" +#~ msgstr "Entfernung der Zusatzinformationen abschalten" -#: share/completions/gem.fish:48 #, fuzzy -msgid "List trusted certificates" -msgstr "Vertraute Schlüssel auflisten" +#~ msgid "List trusted certificates" +#~ msgstr "Vertraute Schlüssel auflisten" -#: share/completions/gem.fish:49 -msgid "Remove trusted certificates containing STRING" -msgstr "" +#, fuzzy +#~ msgid "Report 'unmanaged' or rogue files in the gem repository" +#~ msgstr "Ein oder mehrere Dateien/Verzeichnisse aus dem Paketdepot entfernen" -#: share/completions/gem.fish:50 -msgid "Build private key and self-signed certificate for EMAIL_ADDR" -msgstr "" +#, fuzzy +#~ msgid "Specify version for which to run unit tests" +#~ msgstr "Das Paketdepotverzeichnis angeben, in dem gearbeitet wird" -#: share/completions/gem.fish:51 -msgid "Certificate for --sign command" -msgstr "" +#, fuzzy +#~ msgid "Don't really cleanup" +#~ msgstr "Nicht wirklich deinstallieren" -#: share/completions/gem.fish:52 -msgid "Private key for --sign command" -msgstr "" +#, fuzzy +#~ msgid "List the files inside a Gem" +#~ msgstr "Dateien im Paket auflisten" -#: share/completions/gem.fish:53 -msgid "Sign a certificate with my key and certificate" -msgstr "" +#, fuzzy +#~ msgid "Specify version for gem to view" +#~ msgstr "Ziel-E-Mail-Adresse angeben" -#: share/completions/gem.fish:58 -msgid "Verify gem file against its internal checksum" -msgstr "" +#, fuzzy +#~ msgid "Specify version of gem to uninstall" +#~ msgstr "Liste zu installierender Pakete" -#: share/completions/gem.fish:59 #, fuzzy -msgid "Report 'unmanaged' or rogue files in the gem repository" -msgstr "Ein oder mehrere Dateien/Verzeichnisse aus dem Paketdepot entfernen" +#~ msgid "Include reverse dependencies in the output" +#~ msgstr "Umgekehrte Abhängigkeiten für das Paket auflisten" -#: share/completions/gem.fish:60 -msgid "Run unit tests for gem" -msgstr "" +#, fuzzy +#~ msgid "Don't include reverse dependencies in the output" +#~ msgstr "Umgekehrte Abhängigkeiten für das Paket auflisten" -#: share/completions/gem.fish:61 #, fuzzy -msgid "Specify version for which to run unit tests" -msgstr "Das Paketdepotverzeichnis angeben, in dem gearbeitet wird" +#~ msgid "display the package version" +#~ msgstr "Paketsatz anzeigen" -#: share/completions/gem.fish:66 #, fuzzy -msgid "Don't really cleanup" -msgstr "Nicht wirklich deinstallieren" +#~ msgid "display path used to search for gems" +#~ msgstr "Zeige den für eine Nachricht benutzten Sitzungsschlüssel an" -#: share/completions/gem.fish:71 #, fuzzy -msgid "List the files inside a Gem" -msgstr "Dateien im Paket auflisten" +#~ msgid "display the gem format version" +#~ msgstr "Sektion für Dateiformate" -#: share/completions/gem.fish:72 #, fuzzy -msgid "Specify version for gem to view" -msgstr "Ziel-E-Mail-Adresse angeben" +#~ msgid "display the remote gem servers" +#~ msgstr "Datei zum Zugriff auf Server" -#: share/completions/gem.fish:73 -msgid "Search for gems under specific paths" -msgstr "" +#, fuzzy +#~ msgid "list all 'gem' commands" +#~ msgstr "Diesen Befehl deaktivieren" -#: share/completions/gem.fish:74 -msgid "Be verbose when showing status" -msgstr "" +#, fuzzy +#~ msgid "Specify version of gem to install" +#~ msgstr "Liste zu installierender Pakete" -#: share/completions/gem.fish:79 share/completions/gem.fish:172 #, fuzzy -msgid "Specify version of gem to uninstall" -msgstr "Liste zu installierender Pakete" +#~ msgid "Don't force gem to install, bypassing dependency checks" +#~ msgstr "Keine Abhängigkeiten prüfen" -#: share/completions/gem.fish:80 #, fuzzy -msgid "Include reverse dependencies in the output" -msgstr "Umgekehrte Abhängigkeiten für das Paket auflisten" +#~ msgid "Don't run unit tests prior to installation" +#~ msgstr "Vor der Installation nicht auf ausreichenden Plattenplatz prüfen" -#: share/completions/gem.fish:81 #, fuzzy -msgid "Don't include reverse dependencies in the output" -msgstr "Umgekehrte Abhängigkeiten für das Paket auflisten" +#~ msgid "Use bin wrappers for executables" +#~ msgstr "Datei ist ausführbar" -#: share/completions/gem.fish:82 -msgid "Pipe Format (name --version ver)" -msgstr "" +#, fuzzy +#~ msgid "Don't use bin wrappers for executables" +#~ msgstr "Skripte nicht ausführbar machen" -#: share/completions/gem.fish:87 #, fuzzy -msgid "display the package version" -msgstr "Paketsatz anzeigen" +#~ msgid "Specify gem trust policy" +#~ msgstr "Vertrauensmodell angeben" -#: share/completions/gem.fish:87 -msgid "display the path where gems are installed" -msgstr "" +#, fuzzy +#~ msgid "Display detailed information of gem(s)" +#~ msgstr "Zeigt Benutzungsinformation für den Befehl" -#: share/completions/gem.fish:87 #, fuzzy -msgid "display path used to search for gems" -msgstr "Zeige den für eine Nachricht benutzten Sitzungsschlüssel an" +#~ msgid "Don't display detailed information of gem(s)" +#~ msgstr "Zeigt Benutzungsinformation für den Befehl" -#: share/completions/gem.fish:87 #, fuzzy -msgid "display the gem format version" -msgstr "Sektion für Dateiformate" +#~ msgid "Specify version of gem to examine" +#~ msgstr "Ziel-E-Mail-Adresse angeben" -#: share/completions/gem.fish:87 #, fuzzy -msgid "display the remote gem servers" -msgstr "Datei zum Zugriff auf Server" +#~ msgid "Uninstall all matching versions" +#~ msgstr "Alle Versionen ausgeben" -#: share/completions/gem.fish:92 #, fuzzy -msgid "list all 'gem' commands" -msgstr "Diesen Befehl deaktivieren" +#~ msgid "Don't uninstall all matching versions" +#~ msgstr "Nicht wirklich deinstallieren" -#: share/completions/gem.fish:92 -msgid "show some examples of usage" -msgstr "" +#, fuzzy +#~ msgid "Don't ignore dependency requirements while uninstalling" +#~ msgstr "Vor dem Deinstallieren der Pakete keine Abhängigkeiten prüfen" -#: share/completions/gem.fish:97 #, fuzzy -msgid "Specify version of gem to install" -msgstr "Liste zu installierender Pakete" +#~ msgid "name" +#~ msgstr "Benutzername" -#: share/completions/gem.fish:98 share/completions/gem.fish:121 -#: share/completions/gem.fish:131 share/completions/gem.fish:150 -#: share/completions/gem.fish:158 -msgid "Restrict operations to the LOCAL domain (default)" -msgstr "" +#, fuzzy +#~ msgid "Tag" +#~ msgstr "Ziel" -#: share/completions/gem.fish:99 share/completions/gem.fish:122 -#: share/completions/gem.fish:132 share/completions/gem.fish:151 -#: share/completions/gem.fish:159 -msgid "Restrict operations to the REMOTE domain" -msgstr "" +#~ msgid "Write output to specified file" +#~ msgstr "Schreibe Ausgabe in die angegebene Datei" -#: share/completions/gem.fish:100 share/completions/gem.fish:123 -#: share/completions/gem.fish:133 share/completions/gem.fish:152 -#: share/completions/gem.fish:160 -msgid "Allow LOCAL and REMOTE operations" -msgstr "" +#~ msgid "Use specified keyserver" +#~ msgstr "Angegebenen Schlüsselserver verwenden" -#: share/completions/gem.fish:101 share/completions/gem.fish:182 -msgid "Gem repository directory to get installed gems" -msgstr "" +#~ msgid "The command line that should be run to view a photo ID" +#~ msgstr "" +#~ "Befehlszeile, die zum Betrachten einer Fotokennung benutzt werden soll" -#: share/completions/gem.fish:102 share/completions/gem.fish:183 -msgid "Generate RDoc documentation for the gem on install" -msgstr "" +#~ msgid "" +#~ "Sets a list of directories to search for photo viewers and keyserver " +#~ "helpers" +#~ msgstr "" +#~ "Legt eine Liste von Verzeichnissen fest, die nach Bildbetrachtern und " +#~ "Schlüsselserver-Hilfsprogrammen durchsucht werden" -#: share/completions/gem.fish:103 share/completions/gem.fish:184 -msgid "Don't generate RDoc documentation for the gem on install" -msgstr "" +#~ msgid "Add specified file to the current list of keyrings" +#~ msgstr "Angegebene Datei zur aktuellen Schlüsselringliste hinzufügen" -#: share/completions/gem.fish:104 share/completions/gem.fish:185 -msgid "Generate RI documentation for the gem on install" -msgstr "" +#~ msgid "Add specified file to the current list of secret keyrings" +#~ msgstr "" +#~ "Angegebene Datei zur aktuellen Liste geheimer Schlüsselringe hinzufügen" -#: share/completions/gem.fish:105 share/completions/gem.fish:186 -msgid "Don't generate RI documentation for the gem on install" -msgstr "" +#~ msgid "Designate specified file as the primary public keyring" +#~ msgstr "Angegebene Datei als primären öffentlichen Schlüsselring bestimmen" -#: share/completions/gem.fish:106 share/completions/gem.fish:187 -msgid "Force gem to install, bypassing dependency checks" -msgstr "" +#~ msgid "Use specified file instead of the default trustdb" +#~ msgstr "Angegebene Datei anstelle der Standardvertrauensdatenbank nutzen" -#: share/completions/gem.fish:107 share/completions/gem.fish:188 -#, fuzzy -msgid "Don't force gem to install, bypassing dependency checks" -msgstr "Keine Abhängigkeiten prüfen" +#~ msgid "" +#~ "Read options from specified file, do not read the default options file" +#~ msgstr "" +#~ "Optionen aus angegebener Datei lesen, Standardoptionsdatei nicht lesen" -#: share/completions/gem.fish:108 share/completions/gem.fish:189 -msgid "Run unit tests prior to installation" -msgstr "" +#~ msgid "Load an extension module" +#~ msgstr "Erweiterungsmodul laden" -#: share/completions/gem.fish:109 share/completions/gem.fish:190 -#, fuzzy -msgid "Don't run unit tests prior to installation" -msgstr "Vor der Installation nicht auf ausreichenden Plattenplatz prüfen" +#~ msgid "Write special status strings to the specified file descriptor" +#~ msgstr "" +#~ "Spezielle Statusmeldungen auf den angegebenen Dateideskriptor schreiben" -#: share/completions/gem.fish:110 share/completions/gem.fish:191 -#, fuzzy -msgid "Use bin wrappers for executables" -msgstr "Datei ist ausführbar" +#~ msgid "Write log output to the specified file descriptor" +#~ msgstr "Protokollausgabe auf angegebenen Dateideskriptor schreiben" -#: share/completions/gem.fish:111 share/completions/gem.fish:192 -#, fuzzy -msgid "Don't use bin wrappers for executables" -msgstr "Skripte nicht ausführbar machen" +#~ msgid "Use specified string as comment string" +#~ msgstr "Angegebene Zeichenkette als Kommentar verwenden" -#: share/completions/gem.fish:112 share/completions/gem.fish:193 -#, fuzzy -msgid "Specify gem trust policy" -msgstr "Vertrauensmodell angeben" +#~ msgid "" +#~ "Put the specified name value pair into the signature as notation data" +#~ msgstr "" +#~ "Das angegebene Wertepaar als Notationsdaten in die Signatur einfügen" -#: share/completions/gem.fish:113 share/completions/gem.fish:194 -msgid "Do not install any required dependent gems" -msgstr "" +#~ msgid "Set signature policy" +#~ msgstr "Signaturregeln festlegen" -#: share/completions/gem.fish:114 share/completions/gem.fish:195 -msgid "Unconditionally install the required dependent gems" -msgstr "" +#~ msgid "Set certificate policy" +#~ msgstr "Zertifikatsregeln festlegen" -#: share/completions/gem.fish:119 share/completions/gem.fish:129 -#: share/completions/gem.fish:148 -#, fuzzy -msgid "Display detailed information of gem(s)" -msgstr "Zeigt Benutzungsinformation für den Befehl" +#~ msgid "Set signature and certificate policy" +#~ msgstr "Signatur- und Zertifikatsregeln festlegen" -#: share/completions/gem.fish:120 share/completions/gem.fish:130 -#: share/completions/gem.fish:149 -#, fuzzy -msgid "Don't display detailed information of gem(s)" -msgstr "Zeigt Benutzungsinformation für den Befehl" +#~ msgid "Use specified URL as a preferred keyserver for data signatures" +#~ msgstr "" +#~ "Angegebene URL als bevorzugten Schlüsselserver für Datensignaturen " +#~ "benutzen" -#: share/completions/gem.fish:128 -msgid "Name of gem(s) to query on matches the provided REGEXP" -msgstr "" +#~ msgid "Use specified string as the filename which is stored inside messages" +#~ msgstr "" +#~ "Angegebene Zeichenkette als in den Nachrichten gespeicherten Dateinamen " +#~ "verwenden" -#: share/completions/gem.fish:138 -msgid "Generate RDoc/RI documentation for all installed gems" -msgstr "" +#~ msgid "" +#~ "Number of completely trusted users to introduce a new key signer " +#~ "(defaults to 1)" +#~ msgstr "" +#~ "Anzahl der vollständig vertrauenswürdigen Benutzer, um einen neuen " +#~ "Schlüsselunterzeichner einzuführen (Standard ist 1)" -#: share/completions/gem.fish:139 -msgid "Include RDoc generated documents" -msgstr "" +#~ msgid "" +#~ "Number of marginally trusted users to introduce a new key signer " +#~ "(defaults to 3)" +#~ msgstr "" +#~ "Anzahl der beschränkt vertrauenswürdigen Benutzer, um einen neuen " +#~ "Schlüsselunterzeichner einzuführen (Standard ist 3)" -#: share/completions/gem.fish:140 -msgid "Don't include RDoc generated documents" -msgstr "" +#~ msgid "Maximum depth of a certification chain (default is 5)" +#~ msgstr "Maximale Tiefe einer Zertifizierungskette (Standard 5)" -#: share/completions/gem.fish:141 -msgid "Include RI generated documents" -msgstr "" +#~ msgid "Read passphrase from specified file descriptor" +#~ msgstr "Passwortsatz aus dem angegebenen Dateideskriptor lesen" -#: share/completions/gem.fish:142 -msgid "Don't include RI generated documents" -msgstr "" +#~ msgid "Read user input from specified file descriptor" +#~ msgstr "Benutzereingaben aus dem angegebenen Dateideskriptor lesen" -#: share/completions/gem.fish:143 -msgid "Specify version of gem to rdoc" -msgstr "" +#~ msgid "Override value of GPG_AGENT_INFO environment variable" +#~ msgstr "Wert der GPG_AGENT_INFO-Umgebungsvariablen überschreiben" -#: share/completions/gem.fish:157 -#, fuzzy -msgid "Specify version of gem to examine" -msgstr "Ziel-E-Mail-Adresse angeben" +#~ msgid "Don't use the public key but the specified session key" +#~ msgstr "" +#~ "Nicht den öffentlichen Schlüssel, sondern den angegebenen " +#~ "Sitzungsschlüssel benutzen" -#: share/completions/gem.fish:161 -msgid "Output specifications for all versions of the gem" -msgstr "" +#~ msgid "Sets up a named group, which is similar to aliases in email programs" +#~ msgstr "" +#~ "Richtet eine benannte Gruppe ein, die Aliasnamen in E-Mail-Programmen " +#~ "entspricht" -#: share/completions/gem.fish:166 -#, fuzzy -msgid "Uninstall all matching versions" -msgstr "Alle Versionen ausgeben" +#~ msgid "Set the list of personal cipher preferences to the specified string" +#~ msgstr "" +#~ "Die Liste der persönlichen Verschlüsselungseinstellungen gemäß der " +#~ "angegebenen Zeichenkette festlegen" -#: share/completions/gem.fish:167 -#, fuzzy -msgid "Don't uninstall all matching versions" -msgstr "Nicht wirklich deinstallieren" +#~ msgid "Set the list of personal digest preferences to the specified string" +#~ msgstr "" +#~ "Die Liste der persönlichen Übersichtseinstellungen gemäß der angegebenen " +#~ "Zeichenkette festlegen" -#: share/completions/gem.fish:168 -msgid "Ignore dependency requirements while uninstalling" -msgstr "" +#~ msgid "" +#~ "Set the list of personal compression preferences to the specified string" +#~ msgstr "" +#~ "Die Liste der persönlichen Komprimierungseinstellungen gemäß der " +#~ "angegebenen Zeichenkette festlegen" -#: share/completions/gem.fish:169 -#, fuzzy -msgid "Don't ignore dependency requirements while uninstalling" -msgstr "Vor dem Deinstallieren der Pakete keine Abhängigkeiten prüfen" +#~ msgid "Set the list of default preferences to the specified string" +#~ msgstr "" +#~ "Die Liste der Standardeinstellungen gemäß der angegebenen Zeichenkette " +#~ "festlegen" -#: share/completions/gem.fish:170 -msgid "Uninstall applicable executables without confirmation" -msgstr "" +#~ msgid "Delete arcs from callgraph" +#~ msgstr "Bögen aus Aufrufgraph löschen" -#: share/completions/gem.fish:171 -msgid "Don't uninstall applicable executables without confirmation" -msgstr "" +#~ msgid "Supress output when executed less than specified times" +#~ msgstr "Ausgabe unterdrücken, wenn weniger als angegeben ausgeführt" -#: share/completions/gem.fish:177 -msgid "Specify version of gem to unpack" -msgstr "" +#~ msgid "Profile data format" +#~ msgstr "Profildatenformat" -#: share/completions/gem.fish:196 -msgid "Update the RubyGems system software" -msgstr "" +#~ msgid "Suffix" +#~ msgstr "Suffix" -#: share/completions/git.fish:98 #, fuzzy -msgid "name" -msgstr "Benutzername" - -#: share/completions/git.fish:153 share/completions/git.fish:176 -msgid "Branch" -msgstr "" +#~ msgid "Help for this command" +#~ msgstr "Hilfe für den Befehl '%s'" -#: share/completions/git.fish:177 -#, fuzzy -msgid "Tag" -msgstr "Ziel" +#~ msgid "Help on how tab-completion works" +#~ msgstr "Hilfe zur Tab-Vervollständigung" -#: share/completions/gpg.fish:116 -msgid "Write output to specified file" -msgstr "Schreibe Ausgabe in die angegebene Datei" +#~ msgid "Help on how job control works" +#~ msgstr "Hilfe zur Jobsteuerung" -#: share/completions/gpg.fish:161 -msgid "Use specified keyserver" -msgstr "Angegebenen Schlüsselserver verwenden" +#~ msgid "Summary on how fish differs from other shells" +#~ msgstr "Zusammenfassung der Unterschiede zwischen fish und anderen shells" -#: share/completions/gpg.fish:169 -msgid "The command line that should be run to view a photo ID" -msgstr "Befehlszeile, die zum Betrachten einer Fotokennung benutzt werden soll" +#~ msgid "Help on how to set the prompt" +#~ msgstr "Hilfe zum Festlegen des Prompts" -#: share/completions/gpg.fish:170 -msgid "" -"Sets a list of directories to search for photo viewers and keyserver helpers" -msgstr "" -"Legt eine Liste von Verzeichnissen fest, die nach Bildbetrachtern und " -"Schlüsselserver-Hilfsprogrammen durchsucht werden" +#~ msgid "Help on how to set the titlebar message" +#~ msgstr "Hilfe zum Einrichten der Titelzeilen-Nachricht" -#: share/completions/gpg.fish:173 -msgid "Add specified file to the current list of keyrings" -msgstr "Angegebene Datei zur aktuellen Schlüsselringliste hinzufügen" +#~ msgid "Help on how to copy and paste" +#~ msgstr "Hilfe zum Kopieren und Einfügen" -#: share/completions/gpg.fish:175 -msgid "Add specified file to the current list of secret keyrings" -msgstr "" -"Angegebene Datei zur aktuellen Liste geheimer Schlüsselringe hinzufügen" +#~ msgid "Help on editor shortcuts" +#~ msgstr "Hilfe zu Editor-Tastenkürzeln" -#: share/completions/gpg.fish:176 -msgid "Designate specified file as the primary public keyring" -msgstr "Angegebene Datei als primären öffentlichen Schlüsselring bestimmen" - -#: share/completions/gpg.fish:178 -msgid "Use specified file instead of the default trustdb" -msgstr "Angegebene Datei anstelle der Standardvertrauensdatenbank nutzen" - -#: share/completions/gpg.fish:184 -msgid "Read options from specified file, do not read the default options file" -msgstr "Optionen aus angegebener Datei lesen, Standardoptionsdatei nicht lesen" - -#: share/completions/gpg.fish:186 -msgid "Load an extension module" -msgstr "Erweiterungsmodul laden" - -#: share/completions/gpg.fish:188 -msgid "Write special status strings to the specified file descriptor" -msgstr "" -"Spezielle Statusmeldungen auf den angegebenen Dateideskriptor schreiben" - -#: share/completions/gpg.fish:189 -msgid "Write log output to the specified file descriptor" -msgstr "Protokollausgabe auf angegebenen Dateideskriptor schreiben" - -#: share/completions/gpg.fish:195 -msgid "Use specified string as comment string" -msgstr "Angegebene Zeichenkette als Kommentar verwenden" - -#: share/completions/gpg.fish:204 -msgid "Put the specified name value pair into the signature as notation data" -msgstr "Das angegebene Wertepaar als Notationsdaten in die Signatur einfügen" - -#: share/completions/gpg.fish:205 -msgid "Set signature policy" -msgstr "Signaturregeln festlegen" - -#: share/completions/gpg.fish:206 -msgid "Set certificate policy" -msgstr "Zertifikatsregeln festlegen" - -#: share/completions/gpg.fish:207 -msgid "Set signature and certificate policy" -msgstr "Signatur- und Zertifikatsregeln festlegen" - -#: share/completions/gpg.fish:208 -msgid "Use specified URL as a preferred keyserver for data signatures" -msgstr "" -"Angegebene URL als bevorzugten Schlüsselserver für Datensignaturen benutzen" - -#: share/completions/gpg.fish:210 -msgid "Use specified string as the filename which is stored inside messages" -msgstr "" -"Angegebene Zeichenkette als in den Nachrichten gespeicherten Dateinamen " -"verwenden" - -#: share/completions/gpg.fish:218 -msgid "" -"Number of completely trusted users to introduce a new key signer (defaults " -"to 1)" -msgstr "" -"Anzahl der vollständig vertrauenswürdigen Benutzer, um einen neuen " -"Schlüsselunterzeichner einzuführen (Standard ist 1)" - -#: share/completions/gpg.fish:219 -msgid "" -"Number of marginally trusted users to introduce a new key signer (defaults " -"to 3)" -msgstr "" -"Anzahl der beschränkt vertrauenswürdigen Benutzer, um einen neuen " -"Schlüsselunterzeichner einzuführen (Standard ist 3)" - -#: share/completions/gpg.fish:221 -msgid "Maximum depth of a certification chain (default is 5)" -msgstr "Maximale Tiefe einer Zertifizierungskette (Standard 5)" - -#: share/completions/gpg.fish:249 -msgid "Read passphrase from specified file descriptor" -msgstr "Passwortsatz aus dem angegebenen Dateideskriptor lesen" - -#: share/completions/gpg.fish:250 -msgid "Read user input from specified file descriptor" -msgstr "Benutzereingaben aus dem angegebenen Dateideskriptor lesen" - -#: share/completions/gpg.fish:254 -msgid "Override value of GPG_AGENT_INFO environment variable" -msgstr "Wert der GPG_AGENT_INFO-Umgebungsvariablen überschreiben" - -#: share/completions/gpg.fish:304 -msgid "Don't use the public key but the specified session key" -msgstr "" -"Nicht den öffentlichen Schlüssel, sondern den angegebenen Sitzungsschlüssel " -"benutzen" - -#: share/completions/gpg.fish:315 -msgid "Sets up a named group, which is similar to aliases in email programs" -msgstr "" -"Richtet eine benannte Gruppe ein, die Aliasnamen in E-Mail-Programmen " -"entspricht" - -#: share/completions/gpg.fish:321 -msgid "Set the list of personal cipher preferences to the specified string" -msgstr "" -"Die Liste der persönlichen Verschlüsselungseinstellungen gemäß der " -"angegebenen Zeichenkette festlegen" - -#: share/completions/gpg.fish:322 -msgid "Set the list of personal digest preferences to the specified string" -msgstr "" -"Die Liste der persönlichen Übersichtseinstellungen gemäß der angegebenen " -"Zeichenkette festlegen" - -#: share/completions/gpg.fish:323 -msgid "" -"Set the list of personal compression preferences to the specified string" -msgstr "" -"Die Liste der persönlichen Komprimierungseinstellungen gemäß der angegebenen " -"Zeichenkette festlegen" - -#: share/completions/gpg.fish:324 -msgid "Set the list of default preferences to the specified string" -msgstr "" -"Die Liste der Standardeinstellungen gemäß der angegebenen Zeichenkette " -"festlegen" - -#: share/completions/gprof.fish:24 -msgid "Delete arcs from callgraph" -msgstr "Bögen aus Aufrufgraph löschen" - -#: share/completions/gprof.fish:26 -msgid "Supress output when executed less than specified times" -msgstr "Ausgabe unterdrücken, wenn weniger als angegeben ausgeführt" - -#: share/completions/gprof.fish:33 -msgid "Profile data format" -msgstr "Profildatenformat" - -#: share/completions/gunzip.fish:15 share/completions/gzip.fish:17 -msgid "Suffix" -msgstr "Suffix" - -#: share/completions/help.fish:6 -#, fuzzy -msgid "Help for this command" -msgstr "Hilfe für den Befehl '%s'" - -#: share/completions/help.fish:9 -msgid "Introduction to the fish syntax" -msgstr "" - -#: share/completions/help.fish:10 -msgid "Incomplete aspects of fish" -msgstr "" - -#: share/completions/help.fish:11 -msgid "Known fish bugs" -msgstr "" - -#: share/completions/help.fish:12 -msgid "Help on how to reuse previously entered commands" -msgstr "" - -#: share/completions/help.fish:14 -msgid "Help on how tab-completion works" -msgstr "Hilfe zur Tab-Vervollständigung" - -#: share/completions/help.fish:15 -msgid "Help on how job control works" -msgstr "Hilfe zur Jobsteuerung" - -#: share/completions/help.fish:16 -msgid "Summary on how fish differs from other shells" -msgstr "Zusammenfassung der Unterschiede zwischen fish und anderen shells" - -#: share/completions/help.fish:18 -msgid "Help on how to set the prompt" -msgstr "Hilfe zum Festlegen des Prompts" - -#: share/completions/help.fish:19 -msgid "Help on how to set the titlebar message" -msgstr "Hilfe zum Einrichten der Titelzeilen-Nachricht" - -#: share/completions/help.fish:20 -msgid "Help on how to copy and paste" -msgstr "Hilfe zum Kopieren und Einfügen" - -#: share/completions/help.fish:21 -msgid "Help on editor shortcuts" -msgstr "Hilfe zu Editor-Tastenkürzeln" - -#: share/completions/help.fish:22 -msgid "Help on environment variables" -msgstr "Hilfe zu Umgebungsvariablen" +#~ msgid "Help on environment variables" +#~ msgstr "Hilfe zu Umgebungsvariablen" -#: share/completions/help.fish:23 -msgid "Help on setting syntax highlighting colors" -msgstr "Hilfe zur Farbeinrichtung zur Syntaxhervorhebung" +#~ msgid "Help on setting syntax highlighting colors" +#~ msgstr "Hilfe zur Farbeinrichtung zur Syntaxhervorhebung" -#: share/completions/help.fish:25 share/completions/help.fish:26 -msgid "Help on parameter expansion (Globbing)" -msgstr "Hilfe zur Parameter-Expansion (Dateinamen)" +#~ msgid "Help on parameter expansion (Globbing)" +#~ msgstr "Hilfe zur Parameter-Expansion (Dateinamen)" -#: share/completions/help.fish:27 -#, sh-format -msgid "Help on variable expansion $VARNAME" -msgstr "Hilfe zur Variablen-Expansion $VARNAME" +#~ msgid "Help on variable expansion $VARNAME" +#~ msgstr "Hilfe zur Variablen-Expansion $VARNAME" -#: share/completions/help.fish:28 -msgid "Help on home directory expansion ~USER" -msgstr "Hilfe zur Startverzeichnis-Expansion ~USER" +#~ msgid "Help on home directory expansion ~USER" +#~ msgstr "Hilfe zur Startverzeichnis-Expansion ~USER" -#: share/completions/help.fish:29 -msgid "Help on brace expansion {a,b,c}" -msgstr "Hilfe zur Klammer-Expansion {a,b,c}" +#~ msgid "Help on brace expansion {a,b,c}" +#~ msgstr "Hilfe zur Klammer-Expansion {a,b,c}" -#: share/completions/help.fish:30 -msgid "Help on wildcard expansion *.*" -msgstr "Hilfe zur Muster-Expansion *.*" +#~ msgid "Help on wildcard expansion *.*" +#~ msgstr "Hilfe zur Muster-Expansion *.*" -#: share/completions/help.fish:31 #, fuzzy -msgid "Help on command substitution (SUBCOMMAND)" -msgstr "Hilfe zu Befehlsersetzungen (SUBCOMMAND)" +#~ msgid "Help on command substitution (SUBCOMMAND)" +#~ msgstr "Hilfe zu Befehlsersetzungen (SUBCOMMAND)" -#: share/completions/help.fish:32 -msgid "Help on process expansion %JOB" -msgstr "Hilfe zur Prozess-Expansion %JOB" +#~ msgid "Help on process expansion %JOB" +#~ msgstr "Hilfe zur Prozess-Expansion %JOB" -#: share/completions/history.fish:1 -msgid "Match history items that start with the given prefix" -msgstr "" +#~ msgid "Stop interface" +#~ msgstr "Schnittstelle stoppen" -#: share/completions/history.fish:2 -msgid "Match history items that contain the given string" -msgstr "" +#~ msgid "Start interface" +#~ msgstr "Schnittstelle starten" -#: share/completions/ifconfig.fish:1 -msgid "Stop interface" -msgstr "Schnittstelle stoppen" +#~ msgid "Network interface" +#~ msgstr "Netzwerkschnittstelle" -#: share/completions/ifconfig.fish:2 -msgid "Start interface" -msgstr "Schnittstelle starten" - -#: share/completions/ifconfig.fish:25 share/completions/ifdown.fish:1 -#: share/completions/ifup.fish:1 -msgid "Network interface" -msgstr "Netzwerkschnittstelle" - -#: share/completions/kitchen.fish:3 #, fuzzy -msgid "Test if kitchen has yet to be given the main command" -msgstr "Test, ob an apt noch ein Unterbefehl gegeben werden muss" - -#: share/completions/less.fish:3 -msgid "Buffer space" -msgstr "Pufferplatz" - -#: share/completions/lsusb.fish:2 -msgid "Show only devices with specified device and/or bus numbers (in decimal)" -msgstr "" +#~ msgid "Test if kitchen has yet to be given the main command" +#~ msgstr "Test, ob an apt noch ein Unterbefehl gegeben werden muss" -#: share/completions/make.fish:12 -msgid "Target" -msgstr "Ziel" +#~ msgid "Buffer space" +#~ msgstr "Pufferplatz" -#: share/completions/make.fish:13 -msgid "Use file as makefile" -msgstr "Datei als makefile verwenden" +#~ msgid "Target" +#~ msgstr "Ziel" -#: share/completions/make.fish:18 -msgid "Search directory for makefile" -msgstr "Verzeichnis nach makefile durchsuchen" +#~ msgid "Use file as makefile" +#~ msgstr "Datei als makefile verwenden" -#: share/completions/make.fish:19 -msgid "Number of concurrent jobs" -msgstr "Anzahl gleichzeitiger Jobs" +#~ msgid "Search directory for makefile" +#~ msgstr "Verzeichnis nach makefile durchsuchen" -#: share/completions/make.fish:23 -msgid "Ignore specified file" -msgstr "Angegebene Datei ignorieren" +#~ msgid "Number of concurrent jobs" +#~ msgstr "Anzahl gleichzeitiger Jobs" -#: share/completions/make.fish:32 -msgid "Pretend file is modified" -msgstr "Vorgegebene Datei wurde geändert" +#~ msgid "Ignore specified file" +#~ msgstr "Angegebene Datei ignorieren" -#: share/completions/makedepend.fish:1 -msgid "Define" -msgstr "Definiere" +#~ msgid "Pretend file is modified" +#~ msgstr "Vorgegebene Datei wurde geändert" -#: share/completions/makedepend.fish:2 -msgid "Include directory" -msgstr "include-Verzeichnis" +#~ msgid "Define" +#~ msgstr "Definiere" -#: share/completions/makedepend.fish:3 -msgid "Replace include directories" -msgstr "include-Verzeichnisse ersetzen" +#~ msgid "Include directory" +#~ msgstr "include-Verzeichnis" -#: share/completions/makedepend.fish:5 -msgid "Specify makefile" -msgstr "makefile angeben" +#~ msgid "Replace include directories" +#~ msgstr "include-Verzeichnisse ersetzen" -#: share/completions/makedepend.fish:6 -msgid "Prepend file to input" -msgstr "Datei der Eingabe voranstellen" +#~ msgid "Specify makefile" +#~ msgstr "makefile angeben" -#: share/completions/makedepend.fish:7 -msgid "Object file suffix" -msgstr "Suffix für Objektdatei" +#~ msgid "Prepend file to input" +#~ msgstr "Datei der Eingabe voranstellen" -#: share/completions/makedepend.fish:8 -msgid "Object file prefix" -msgstr "Prefix für Objektdatei" +#~ msgid "Object file suffix" +#~ msgstr "Suffix für Objektdatei" -#: share/completions/makedepend.fish:9 -msgid "Starting string delimiter" -msgstr "Start-Begrenzer für Zeichenketten" +#~ msgid "Object file prefix" +#~ msgstr "Prefix für Objektdatei" -#: share/completions/makedepend.fish:10 -msgid "Line width" -msgstr "Zeilenbreite" +#~ msgid "Starting string delimiter" +#~ msgstr "Start-Begrenzer für Zeichenketten" -#: share/completions/mosh.fish:20 -msgid "Controls use of speculative local echo" -msgstr "" +#~ msgid "Line width" +#~ msgstr "Zeilenbreite" -#: share/completions/mount.fish:19 -msgid "Mount partition with specified label" -msgstr "Partition mit angegebenem Label einhängen" +#~ msgid "Mount partition with specified label" +#~ msgstr "Partition mit angegebenem Label einhängen" -#: share/completions/mount.fish:20 -msgid "Mount partition with specified UID" -msgstr "Partition mit angegebener UID einhängen" +#~ msgid "Mount partition with specified UID" +#~ msgstr "Partition mit angegebener UID einhängen" -#: share/completions/mount.fish:21 #, fuzzy -msgid "Exclude file systems" -msgstr "Dateisysteme ausschliessen" +#~ msgid "Exclude file systems" +#~ msgstr "Dateisysteme ausschliessen" -#: share/completions/mount.fish:22 -msgid "Remount a subtree to a second position" -msgstr "Teilbaum an einer zweiten Position erneut einhängen" +#~ msgid "Remount a subtree to a second position" +#~ msgstr "Teilbaum an einer zweiten Position erneut einhängen" -#: share/completions/mount.fish:23 -msgid "Move a subtree to a new position" -msgstr "Teilbaum zu einer neuen Position verschieben" +#~ msgid "Move a subtree to a new position" +#~ msgstr "Teilbaum zu einer neuen Position verschieben" -#: share/completions/mount.fish:24 #, fuzzy -msgid "File system" -msgstr "Dateisystem" +#~ msgid "File system" +#~ msgstr "Dateisystem" -#: share/completions/mount.fish:26 -msgid "Mount option" -msgstr "Einhäng-Option" +#~ msgid "Mount option" +#~ msgstr "Einhäng-Option" -#: share/completions/mplayer.fish:28 -msgid "A/V sync speed" -msgstr "A/V Sync-Geschwindigkeit" +#~ msgid "A/V sync speed" +#~ msgstr "A/V Sync-Geschwindigkeit" -#: share/completions/mplayer.fish:32 -msgid "Loop playback" -msgstr "Playback-Schleife" +#~ msgid "Loop playback" +#~ msgstr "Playback-Schleife" -#: share/completions/mplayer.fish:58 share/completions/mplayer.fish:76 -msgid "Video output" -msgstr "Video-Ausgabe" +#~ msgid "Video output" +#~ msgstr "Video-Ausgabe" -#: share/completions/mplayer.fish:64 share/completions/mplayer.fish:70 -msgid "Audio output" -msgstr "Audio-Ausgabe" +#~ msgid "Audio output" +#~ msgstr "Audio-Ausgabe" -#: share/completions/msgfmt.fish:5 #, fuzzy -msgid "Generate a Java ResourceBundle class" -msgstr "Quellindexdatei erstellen" +#~ msgid "Generate a Java ResourceBundle class" +#~ msgstr "Quellindexdatei erstellen" -#: share/completions/msgfmt.fish:6 -msgid "Like --java, and assume Java2 (JDK 1.2 or higher)" -msgstr "" - -#: share/completions/msgfmt.fish:7 #, fuzzy -msgid "Generate a .NET .dll file" -msgstr "Masterdatei erstellen" +#~ msgid "Generate a .NET .dll file" +#~ msgstr "Masterdatei erstellen" -#: share/completions/msgfmt.fish:8 #, fuzzy -msgid "Generate a .NET .resources file" -msgstr "Quellindexdatei erstellen" +#~ msgid "Generate a .NET .resources file" +#~ msgstr "Quellindexdatei erstellen" -#: share/completions/msgfmt.fish:9 #, fuzzy -msgid "Generate a tcl/msgcat .msg file" -msgstr "Masterdatei erstellen" +#~ msgid "Generate a tcl/msgcat .msg file" +#~ msgstr "Masterdatei erstellen" -#: share/completions/msgfmt.fish:10 #, fuzzy -msgid "Generate a Qt .qm file" -msgstr "Masterdatei erstellen" +#~ msgid "Generate a Qt .qm file" +#~ msgstr "Masterdatei erstellen" -#: share/completions/msgfmt.fish:17 #, fuzzy -msgid "Resource name" -msgstr "Dienstname" - -#: share/completions/msgfmt.fish:18 -msgid "Locale name, either language or language_COUNTRY" -msgstr "" +#~ msgid "Resource name" +#~ msgstr "Dienstname" -#: share/completions/msgfmt.fish:19 #, fuzzy -msgid "Base directory for output" -msgstr "Datei-Deskriptor für Eingabe" - -#: share/completions/mutt.fish:18 -msgid "An expanded version of the given alias is passed to stdout" -msgstr "" - -#: share/completions/mutt.fish:19 -msgid "Attach a file to your message using MIME" -msgstr "" +#~ msgid "Base directory for output" +#~ msgstr "Datei-Deskriptor für Eingabe" -#: share/completions/mutt.fish:20 -msgid "Specify a blind-carbon-copy (BCC) recipient" -msgstr "" - -#: share/completions/mutt.fish:21 -msgid "Specify a carbon-copy (CC) recipient" -msgstr "" - -#: share/completions/mutt.fish:22 -msgid "Run command after processing of initialization files" -msgstr "" - -#: share/completions/mutt.fish:23 #, fuzzy -msgid "Specify which mailbox to load" -msgstr "sendmail-Befehl angeben" - -#: share/completions/mutt.fish:24 -msgid "Specify an initialization file to read instead of ~/.muttrc" -msgstr "" +#~ msgid "Specify which mailbox to load" +#~ msgstr "sendmail-Befehl angeben" -#: share/completions/mutt.fish:25 -msgid "Specify a draft file containing header and body for the message" -msgstr "" - -#: share/completions/mutt.fish:26 -msgid "Specify a file to include into the body of a message" -msgstr "" - -#: share/completions/mutt.fish:27 #, fuzzy -msgid "Specify a default mailbox type" -msgstr "Ziel-E-Mail-Adresse angeben" +#~ msgid "Specify a default mailbox type" +#~ msgstr "Ziel-E-Mail-Adresse angeben" -#: share/completions/mutt.fish:28 #, fuzzy -msgid "Query a configuration variables value" -msgstr "Eine Konfigurationsdatei angeben" +#~ msgid "Query a configuration variables value" +#~ msgstr "Eine Konfigurationsdatei angeben" -#: share/completions/mutt.fish:29 #, fuzzy -msgid "Specify the subject of the message" -msgstr "Geben Sie einen Titel für rss an" +#~ msgid "Specify the subject of the message" +#~ msgstr "Geben Sie einen Titel für rss an" -#: share/completions/mv.fish:4 -msgid "Answer for overwrite questions" -msgstr "Antwort für Überschreib-Fragen" +#~ msgid "Answer for overwrite questions" +#~ msgstr "Antwort für Überschreib-Fragen" -#: share/completions/node.fish:9 #, fuzzy -msgid "Print node's version" -msgstr "Kernel-Version ausgeben" +#~ msgid "Print node's version" +#~ msgstr "Kernel-Version ausgeben" -#: share/completions/node.fish:10 #, fuzzy -msgid "Evaluate script" -msgstr "Datei auswerten" +#~ msgid "Evaluate script" +#~ msgstr "Datei auswerten" -#: share/completions/node.fish:11 #, fuzzy -msgid "Print result of --eval" -msgstr "Flaches Profil ausgeben" +#~ msgid "Print result of --eval" +#~ msgstr "Flaches Profil ausgeben" -#: share/completions/obnam.fish:9 #, fuzzy -msgid "Adds an encryption key to the repository" -msgstr "Neue/s Datei/Verzeichnis zum Paketdepot hinzufügen" - -#: share/completions/obnam.fish:11 -msgid "Lists the keys associated with each client" -msgstr "" +#~ msgid "Adds an encryption key to the repository" +#~ msgstr "Neue/s Datei/Verzeichnis zum Paketdepot hinzufügen" -#: share/completions/obnam.fish:12 #, fuzzy -msgid "Lists the clients in the repository" -msgstr "Paketdepot aktualisieren" +#~ msgid "Lists the clients in the repository" +#~ msgstr "Paketdepot aktualisieren" -#: share/completions/obnam.fish:13 #, fuzzy -msgid "Compares two generations" -msgstr "Saloppe Einhäng-Optionen tolerieren" +#~ msgid "Compares two generations" +#~ msgstr "Saloppe Einhäng-Optionen tolerieren" -#: share/completions/obnam.fish:14 #, fuzzy -msgid "Dumps the repository" -msgstr "Paketdepot aktualisieren" +#~ msgid "Dumps the repository" +#~ msgstr "Paketdepot aktualisieren" -#: share/completions/obnam.fish:15 #, fuzzy -msgid "Removes a lock file for a client" -msgstr "Alle gz-Dateien aus dem Zwischenspeicher entfernen" +#~ msgid "Removes a lock file for a client" +#~ msgstr "Alle gz-Dateien aus dem Zwischenspeicher entfernen" -#: share/completions/obnam.fish:16 #, fuzzy -msgid "Removes backup generations" -msgstr "Vervollständigung entfernen" +#~ msgid "Removes backup generations" +#~ msgstr "Vervollständigung entfernen" -#: share/completions/obnam.fish:17 #, fuzzy -msgid "Checks the consistency of the repository" -msgstr "Das ganze Paketdepot prüfen" +#~ msgid "Checks the consistency of the repository" +#~ msgstr "Das ganze Paketdepot prüfen" -#: share/completions/obnam.fish:18 -msgid "Lists every backup generation" -msgstr "" - -#: share/completions/obnam.fish:19 -msgid "Lists the identifier for every generation" -msgstr "" - -#: share/completions/obnam.fish:20 #, fuzzy -msgid "Lists the keys" -msgstr "Vertraute Schlüssel auflisten" +#~ msgid "Lists the keys" +#~ msgstr "Vertraute Schlüssel auflisten" -#: share/completions/obnam.fish:21 #, fuzzy -msgid "Lists the toplevel keys" -msgstr "Vertraute Schlüssel auflisten" +#~ msgid "Lists the toplevel keys" +#~ msgstr "Vertraute Schlüssel auflisten" -#: share/completions/obnam.fish:22 #, fuzzy -msgid "Lists the contents of a given generation" -msgstr "Startverzeichnis festlegen" +#~ msgid "Lists the contents of a given generation" +#~ msgstr "Startverzeichnis festlegen" -#: share/completions/obnam.fish:23 #, fuzzy -msgid "Makes the repository available via FUSE" -msgstr "Das Paketdepotverzeichnis angeben, in dem gearbeitet wird" +#~ msgid "Makes the repository available via FUSE" +#~ msgstr "Das Paketdepotverzeichnis angeben, in dem gearbeitet wird" -#: share/completions/obnam.fish:24 -msgid "Check if a backup age exceeds a threshold" -msgstr "" - -#: share/completions/obnam.fish:25 #, fuzzy -msgid "Removes a client from the repository" -msgstr "Einen Eintrag aus dem Paketdepot entfernen" +#~ msgid "Removes a client from the repository" +#~ msgstr "Einen Eintrag aus dem Paketdepot entfernen" -#: share/completions/obnam.fish:26 #, fuzzy -msgid "Removes a key from the repository" -msgstr "Einen Eintrag aus dem Paketdepot entfernen" +#~ msgid "Removes a key from the repository" +#~ msgstr "Einen Eintrag aus dem Paketdepot entfernen" -#: share/completions/obnam.fish:27 #, fuzzy -msgid "Restore files from the repository" -msgstr "Dateien in das Paketdepot übertragen" +#~ msgid "Restore files from the repository" +#~ msgstr "Dateien in das Paketdepot übertragen" -#: share/completions/obnam.fish:28 #, fuzzy -msgid "Verifies files in the repository" -msgstr "Dateien in das Paketdepot übertragen" - -#: share/completions/obnam.fish:30 -msgid "Restore setuid/setgid bits in restored files" -msgstr "" +#~ msgid "Verifies files in the repository" +#~ msgstr "Dateien in das Paketdepot übertragen" -#: share/completions/obnam.fish:31 -msgid "Do not restore setuid/setgid bits in restored files" -msgstr "" - -#: share/completions/obnam.fish:32 #, fuzzy -msgid "Name of client" -msgstr "Name des Patch" +#~ msgid "Name of client" +#~ msgstr "Name des Patch" -#: share/completions/obnam.fish:33 #, fuzzy -msgid "Compress repository with" -msgstr "Auf Standardausgabe komprimieren" +#~ msgid "Compress repository with" +#~ msgstr "Auf Standardausgabe komprimieren" -#: share/completions/obnam.fish:34 -msgid "For --nagios-last-backup-age: maximum age" -msgstr "" +#, fuzzy +#~ msgid "Do not dump metadata about files" +#~ msgstr "Erstellte Dateien nicht löschen" -#: share/completions/obnam.fish:35 -msgid "Dump metadata about files" -msgstr "" +#, fuzzy +#~ msgid "Generate man page" +#~ msgstr "Ein neues Schlüsselpaar erstellen" -#: share/completions/obnam.fish:36 #, fuzzy -msgid "Do not dump metadata about files" -msgstr "Erstellte Dateien nicht löschen" +#~ msgid "Show this help message and exit" +#~ msgstr "Hilfe anzeigen und beenden" -#: share/completions/obnam.fish:37 #, fuzzy -msgid "Generate man page" -msgstr "Ein neues Schlüsselpaar erstellen" +#~ msgid "Do not actually change anything" +#~ msgstr "Nichts schreiben" -#: share/completions/obnam.fish:38 -msgid "Which generation to restore" -msgstr "" +#, fuzzy +#~ msgid "Actually commit changes" +#~ msgstr "Änderungen zusammenfassen" -#: share/completions/obnam.fish:39 #, fuzzy -msgid "Show this help message and exit" -msgstr "Hilfe anzeigen und beenden" +#~ msgid "Simulate failures for files that match REGEXP" +#~ msgstr "Dem REGEXP entsprechende Patche auswählen" -#: share/completions/obnam.fish:40 -msgid "Policy for what generations to keep when forgetting." -msgstr "" +#, fuzzy +#~ msgid "Do not be verbose" +#~ msgstr "Nicht überschreiben" -#: share/completions/obnam.fish:41 -msgid "Wait TIMEOUT seconds for an existing lock" -msgstr "" +#, fuzzy +#~ msgid "Show version number and exit" +#~ msgstr "Version anzeigen und beenden" -#: share/completions/obnam.fish:43 #, fuzzy -msgid "Do not actually change anything" -msgstr "Nichts schreiben" +#~ msgid "Deduplicate mode" +#~ msgstr "Lese-/Schreib-Modus" -#: share/completions/obnam.fish:44 #, fuzzy -msgid "Actually commit changes" -msgstr "Änderungen zusammenfassen" +#~ msgid "Exclude directories tagged as cache" +#~ msgstr "Verzeichnisse nach Quelle durchsuchen" -#: share/completions/obnam.fish:45 -msgid "Show only errors, no progress updates" -msgstr "" +#, fuzzy +#~ msgid "Include directories tagged as cache" +#~ msgstr "include-Verzeichnis" -#: share/completions/obnam.fish:46 -msgid "Show errors and progress updates" -msgstr "" +#, fuzzy +#~ msgid "Do not follow mount points" +#~ msgstr "Lange Zeilen nicht umbrechen" -#: share/completions/obnam.fish:49 #, fuzzy -msgid "Simulate failures for files that match REGEXP" -msgstr "Dem REGEXP entsprechende Patche auswählen" +#~ msgid "Follow mount points" +#~ msgstr "Einhängepunkt" -#: share/completions/obnam.fish:52 -msgid "Be more verbose" -msgstr "" +#, fuzzy +#~ msgid "Write out the current configuration" +#~ msgstr "Dienstkonfiguration neu laden" -#: share/completions/obnam.fish:53 #, fuzzy -msgid "Do not be verbose" -msgstr "Nicht überschreiben" +#~ msgid "Write out setting names" +#~ msgstr "Prompt ausgeben" -#: share/completions/obnam.fish:54 -msgid "Verify N files randomly from the backup" -msgstr "" +#, fuzzy +#~ msgid "Show all options" +#~ msgstr "Hilfe- und Debug-Optionen anzeigen" -#: share/completions/obnam.fish:55 #, fuzzy -msgid "Show version number and exit" -msgstr "Version anzeigen und beenden" +#~ msgid "List config files" +#~ msgstr "Konfigurationsdatei benutzen" -#: share/completions/obnam.fish:57 -msgid "Make a checkpoint after a given SIZE" -msgstr "" +#, fuzzy +#~ msgid "Clear list of configuration files to read" +#~ msgstr "Liste der rpm-Konfigurationsdateien" -#: share/completions/obnam.fish:58 #, fuzzy -msgid "Deduplicate mode" -msgstr "Lese-/Schreib-Modus" +#~ msgid "Do not show additional user IDs" +#~ msgstr "Verzeichnisnamen nicht speichern" -#: share/completions/obnam.fish:60 #, fuzzy -msgid "Exclude directories tagged as cache" -msgstr "Verzeichnisse nach Quelle durchsuchen" +#~ msgid "Use /dev/urandom instead of /dev/random" +#~ msgstr "purge anstelle von remove verwenden" -#: share/completions/obnam.fish:61 #, fuzzy -msgid "Include directories tagged as cache" -msgstr "include-Verzeichnis" +#~ msgid "Ignore chunks when checking integrity" +#~ msgstr "Groß-/Kleinschreibung beim Dateinamenvergleich ignorieren" -#: share/completions/obnam.fish:63 -msgid "Leave checkpoint generations at the end of backup" -msgstr "" +#, fuzzy +#~ msgid "Check only the last generation" +#~ msgstr "Inhaltsgenerierung durchführen" -#: share/completions/obnam.fish:64 -msgid "Omit checkpoint generations at the end of backup" -msgstr "" +#, fuzzy +#~ msgid "Check all generations" +#~ msgstr "Installierte Pakete abfragen" -#: share/completions/obnam.fish:65 #, fuzzy -msgid "Do not follow mount points" -msgstr "Lange Zeilen nicht umbrechen" +#~ msgid "Do not check directories" +#~ msgstr "Verzeichnisnamen nicht speichern" -#: share/completions/obnam.fish:66 #, fuzzy -msgid "Follow mount points" -msgstr "Einhängepunkt" +#~ msgid "Check directories" +#~ msgstr "Verzeichnisse rekursiv durchlaufen" -#: share/completions/obnam.fish:67 -msgid "Put small files directly into the B-tree" -msgstr "" +#, fuzzy +#~ msgid "Do not check files" +#~ msgstr "Quelldateien nicht löschen" -#: share/completions/obnam.fish:68 -msgid "No not put small files into the B-tree" -msgstr "" +#, fuzzy +#~ msgid "Check files" +#~ msgstr "Installierte Pakete abfragen" -#: share/completions/obnam.fish:70 #, fuzzy -msgid "Write out the current configuration" -msgstr "Dienstkonfiguration neu laden" +#~ msgid "Do not check any generations" +#~ msgstr "Überprüfungsstatus von Schlüsselsignaturen nicht zwischenspeichern" -#: share/completions/obnam.fish:71 #, fuzzy -msgid "Write out setting names" -msgstr "Prompt ausgeben" +#~ msgid "Do not check shared B-trees" +#~ msgstr "Quelldateien nicht löschen" -#: share/completions/obnam.fish:72 #, fuzzy -msgid "Show all options" -msgstr "Hilfe- und Debug-Optionen anzeigen" +#~ msgid "Check shared B-trees" +#~ msgstr "Installierte Pakete abfragen" -#: share/completions/obnam.fish:73 #, fuzzy -msgid "List config files" -msgstr "Konfigurationsdatei benutzen" +#~ msgid "Depth of chunk id mapping" +#~ msgstr "Tiefe der Aufrufkette" -#: share/completions/obnam.fish:74 #, fuzzy -msgid "Clear list of configuration files to read" -msgstr "Liste der rpm-Konfigurationsdateien" +#~ msgid "Use openssh if available" +#~ msgstr "Index erstellen, wenn nicht vorhanden" -#: share/completions/obnam.fish:75 -msgid "PGP key with which to encrypt" -msgstr "" +#~ msgid "Specify record separator" +#~ msgstr "Satztrenner angeben" -#: share/completions/obnam.fish:76 -msgid "Show additional user IDs" -msgstr "" +#~ msgid "Turn on autosplit mode" +#~ msgstr "Autosplit-Modus aktivieren" -#: share/completions/obnam.fish:77 -#, fuzzy -msgid "Do not show additional user IDs" -msgstr "Verzeichnisnamen nicht speichern" +#~ msgid "Check syntax" +#~ msgstr "Syntax prüfen" -#: share/completions/obnam.fish:78 -msgid "PGP key id" -msgstr "" +#~ msgid "Debugger" +#~ msgstr "Debugger" -#: share/completions/obnam.fish:79 -msgid "Size of symmetric key" -msgstr "" +#, fuzzy +#~ msgid "Disable sitecustomize.pl" +#~ msgstr "Cookie-Benutzung deaktivieren" -#: share/completions/obnam.fish:80 #, fuzzy -msgid "Use /dev/urandom instead of /dev/random" -msgstr "purge anstelle von remove verwenden" +#~ msgid "Show help and exit" +#~ msgstr "Hilfe anzeigen und beenden" -#: share/completions/obnam.fish:81 -msgid "Use default /dev/random" -msgstr "" +#~ msgid "Automatic line ending processing" +#~ msgstr "Automatische Zeilenende-Verarbeitung" -#: share/completions/obnam.fish:83 -msgid "fsck should try to fix problems" -msgstr "" +#~ msgid "Loop script" +#~ msgstr "Schleifen-Skript" -#: share/completions/obnam.fish:84 -msgid "fsck should not try to fix problems" -msgstr "" +#~ msgid "Loop script, print $_" +#~ msgstr "Schleifen-Skript, zeige $_" -#: share/completions/obnam.fish:85 -#, fuzzy -msgid "Ignore chunks when checking integrity" -msgstr "Groß-/Kleinschreibung beim Dateinamenvergleich ignorieren" +#~ msgid "Define custom switches" +#~ msgstr "Angepasste Schalter definieren" -#: share/completions/obnam.fish:86 -msgid "Check chunks when checking integrity" -msgstr "" +#~ msgid "Search $PATH for script" +#~ msgstr "$PATH nach Skript durchsuchen" -#: share/completions/obnam.fish:87 -msgid "Do not check data for cient NAME." -msgstr "" +#~ msgid "Taint checking" +#~ msgstr "Taintprüfung" + +#~ msgid "Unsafe mode" +#~ msgstr "Unsicherer Modus" -#: share/completions/obnam.fish:88 #, fuzzy -msgid "Check only the last generation" -msgstr "Inhaltsgenerierung durchführen" +#~ msgid "Display configuration and exit" +#~ msgstr "Version anzeigen und beenden" -#: share/completions/obnam.fish:89 share/completions/obnam.fish:95 #, fuzzy -msgid "Check all generations" -msgstr "Installierte Pakete abfragen" +#~ msgid "Show warnings" +#~ msgstr "Warnungen unterdrücken" -#: share/completions/obnam.fish:90 #, fuzzy -msgid "Do not check directories" -msgstr "Verzeichnisnamen nicht speichern" +#~ msgid "Force warnings" +#~ msgstr "Warnungen unterdrücken" -#: share/completions/obnam.fish:91 #, fuzzy -msgid "Check directories" -msgstr "Verzeichnisse rekursiv durchlaufen" +#~ msgid "Disable warnings" +#~ msgstr "Warnungen über MFC deaktivieren" -#: share/completions/obnam.fish:92 #, fuzzy -msgid "Do not check files" -msgstr "Quelldateien nicht löschen" +#~ msgid "Ports Directory" +#~ msgstr "Verzeichnis" -#: share/completions/obnam.fish:93 #, fuzzy -msgid "Check files" -msgstr "Installierte Pakete abfragen" +#~ msgid "Installed Package" +#~ msgstr "Neues Paket installieren" -#: share/completions/obnam.fish:94 #, fuzzy -msgid "Do not check any generations" -msgstr "Überprüfungsstatus von Schlüsselsignaturen nicht zwischenspeichern" +#~ msgid "execute commands from file, then exit" +#~ msgstr "Befehl ausführen, als ob es Teil von .wgetrc wäre" -#: share/completions/obnam.fish:96 -msgid "Do not check per-client B-trees" -msgstr "" +#~ msgid "Add suggested packages to the transaction set when needed" +#~ msgstr "" +#~ "Füge der Transaktionsmenge die vorgeschlagenen Pakete hinzu, falls nötig" -#: share/completions/obnam.fish:97 -msgid "Check per-client B-trees" -msgstr "" +#~ msgid "" +#~ "Installs or upgrades all the files in the package, even if they aren't " +#~ "needed (missingok) and don't exist" +#~ msgstr "" +#~ "Installiert oder aktualisiert alle Dateien im Paket, selbst wenn sie " +#~ "nicht erforderlich sind (missingok) und nicht existieren" -#: share/completions/obnam.fish:98 -#, fuzzy -msgid "Do not check shared B-trees" -msgstr "Quelldateien nicht löschen" +#~ msgid "" +#~ "Used with --relocate, permit relocations on all file paths, not just " +#~ "those OLD-PATH's included in the binary package relocation hint(s)" +#~ msgstr "" +#~ "Benutzt mit --relocate, erlaubt es die Relozierung auf sämtliche " +#~ "Dateipfade und nicht nur auf die ALTENPFADE, die in dem/den Binärpaket-" +#~ "Relozierungshinweis(en) enthalten sind" -#: share/completions/obnam.fish:99 -#, fuzzy -msgid "Check shared B-trees" -msgstr "Installierte Pakete abfragen" +#~ msgid "Don't install files whose name begins with specified path" +#~ msgstr "" +#~ "Keine Dateien installieren, deren Name mit dem angegebenen Pfad beginnen" -#: share/completions/obnam.fish:102 -msgid "Keep last N logs (10)" -msgstr "" +#~ msgid "Don't install any files which are marked as documentation" +#~ msgstr "Keine Dateien installieren, die als Dokumentation markiert sind" -#: share/completions/obnam.fish:103 -msgid "Log at LEVEL" -msgstr "" +#~ msgid "Same as using --replacepkgs, --replacefiles, and --oldpackage" +#~ msgstr "" +#~ "Entspricht der Benutzung von --replacepkgs, --replacefiles und --" +#~ "oldpackage" -#: share/completions/obnam.fish:104 -msgid "Rotate logs larger than SIZE" -msgstr "" +#~ msgid "Print 50 hash marks as the package archive is unpacked" +#~ msgstr "Zeige 50 Hash-Markierungen beim Auspacken des Paketarchivs" -#: share/completions/obnam.fish:105 -msgid "Set permissions of logfiles to MODE" -msgstr "" +#~ msgid "Don't check for sufficient disk space before installation" +#~ msgstr "Vor der Installation nicht auf ausreichenden Plattenplatz prüfen" -#: share/completions/obnam.fish:106 -msgid "Options to pass to FUSE" -msgstr "" +#~ msgid "" +#~ "Allow installation or upgrading even if the architectures of the binary " +#~ "package and host don't match" +#~ msgstr "" +#~ "Installation und Aktualisierung auch dann ermöglichen, wenn die " +#~ "Architekturen des Binärpaketes und des Rechners nicht übereinstimmen" -#: share/completions/obnam.fish:107 -msgid "Make memory profiling dumps using METHOD" -msgstr "" +#~ msgid "" +#~ "Allow installation or upgrading even if the operating systems of the " +#~ "binary package and host don't match" +#~ msgstr "" +#~ "Installation und Aktualisierung auch dann ermöglichen, wenn die " +#~ "Betriebssysteme des Binärpaketes und des Rechners nicht übereinstimmen" -#: share/completions/obnam.fish:108 -msgid "Make memory profiling dumps at SECONDS" -msgstr "" +#~ msgid "Install documentation files (default)" +#~ msgstr "Dokumentationsdateien installieren (Standard)" -#: share/completions/obnam.fish:109 -msgid "Size of chunks of file data" -msgstr "" +#~ msgid "Update only the database, not the filesystem" +#~ msgstr "Nur die Datenbank, nicht das Dateisystem aktualisieren" -#: share/completions/obnam.fish:110 -msgid "Encode NUM chunk ids per group" -msgstr "" +#~ msgid "Don't verify package or header digests when reading" +#~ msgstr "Beim Lesen keine Paket- oder Kopfzeilen-Prüfsummen überprüfen" -#: share/completions/obnam.fish:111 -msgid "Chunk id level size" -msgstr "" +#~ msgid "Don't verify package or header signatures when reading" +#~ msgstr "Beim Lesen keine Paket- oder Kopfzeilen-Signaturen überprüfen" -#: share/completions/obnam.fish:112 -#, fuzzy -msgid "Depth of chunk id mapping" -msgstr "Tiefe der Aufrufkette" +#~ msgid "Don't do a dependency check" +#~ msgstr "Keine Abhängigkeiten prüfen" -#: share/completions/obnam.fish:113 -msgid "Chunk id mapping lowest bits skip" -msgstr "" +#~ msgid "Don't suggest package(s) that provide a missing dependency" +#~ msgstr "Keine Pakete vorschlagen, die fehlende Abhängigkeiten bereitstellen" -#: share/completions/obnam.fish:114 -msgid "Size of LRU cache for B-tree nodes" -msgstr "" +#~ msgid "Don't change the package installation order" +#~ msgstr "Paket-Installationsreihenfolge nicht ändern" -#: share/completions/obnam.fish:115 -msgid "Size of B-tree nodes on disk" -msgstr "" +#~ msgid "Don't execute scripts" +#~ msgstr "Keine Skrpte ausführen" -#: share/completions/obnam.fish:116 -msgid "Length of upload queue for B-tree nodes" -msgstr "" +#~ msgid "Don't execute pre scripts" +#~ msgstr "Keine pre-Skripte ausführen" -#: share/completions/obnam.fish:117 -msgid "Use only paramiko, no openssh" -msgstr "" +#~ msgid "Don't execute post scripts" +#~ msgstr "Keine post-Skripte ausführen" -#: share/completions/obnam.fish:118 -#, fuzzy -msgid "Use openssh if available" -msgstr "Index erstellen, wenn nicht vorhanden" +#~ msgid "Don't execute preun scripts" +#~ msgstr "Prerun-Skripte nicht ausführen" -#: share/completions/obnam.fish:120 -msgid "ssh host key check" -msgstr "" +#~ msgid "Don't execute postun scripts" +#~ msgstr "Postrun-Skripte nicht ausführen" -#: share/completions/perl.fish:6 -msgid "Specify record separator" -msgstr "Satztrenner angeben" +#~ msgid "Don't execute trigger scriptlets" +#~ msgstr "Trigger-Skripte nicht ausführen" -#: share/completions/perl.fish:7 -msgid "Turn on autosplit mode" -msgstr "Autosplit-Modus aktivieren" +#~ msgid "Don't execute triggerin scriptlets" +#~ msgstr "Triggerin-Skripte nicht ausführen" -#: share/completions/perl.fish:8 -msgid "Check syntax" -msgstr "Syntax prüfen" +#~ msgid "Don't execute triggerun scriptlets" +#~ msgstr "Triggerun-Skripte nicht ausführen" -#: share/completions/perl.fish:9 -msgid "Control Unicode features" -msgstr "" +#~ msgid "Don't execute triggerpostun scriptlets" +#~ msgstr "Triggerpostun-Skripte nicht ausführen" + +#~ msgid "Allow an upgrade to replace a newer package with an older one" +#~ msgstr "" +#~ "Erlaube einer Aktualisierung das Ersetzen eines neueren Paketes durch ein " +#~ "älteres" + +#~ msgid "" +#~ "Print percentages as files are unpacked from the package archive. This is " +#~ "intended to make rpm easy to run from other tools" +#~ msgstr "" +#~ "Prozentwert ausgeben, während Dateien aus dem Paketarchiv ausgepackt " +#~ "werden. Dies soll das Ausführen von rpm aus anderen Programmen heraus " +#~ "erleichtern" + +#~ msgid "" +#~ "For relocatable binary packages, translate all file paths that start with " +#~ "the installation prefix in the package relocation hint(s) to NEWPATH" +#~ msgstr "" +#~ "Für relozierbare Binärpakete alle Dateipfade, die mit dem " +#~ "Installationspräfix im/in den Paket-Relozierungshinweis(en) beginnen, auf " +#~ "den NEUENPFAD konvertieren" + +#~ msgid "Re-package the files before erasing" +#~ msgstr "Dateien vor dem Löschen umpacken" + +#~ msgid "" +#~ "Install the packages even if they replace files from other, already " +#~ "installed, packages" +#~ msgstr "" +#~ "Installiere diese Pakete, selbst wenn sie Dateien aus anderen, bereits " +#~ "installierten Paketen ersetzen" + +#~ msgid "" +#~ "Install the packages even if some of them are already installed on this " +#~ "system" +#~ msgstr "" +#~ "Installiere diese Pakete, selbst wenn einige von ihnen auf diesem System " +#~ "bereits installiert sind" + +#~ msgid "" +#~ "Don't install the package, simply check for and report potential conflicts" +#~ msgstr "" +#~ "Paket nicht installieren, nur auf mögliche Konflikte testen und diese " +#~ "anzeigen" + +#~ msgid "Display change information for the package" +#~ msgstr "Zeigt Änderungsinformationen zu dem Paket an" + +#~ msgid "List only configuration files (implies -l)" +#~ msgstr "Zeigt nur Konfigurationsdateien (impliziert -l)" -#: share/completions/perl.fish:10 -msgid "Debug UTF-8 cache" -msgstr "" +#~ msgid "List only documentation files (implies -l)" +#~ msgstr "Nur Dokumentationsdateien auflisten (impliziert -l)" -#: share/completions/perl.fish:11 -msgid "ARGV uses UTF-8" -msgstr "" +#~ msgid "Dump file information. Must be used with at least one of -l, -c, -d" +#~ msgstr "" +#~ "Gibt Dateiinformationen aus. Muss mit einem von -l, -c, -d benutzt werden" -#: share/completions/perl.fish:12 -msgid "Opened filehandles are UTF-8" -msgstr "" +#~ msgid "List all the files in each selected package" +#~ msgstr "Zeigt alle Dateien in jedem gewählten Paket an" -#: share/completions/perl.fish:13 -msgid "STDERR is UTF-8" -msgstr "" +#~ msgid "" +#~ "Display package information, including name, version, and description. " +#~ "Uses --queryformat if specified" +#~ msgstr "" +#~ "Zeit Paketinformation einschließlich Name, Version und Beschreibung. " +#~ "Benutzt --queryformat falls angegeben" -#: share/completions/perl.fish:14 -msgid "Filehandles that are read are UTF-8" -msgstr "" +#~ msgid "Orders the package listing by install time" +#~ msgstr "Ordnet die angezeigten Paketen entsprechend der Installationszeit" -#: share/completions/perl.fish:15 -msgid "STDIN is UTF-8" -msgstr "" +#~ msgid "List files in package" +#~ msgstr "Dateien im Paket auflisten" -#: share/completions/perl.fish:16 -msgid "Enable Unicode conditionally" -msgstr "" +#~ msgid "List capabilities this package provides" +#~ msgstr "Eigenschaften auflisten, die dieses Paket bereitstellt" -#: share/completions/perl.fish:17 -msgid "Filehandles written to are UTF-8" -msgstr "" +#~ msgid "List packages on which this package depends" +#~ msgstr "Pakete auflisten, von denen dieses Paket abhängt" -#: share/completions/perl.fish:18 -msgid "STDOUT is UTF-8" -msgstr "" +#~ msgid "List the package specific scriptlets" +#~ msgstr "Die Paket-spezifischen Skripte auflisten" -#: share/completions/perl.fish:19 -msgid "STDOUT, STDIN, and STDERR are UTF-8" -msgstr "" +#~ msgid "" +#~ "Display the states of files in the package. The state of each file is one " +#~ "of normal, not installed, or replaced" +#~ msgstr "" +#~ "Zeigt den Status der Dateien im Paket. Status einer jeden Datei ist " +#~ "entweder normal, nicht installiert oder ersetzt" -#: share/completions/perl.fish:20 -msgid "Debugger" -msgstr "Debugger" +#~ msgid "Display the trigger scripts contained in the package" +#~ msgstr "Die im Paket enthaltenen Auslöser-Skripte anzeigen" -#: share/completions/perl.fish:25 -#, fuzzy -msgid "Disable sitecustomize.pl" -msgstr "Cookie-Benutzung deaktivieren" +#~ msgid "Query all installed packages" +#~ msgstr "Alle installierten Pakete abfragen" -#: share/completions/perl.fish:27 -#, fuzzy -msgid "Show help and exit" -msgstr "Hilfe anzeigen und beenden" +#~ msgid "Query package owning specified file" +#~ msgstr "Paket abfragen, zu dem die angegebene Datei gehört" -#: share/completions/perl.fish:30 -msgid "Automatic line ending processing" -msgstr "Automatische Zeilenende-Verarbeitung" +#~ msgid "" +#~ "Query package that contains a given file identifier, i.e. the MD5 digest " +#~ "of the file contents" +#~ msgstr "" +#~ "Frage nach Paketen, die einen gegebenen Datei-Identifikator enthalten, z. " +#~ "B. den MD5-Digest der Dateiinhalte" -#: share/completions/perl.fish:33 -msgid "Loop script" -msgstr "Schleifen-Skript" +#~ msgid "Query packages with the specified group" +#~ msgstr "Pakete mit der angegebenen Gruppe abfragen" -#: share/completions/perl.fish:34 -#, sh-format -msgid "Loop script, print $_" -msgstr "Schleifen-Skript, zeige $_" +#~ msgid "" +#~ "Query package that contains a given header identifier, i.e. the SHA1 " +#~ "digest of the immutable header region" +#~ msgstr "" +#~ "Frage nach Paketen, die einen gegebenen Kopfzeilen-Bezeichner enthalten, " +#~ "z. B. den SHA1-Digest des unveränderlichen Kopfzeilenbereichs" -#: share/completions/perl.fish:35 -msgid "Define custom switches" -msgstr "Angepasste Schalter definieren" +#~ msgid "Query an (uninstalled) package in specified file" +#~ msgstr "Ein (deinstalliertes) Paket in der angegebenen Datei abfragen" -#: share/completions/perl.fish:36 -#, sh-format -msgid "Search $PATH for script" -msgstr "$PATH nach Skript durchsuchen" +#~ msgid "" +#~ "Query package that contains a given package identifier, i.e. the MD5 " +#~ "digest of the combined header and payload contents" +#~ msgstr "" +#~ "Paket abfragen, das einen gegebenen Paket-Bezeichner enthält, z. B. die " +#~ "MD5-Prüfsumme der kombinierten Kopfzeile und des Nutzdateninhaltes" -#: share/completions/perl.fish:37 -msgid "Taint checking, but only with warnings" -msgstr "" +#~ msgid "Parse and query specified spec-file as if it were a package" +#~ msgstr "Angegebene spec-Datei auswerten, als ob es ein Paket wäre" -#: share/completions/perl.fish:38 -msgid "Taint checking" -msgstr "Taintprüfung" +#~ msgid "" +#~ "Query package(s) that have the specified TID (transaction identifier)" +#~ msgstr "" +#~ "Paket(e) abfragen, die den angegebenen TID (Transaktions-Bezeichner) " +#~ "besitzen" -#: share/completions/perl.fish:39 -msgid "Dump core" -msgstr "" +#~ msgid "Query packages that are triggered by the specified packages" +#~ msgstr "Pakete abfragen, die von den angegebenen Paketen aktiviert werden" -#: share/completions/perl.fish:40 -msgid "Unsafe mode" -msgstr "Unsicherer Modus" +#~ msgid "Query all packages that provide the specified capability" +#~ msgstr "Alle Pakete abfragen, die die angegebene Eigenschaft bereitstellen" -#: share/completions/perl.fish:42 -#, fuzzy -msgid "Display configuration and exit" -msgstr "Version anzeigen und beenden" +#~ msgid "" +#~ "Query all packages that requires the specified capability for functioning" +#~ msgstr "" +#~ "Alle Pakete abfragen, die die angegebene Eigenschaft für die " +#~ "Funktionsfähigkeit erfordern" -#: share/completions/perl.fish:43 -#, fuzzy -msgid "Show warnings" -msgstr "Warnungen unterdrücken" +#~ msgid "Don't verify dependencies of packages" +#~ msgstr "Abhängigkeiten der Pakete nicht prüfen" -#: share/completions/perl.fish:44 -#, fuzzy -msgid "Force warnings" -msgstr "Warnungen unterdrücken" +#~ msgid "Don't verify any attributes of package files" +#~ msgstr "Keine Attribute der Paketdateien prüfen" -#: share/completions/perl.fish:45 -#, fuzzy -msgid "Disable warnings" -msgstr "Warnungen über MFC deaktivieren" +#~ msgid "Don't execute the %verifyscript scriptlet" +#~ msgstr "Das Skript %verifyscript nicht ausführen" -#: share/completions/portmaster.fish:49 -#, fuzzy -msgid "Ports Directory" -msgstr "Verzeichnis" +#~ msgid "Don't verify linkto attribute" +#~ msgstr "Verweis(linkto)-Attribute nicht prüfen" -#: share/completions/portmaster.fish:55 -#, fuzzy -msgid "Installed Package" -msgstr "Neues Paket installieren" +#~ msgid "Don't verify md5 attribute" +#~ msgstr "md5-Attribute nicht prüfen" -#: share/completions/psql.fish:19 -#, fuzzy -msgid "execute commands from file, then exit" -msgstr "Befehl ausführen, als ob es Teil von .wgetrc wäre" +#~ msgid "Don't verify size attribute" +#~ msgstr "Grössen-Attribute nicht prüfen" -#: share/completions/psql.fish:63 -msgid "database server port" -msgstr "" +#~ msgid "Don't verify user attribute" +#~ msgstr "Benutzerattribute nicht überprüfen" -#: share/completions/rpm.fish:22 -msgid "Add suggested packages to the transaction set when needed" -msgstr "" -"Füge der Transaktionsmenge die vorgeschlagenen Pakete hinzu, falls nötig" +#~ msgid "Don't verify group attribute" +#~ msgstr "Gruppen-Attribute nicht prüfen" -#: share/completions/rpm.fish:23 -msgid "" -"Installs or upgrades all the files in the package, even if they aren't " -"needed (missingok) and don't exist" -msgstr "" -"Installiert oder aktualisiert alle Dateien im Paket, selbst wenn sie nicht " -"erforderlich sind (missingok) und nicht existieren" +#~ msgid "Don't verify time attribute" +#~ msgstr "Zeit-Attribute nicht prüfen" -#: share/completions/rpm.fish:24 -msgid "" -"Used with --relocate, permit relocations on all file paths, not just those " -"OLD-PATH's included in the binary package relocation hint(s)" -msgstr "" -"Benutzt mit --relocate, erlaubt es die Relozierung auf sämtliche Dateipfade " -"und nicht nur auf die ALTENPFADE, die in dem/den Binärpaket-" -"Relozierungshinweis(en) enthalten sind" +#~ msgid "Don't verify mode attribute" +#~ msgstr "Modus-Attribute nicht prüfen" -#: share/completions/rpm.fish:25 -msgid "Don't install files whose name begins with specified path" -msgstr "" -"Keine Dateien installieren, deren Name mit dem angegebenen Pfad beginnen" +#~ msgid "Don't verify dev attribute" +#~ msgstr "Geräte-Attribute nicht prüfen" -#: share/completions/rpm.fish:26 -msgid "Don't install any files which are marked as documentation" -msgstr "Keine Dateien installieren, die als Dokumentation markiert sind" +#~ msgid "Remove all versions of the package which match specified string" +#~ msgstr "Alle Paketversionen entfernen, die der Zeichenkette entsprechen" -#: share/completions/rpm.fish:27 -msgid "Same as using --replacepkgs, --replacefiles, and --oldpackage" -msgstr "" -"Entspricht der Benutzung von --replacepkgs, --replacefiles und --oldpackage" - -#: share/completions/rpm.fish:28 -msgid "Print 50 hash marks as the package archive is unpacked" -msgstr "Zeige 50 Hash-Markierungen beim Auspacken des Paketarchivs" - -#: share/completions/rpm.fish:29 -msgid "Don't check for sufficient disk space before installation" -msgstr "Vor der Installation nicht auf ausreichenden Plattenplatz prüfen" - -#: share/completions/rpm.fish:30 -msgid "" -"Allow installation or upgrading even if the architectures of the binary " -"package and host don't match" -msgstr "" -"Installation und Aktualisierung auch dann ermöglichen, wenn die " -"Architekturen des Binärpaketes und des Rechners nicht übereinstimmen" - -#: share/completions/rpm.fish:31 -msgid "" -"Allow installation or upgrading even if the operating systems of the binary " -"package and host don't match" -msgstr "" -"Installation und Aktualisierung auch dann ermöglichen, wenn die " -"Betriebssysteme des Binärpaketes und des Rechners nicht übereinstimmen" - -#: share/completions/rpm.fish:32 -msgid "Install documentation files (default)" -msgstr "Dokumentationsdateien installieren (Standard)" - -#: share/completions/rpm.fish:33 -msgid "Update only the database, not the filesystem" -msgstr "Nur die Datenbank, nicht das Dateisystem aktualisieren" - -#: share/completions/rpm.fish:34 share/completions/rpm.fish:94 -msgid "Don't verify package or header digests when reading" -msgstr "Beim Lesen keine Paket- oder Kopfzeilen-Prüfsummen überprüfen" - -#: share/completions/rpm.fish:35 share/completions/rpm.fish:97 -msgid "Don't verify package or header signatures when reading" -msgstr "Beim Lesen keine Paket- oder Kopfzeilen-Signaturen überprüfen" - -#: share/completions/rpm.fish:36 -msgid "Don't do a dependency check" -msgstr "Keine Abhängigkeiten prüfen" - -#: share/completions/rpm.fish:37 -msgid "Don't suggest package(s) that provide a missing dependency" -msgstr "Keine Pakete vorschlagen, die fehlende Abhängigkeiten bereitstellen" - -#: share/completions/rpm.fish:38 -msgid "Don't change the package installation order" -msgstr "Paket-Installationsreihenfolge nicht ändern" - -#: share/completions/rpm.fish:39 -msgid "Don't execute scripts" -msgstr "Keine Skrpte ausführen" - -#: share/completions/rpm.fish:40 -msgid "Don't execute pre scripts" -msgstr "Keine pre-Skripte ausführen" - -#: share/completions/rpm.fish:41 -msgid "Don't execute post scripts" -msgstr "Keine post-Skripte ausführen" - -#: share/completions/rpm.fish:42 -msgid "Don't execute preun scripts" -msgstr "Prerun-Skripte nicht ausführen" - -#: share/completions/rpm.fish:43 -msgid "Don't execute postun scripts" -msgstr "Postrun-Skripte nicht ausführen" - -#: share/completions/rpm.fish:44 share/completions/rpm.fish:115 -msgid "Don't execute trigger scriptlets" -msgstr "Trigger-Skripte nicht ausführen" - -#: share/completions/rpm.fish:45 -msgid "Don't execute triggerin scriptlets" -msgstr "Triggerin-Skripte nicht ausführen" - -#: share/completions/rpm.fish:46 share/completions/rpm.fish:116 -msgid "Don't execute triggerun scriptlets" -msgstr "Triggerun-Skripte nicht ausführen" - -#: share/completions/rpm.fish:47 share/completions/rpm.fish:117 -msgid "Don't execute triggerpostun scriptlets" -msgstr "Triggerpostun-Skripte nicht ausführen" - -#: share/completions/rpm.fish:48 -msgid "Allow an upgrade to replace a newer package with an older one" -msgstr "" -"Erlaube einer Aktualisierung das Ersetzen eines neueren Paketes durch ein " -"älteres" - -#: share/completions/rpm.fish:49 -msgid "" -"Print percentages as files are unpacked from the package archive. This is " -"intended to make rpm easy to run from other tools" -msgstr "" -"Prozentwert ausgeben, während Dateien aus dem Paketarchiv ausgepackt werden. " -"Dies soll das Ausführen von rpm aus anderen Programmen heraus erleichtern" - -#: share/completions/rpm.fish:50 -msgid "" -"For relocatable binary packages, translate all file paths that start with " -"the installation prefix in the package relocation hint(s) to NEWPATH" -msgstr "" -"Für relozierbare Binärpakete alle Dateipfade, die mit dem " -"Installationspräfix im/in den Paket-Relozierungshinweis(en) beginnen, auf " -"den NEUENPFAD konvertieren" - -#: share/completions/rpm.fish:52 share/completions/rpm.fish:118 -msgid "Re-package the files before erasing" -msgstr "Dateien vor dem Löschen umpacken" - -#: share/completions/rpm.fish:53 -msgid "" -"Install the packages even if they replace files from other, already " -"installed, packages" -msgstr "" -"Installiere diese Pakete, selbst wenn sie Dateien aus anderen, bereits " -"installierten Paketen ersetzen" - -#: share/completions/rpm.fish:54 -msgid "" -"Install the packages even if some of them are already installed on this " -"system" -msgstr "" -"Installiere diese Pakete, selbst wenn einige von ihnen auf diesem System " -"bereits installiert sind" - -#: share/completions/rpm.fish:55 -msgid "" -"Don't install the package, simply check for and report potential conflicts" -msgstr "" -"Paket nicht installieren, nur auf mögliche Konflikte testen und diese " -"anzeigen" - -#: share/completions/rpm.fish:59 -msgid "Display change information for the package" -msgstr "Zeigt Änderungsinformationen zu dem Paket an" - -#: share/completions/rpm.fish:60 -msgid "List only configuration files (implies -l)" -msgstr "Zeigt nur Konfigurationsdateien (impliziert -l)" - -#: share/completions/rpm.fish:61 -msgid "List only documentation files (implies -l)" -msgstr "Nur Dokumentationsdateien auflisten (impliziert -l)" - -#: share/completions/rpm.fish:62 -msgid "Dump file information. Must be used with at least one of -l, -c, -d" -msgstr "" -"Gibt Dateiinformationen aus. Muss mit einem von -l, -c, -d benutzt werden" - -#: share/completions/rpm.fish:63 -msgid "List all the files in each selected package" -msgstr "Zeigt alle Dateien in jedem gewählten Paket an" - -#: share/completions/rpm.fish:64 -msgid "" -"Display package information, including name, version, and description. Uses " -"--queryformat if specified" -msgstr "" -"Zeit Paketinformation einschließlich Name, Version und Beschreibung. Benutzt " -"--queryformat falls angegeben" - -#: share/completions/rpm.fish:65 -msgid "Orders the package listing by install time" -msgstr "Ordnet die angezeigten Paketen entsprechend der Installationszeit" - -#: share/completions/rpm.fish:66 -msgid "List files in package" -msgstr "Dateien im Paket auflisten" - -#: share/completions/rpm.fish:67 -msgid "List capabilities this package provides" -msgstr "Eigenschaften auflisten, die dieses Paket bereitstellt" - -#: share/completions/rpm.fish:68 -msgid "List packages on which this package depends" -msgstr "Pakete auflisten, von denen dieses Paket abhängt" - -#: share/completions/rpm.fish:69 -msgid "List the package specific scriptlets" -msgstr "Die Paket-spezifischen Skripte auflisten" - -#: share/completions/rpm.fish:70 -msgid "" -"Display the states of files in the package. The state of each file is one of " -"normal, not installed, or replaced" -msgstr "" -"Zeigt den Status der Dateien im Paket. Status einer jeden Datei ist entweder " -"normal, nicht installiert oder ersetzt" - -#: share/completions/rpm.fish:71 share/completions/rpm.fish:72 -msgid "Display the trigger scripts contained in the package" -msgstr "Die im Paket enthaltenen Auslöser-Skripte anzeigen" - -#: share/completions/rpm.fish:78 -msgid "Query all installed packages" -msgstr "Alle installierten Pakete abfragen" - -#: share/completions/rpm.fish:79 -msgid "Query package owning specified file" -msgstr "Paket abfragen, zu dem die angegebene Datei gehört" - -#: share/completions/rpm.fish:80 -msgid "" -"Query package that contains a given file identifier, i.e. the MD5 digest of " -"the file contents" -msgstr "" -"Frage nach Paketen, die einen gegebenen Datei-Identifikator enthalten, z. B. " -"den MD5-Digest der Dateiinhalte" - -#: share/completions/rpm.fish:81 -msgid "Query packages with the specified group" -msgstr "Pakete mit der angegebenen Gruppe abfragen" - -#: share/completions/rpm.fish:82 -msgid "" -"Query package that contains a given header identifier, i.e. the SHA1 digest " -"of the immutable header region" -msgstr "" -"Frage nach Paketen, die einen gegebenen Kopfzeilen-Bezeichner enthalten, z. " -"B. den SHA1-Digest des unveränderlichen Kopfzeilenbereichs" - -#: share/completions/rpm.fish:83 -msgid "Query an (uninstalled) package in specified file" -msgstr "Ein (deinstalliertes) Paket in der angegebenen Datei abfragen" - -#: share/completions/rpm.fish:84 -msgid "" -"Query package that contains a given package identifier, i.e. the MD5 digest " -"of the combined header and payload contents" -msgstr "" -"Paket abfragen, das einen gegebenen Paket-Bezeichner enthält, z. B. die MD5-" -"Prüfsumme der kombinierten Kopfzeile und des Nutzdateninhaltes" - -#: share/completions/rpm.fish:85 -msgid "Parse and query specified spec-file as if it were a package" -msgstr "Angegebene spec-Datei auswerten, als ob es ein Paket wäre" - -#: share/completions/rpm.fish:86 -msgid "Query package(s) that have the specified TID (transaction identifier)" -msgstr "" -"Paket(e) abfragen, die den angegebenen TID (Transaktions-Bezeichner) besitzen" - -#: share/completions/rpm.fish:87 -msgid "Query packages that are triggered by the specified packages" -msgstr "Pakete abfragen, die von den angegebenen Paketen aktiviert werden" - -#: share/completions/rpm.fish:88 -msgid "Query all packages that provide the specified capability" -msgstr "Alle Pakete abfragen, die die angegebene Eigenschaft bereitstellen" - -#: share/completions/rpm.fish:89 -msgid "" -"Query all packages that requires the specified capability for functioning" -msgstr "" -"Alle Pakete abfragen, die die angegebene Eigenschaft für die " -"Funktionsfähigkeit erfordern" - -#: share/completions/rpm.fish:93 -msgid "Don't verify dependencies of packages" -msgstr "Abhängigkeiten der Pakete nicht prüfen" - -#: share/completions/rpm.fish:95 -msgid "Don't verify any attributes of package files" -msgstr "Keine Attribute der Paketdateien prüfen" - -#: share/completions/rpm.fish:96 -msgid "Don't execute the %verifyscript scriptlet" -msgstr "Das Skript %verifyscript nicht ausführen" - -#: share/completions/rpm.fish:98 -msgid "Don't verify linkto attribute" -msgstr "Verweis(linkto)-Attribute nicht prüfen" - -#: share/completions/rpm.fish:99 -msgid "Don't verify md5 attribute" -msgstr "md5-Attribute nicht prüfen" - -#: share/completions/rpm.fish:100 -msgid "Don't verify size attribute" -msgstr "Grössen-Attribute nicht prüfen" - -#: share/completions/rpm.fish:101 -msgid "Don't verify user attribute" -msgstr "Benutzerattribute nicht überprüfen" - -#: share/completions/rpm.fish:102 -msgid "Don't verify group attribute" -msgstr "Gruppen-Attribute nicht prüfen" - -#: share/completions/rpm.fish:103 -msgid "Don't verify time attribute" -msgstr "Zeit-Attribute nicht prüfen" - -#: share/completions/rpm.fish:104 -msgid "Don't verify mode attribute" -msgstr "Modus-Attribute nicht prüfen" - -#: share/completions/rpm.fish:105 -msgid "Don't verify dev attribute" -msgstr "Geräte-Attribute nicht prüfen" - -#: share/completions/rpm.fish:110 -msgid "Remove all versions of the package which match specified string" -msgstr "Alle Paketversionen entfernen, die der Zeichenkette entsprechen" - -#: share/completions/rpm.fish:111 -msgid "Don't check dependencies before uninstalling the packages" -msgstr "Vor dem Deinstallieren der Pakete keine Abhängigkeiten prüfen" +#~ msgid "Don't check dependencies before uninstalling the packages" +#~ msgstr "Vor dem Deinstallieren der Pakete keine Abhängigkeiten prüfen" -#: share/completions/rpm.fish:112 -msgid "Don't execute scriplets" -msgstr "Skripte nicht ausführen" +#~ msgid "Don't execute scriplets" +#~ msgstr "Skripte nicht ausführen" -#: share/completions/rpm.fish:113 -msgid "Don't execute preun scriptlet" -msgstr "Preun-Skripte nicht ausführen" +#~ msgid "Don't execute preun scriptlet" +#~ msgstr "Preun-Skripte nicht ausführen" -#: share/completions/rpm.fish:114 -msgid "Don't execute postun scriptlet" -msgstr "Postun-Skripte nicht ausführen" +#~ msgid "Don't execute postun scriptlet" +#~ msgstr "Postun-Skripte nicht ausführen" -#: share/completions/rpm.fish:119 -msgid "Don't really uninstall anything" -msgstr "Nicht wirklich deinstallieren" +#~ msgid "Don't really uninstall anything" +#~ msgstr "Nicht wirklich deinstallieren" -#: share/completions/rpm.fish:123 -msgid "Install new package" -msgstr "Neues Paket installieren" +#~ msgid "Install new package" +#~ msgstr "Neues Paket installieren" -#: share/completions/rpm.fish:124 -msgid "Upgrade existing package" -msgstr "Bestehendes Paket aktualisieren" +#~ msgid "Upgrade existing package" +#~ msgstr "Bestehendes Paket aktualisieren" -#: share/completions/rpm.fish:125 -msgid "Upgrade package if already installed" -msgstr "Paket aktualisieren, wenn es bereits installiert ist" +#~ msgid "Upgrade package if already installed" +#~ msgstr "Paket aktualisieren, wenn es bereits installiert ist" -#: share/completions/rpm.fish:126 -msgid "Query installed packages" -msgstr "Installierte Pakete abfragen" +#~ msgid "Query installed packages" +#~ msgstr "Installierte Pakete abfragen" -#: share/completions/rpm.fish:127 #, fuzzy -msgid "Verify package integrity" -msgstr "Paketintegrität verifizieren" - -#: share/completions/rpm.fish:128 -msgid "Erase package" -msgstr "Paket löschen" +#~ msgid "Verify package integrity" +#~ msgstr "Paketintegrität verifizieren" -#: share/completions/rsync.fish:41 -msgid "Force a fixed checksum block-size" -msgstr "" +#~ msgid "Erase package" +#~ msgstr "Paket löschen" -#: share/completions/rsync.fish:42 #, fuzzy -msgid "Specify the remote shell to use" -msgstr "Zeitablauf für Zwischenspeicher angeben" +#~ msgid "Specify the remote shell to use" +#~ msgstr "Zeitablauf für Zwischenspeicher angeben" -#: share/completions/rsync.fish:43 #, fuzzy -msgid "Specify the rsync to run on remote machine" -msgstr "root-Verzeichnis für rpm-Operationen angeben" +#~ msgid "Specify the rsync to run on remote machine" +#~ msgstr "root-Verzeichnis für rpm-Operationen angeben" -#: share/completions/rsync.fish:69 -msgid "Also compare received files relative to DIR" -msgstr "" - -#: share/completions/rsync.fish:70 -msgid "" -"Also compare received files relative to DIR and include copies of unchanged " -"files" -msgstr "" - -#: share/completions/rsync.fish:93 #, fuzzy -msgid "Output filenames using the specified format" -msgstr "Profilierungsinformation in angegebene Datei ausgeben" - -#: share/completions/rsync.fish:94 -msgid "Read password from FILE" -msgstr "" - -#: share/completions/rsync.fish:96 -msgid "Limit I/O bandwidth; KBytes per second" -msgstr "" - -#: share/completions/rsync.fish:97 -msgid "Write a batched update to FILE" -msgstr "" - -#: share/completions/rsync.fish:99 -msgid "Read a batched update from FILE" -msgstr "" - -#: share/completions/rsync.fish:100 -msgid "Force an older protocol version to be used" -msgstr "" +#~ msgid "Output filenames using the specified format" +#~ msgstr "Profilierungsinformation in angegebene Datei ausgeben" -#: share/completions/rsync.fish:101 -msgid "Set block/file checksum seed (advanced)" -msgstr "" +#~ msgid "Require file" +#~ msgstr "Datei erfordern" -#: share/completions/ruby.fish:7 -msgid "Execute command" -msgstr "Befehl ausführen" +#~ msgid "Bandwidth limit" +#~ msgstr "Bandbreitenbegrenzung" -#: share/completions/ruby.fish:15 -msgid "Require file" -msgstr "Datei erfordern" +#~ msgid "Port" +#~ msgstr "Port" -#: share/completions/scp.fish:40 -msgid "Bandwidth limit" -msgstr "Bandbreitenbegrenzung" +#~ msgid "Print a list of running screen sessions" +#~ msgstr "Liste laufender screen-Sitzungen ausgeben" -#: share/completions/scp.fish:41 share/completions/ssh.fish:39 -#: share/completions/sshfs.fish:25 -msgid "Port" -msgstr "Port" +#~ msgid "Evaluate expression" +#~ msgstr "Ausdruck auswerten" -#: share/completions/screen.fish:1 -msgid "Print a list of running screen sessions" -msgstr "Liste laufender screen-Sitzungen ausgeben" +#~ msgid "Evalute file" +#~ msgstr "Datei auswerten" -#: share/completions/sed.fish:13 -msgid "Evaluate expression" -msgstr "Ausdruck auswerten" +#~ msgid "Specify line-length" +#~ msgstr "Zeilenlänge angeben" -#: share/completions/sed.fish:14 -msgid "Evalute file" -msgstr "Datei auswerten" +#~ msgid "Color" +#~ msgstr "Farbe" -#: share/completions/sed.fish:22 -msgid "Specify line-length" -msgstr "Zeilenlänge angeben" +#~ msgid "Change background color" +#~ msgstr "Hintergrundfarbe ändern" -#: share/completions/set.fish:73 share/completions/set_color.fish:1 -msgid "Color" -msgstr "Farbe" +#~ msgid "Locale" +#~ msgstr "Locale" -#: share/completions/set.fish:74 share/completions/set_color.fish:2 -msgid "Change background color" -msgstr "Hintergrundfarbe ändern" +#~ msgid "Write to file" +#~ msgstr "In Datei schreiben" -#: share/completions/set.fish:79 -msgid "Locale" -msgstr "Locale" +#~ msgid "Set memory buffer size" +#~ msgstr "Speicherpuffergröße festlegen" -#: share/completions/sort.fish:16 -msgid "Write to file" -msgstr "In Datei schreiben" +#~ msgid "Set temporary directory" +#~ msgstr "Temporäres Verzeichnis festlegen" -#: share/completions/sort.fish:18 -msgid "Set memory buffer size" -msgstr "Speicherpuffergröße festlegen" +#~ msgid "Interface to transmit from" +#~ msgstr "Schnittstelle zur Übertragung" -#: share/completions/sort.fish:20 -msgid "Set temporary directory" -msgstr "Temporäres Verzeichnis festlegen" +#~ msgid "Escape character" +#~ msgstr "Escape-Zeichen" -#: share/completions/ssh.fish:24 -msgid "Interface to transmit from" -msgstr "Schnittstelle zur Übertragung" +#~ msgid "User" +#~ msgstr "Benutzer" -#: share/completions/ssh.fish:30 -msgid "Escape character" -msgstr "Escape-Zeichen" +#~ msgid "Pass command to shell" +#~ msgstr "Befehl an die Shell übergeben" -#: share/completions/ssh.fish:35 -msgid "User" -msgstr "Benutzer" - -#: share/completions/su.fish:5 -msgid "Pass command to shell" -msgstr "Befehl an die Shell übergeben" - -#: share/completions/sylpheed.fish:8 -msgid "Open composition window with address" -msgstr "" - -#: share/completions/sylpheed.fish:9 -msgid "Open composition window with attached files" -msgstr "" - -#: share/completions/sylpheed.fish:10 -msgid "Receive new messages" -msgstr "" - -#: share/completions/sylpheed.fish:11 -msgid "Receive new messages of all accounts" -msgstr "" - -#: share/completions/sylpheed.fish:12 -msgid "Send all queued messages" -msgstr "" - -#: share/completions/sylpheed.fish:13 -msgid "Show the total number of messages for folder" -msgstr "" - -#: share/completions/sylpheed.fish:14 -msgid "Show the total number of messages for each folder" -msgstr "" - -#: share/completions/sylpheed.fish:15 #, fuzzy -msgid "Specify directory with configuration files" -msgstr "Eine Konfigurationsdatei angeben" +#~ msgid "Specify directory with configuration files" +#~ msgstr "Eine Konfigurationsdatei angeben" -#: share/completions/tar.fish:19 share/functions/cd.fish:5 -msgid "Change directory" -msgstr "Verzeichnis wechseln" +#~ msgid "Change directory" +#~ msgstr "Verzeichnis wechseln" -#: share/completions/tar.fish:21 -msgid "Archive file" -msgstr "Archiv-Datei" +#~ msgid "Archive file" +#~ msgstr "Archiv-Datei" -#: share/completions/tar.fish:31 -msgid "Starting file in archive" -msgstr "Startdatei im Archiv" +#~ msgid "Starting file in archive" +#~ msgstr "Startdatei im Archiv" -#: share/completions/tar.fish:33 -msgid "Tape length" -msgstr "Band-Länge" +#~ msgid "Tape length" +#~ msgstr "Band-Länge" -#: share/completions/tar.fish:36 -msgid "Only store newer files" -msgstr "Nur neuere Dateien speichern" +#~ msgid "Only store newer files" +#~ msgstr "Nur neuere Dateien speichern" -#: share/completions/tar.fish:50 -msgid "Extract file from file" -msgstr "Datei aus Datei extrahieren" +#~ msgid "Extract file from file" +#~ msgstr "Datei aus Datei extrahieren" -#: share/completions/tar.fish:54 -msgid "Set volume name" -msgstr "Volume-Namen festlegen" +#~ msgid "Set volume name" +#~ msgstr "Volume-Namen festlegen" -#: share/completions/tar.fish:59 -msgid "Exclude file" -msgstr "Datei ausschliessen" +#~ msgid "Exclude file" +#~ msgstr "Datei ausschliessen" -#: share/completions/tar.fish:60 -msgid "Exclude files listed in specified file" -msgstr "die in der angegebenen Datei aufgeführten Dateien ausschliessen" +#~ msgid "Exclude files listed in specified file" +#~ msgstr "die in der angegebenen Datei aufgeführten Dateien ausschliessen" -#: share/completions/tar.fish:65 -msgid "Filter through specified program" -msgstr "durch angegebenes Programm filtern" +#~ msgid "Filter through specified program" +#~ msgstr "durch angegebenes Programm filtern" -#: share/completions/telnet.fish:9 share/completions/telnet.fish:14 #, fuzzy -msgid "Specifies an 8-bit data path" -msgstr "Man-Pfad angeben" - -#: share/completions/telnet.fish:10 -msgid "Do not try to negotiate TELNET BINARY option" -msgstr "" - -#: share/completions/telnet.fish:11 -msgid "Stops any character from being recognized as an escape character" -msgstr "" - -#: share/completions/telnet.fish:12 -msgid "Use local Kerberos authentication, if possible" -msgstr "" +#~ msgid "Specifies an 8-bit data path" +#~ msgstr "Man-Pfad angeben" -#: share/completions/telnet.fish:13 -msgid "Specifies no automatic login to remote system" -msgstr "" - -#: share/completions/telnet.fish:15 -msgid "Attempt automatic login" -msgstr "" - -#: share/completions/telnet.fish:16 #, fuzzy -msgid "Disables reading user's .telnetrc" -msgstr "Weiterleitung von Kerberos-Tickets deaktivieren" +#~ msgid "Disables reading user's .telnetrc" +#~ msgstr "Weiterleitung von Kerberos-Tickets deaktivieren" -#: share/completions/telnet.fish:17 #, fuzzy -msgid "Sets debug mode" -msgstr "Debug-Grad festlegen" - -#: share/completions/telnet.fish:18 -msgid "Sets IP TOS" -msgstr "" +#~ msgid "Sets debug mode" +#~ msgstr "Debug-Grad festlegen" -#: share/completions/telnet.fish:19 #, fuzzy -msgid "Disables specified type of authentication" -msgstr "Deaktiviert Weiterleitung des Authentifizierungs-Agenten" +#~ msgid "Disables specified type of authentication" +#~ msgstr "Deaktiviert Weiterleitung des Authentifizierungs-Agenten" -#: share/completions/telnet.fish:20 #, fuzzy -msgid "User login" -msgstr "Benutzer-Startverzeichnis" +#~ msgid "User login" +#~ msgstr "Benutzer-Startverzeichnis" -#: share/completions/telnet.fish:21 #, fuzzy -msgid "Log to tracefile" -msgstr "Log in Datei schreiben" +#~ msgid "Log to tracefile" +#~ msgstr "Log in Datei schreiben" -#: share/completions/telnet.fish:22 #, fuzzy -msgid "Turn on encryption" -msgstr "Funktionsbeschreibung festlegen" +#~ msgid "Turn on encryption" +#~ msgstr "Funktionsbeschreibung festlegen" -#: share/completions/telnet.fish:23 -msgid "User interface similar to rlogin" -msgstr "" - -#: share/completions/telnet.fish:24 -msgid "Use Kerberos realm for authentication" -msgstr "" - -#: share/completions/tmux.fish:1 #, fuzzy -msgid "available sessions" -msgstr "Ausdruck auswerten" +#~ msgid "available sessions" +#~ msgstr "Ausdruck auswerten" -#: share/completions/tmux.fish:5 -msgid "connected clients" -msgstr "" - -#: share/completions/tmux.fish:9 #, fuzzy -msgid "window panes" -msgstr "Änderung der Fenstergröße" - -#: share/completions/totem.fish:18 -msgid "Tell any running totem instance: Add to playlist" -msgstr "" +#~ msgid "window panes" +#~ msgstr "Änderung der Fenstergröße" -#: share/completions/totem.fish:19 -msgid "Tell any running totem instance: Play from playlist" -msgstr "" +#~ msgid "Set date back" +#~ msgstr "Datum zurücksetzen" -#: share/completions/touch.fish:2 -msgid "Set date back" -msgstr "Datum zurücksetzen" +#~ msgid "Set date" +#~ msgstr "Datum festlegen" -#: share/completions/touch.fish:4 -msgid "Set date" -msgstr "Datum festlegen" +#~ msgid "Set date forward" +#~ msgstr "Datum in Zukunft festlegen" -#: share/completions/touch.fish:5 -msgid "Set date forward" -msgstr "Datum in Zukunft festlegen" +#~ msgid "Set time" +#~ msgstr "Zeit festlegen" -#: share/completions/touch.fish:9 -msgid "Set time" -msgstr "Zeit festlegen" - -#: share/completions/unrar.fish:5 #, fuzzy -msgid "Extract files to current directory" -msgstr "Dateien unter jedem Verzeichnis lesen" +#~ msgid "Extract files to current directory" +#~ msgstr "Dateien unter jedem Verzeichnis lesen" -#: share/completions/unrar.fish:6 -msgid "List archive" -msgstr "Archiv auflisten" +#~ msgid "List archive" +#~ msgstr "Archiv auflisten" -#: share/completions/unrar.fish:7 #, fuzzy -msgid "List archive (technical)" -msgstr "Archiv auflisten" +#~ msgid "List archive (technical)" +#~ msgstr "Archiv auflisten" -#: share/completions/unrar.fish:8 #, fuzzy -msgid "List archive (bare)" -msgstr "Archiv auflisten" +#~ msgid "List archive (bare)" +#~ msgstr "Archiv auflisten" -#: share/completions/unrar.fish:9 #, fuzzy -msgid "Print file to stdout" -msgstr "Zeit des letzten Neustarts anzeigen" +#~ msgid "Print file to stdout" +#~ msgstr "Zeit des letzten Neustarts anzeigen" -#: share/completions/unrar.fish:10 #, fuzzy -msgid "Test archive files" -msgstr "Archiv-Datei" +#~ msgid "Test archive files" +#~ msgstr "Archiv-Datei" -#: share/completions/unrar.fish:11 #, fuzzy -msgid "Verbosely list archive" -msgstr "Archiv prüfen" - -#: share/completions/unrar.fish:12 -msgid "Verbosely list archive (technical)" -msgstr "" +#~ msgid "Verbosely list archive" +#~ msgstr "Archiv prüfen" -#: share/completions/unrar.fish:13 -msgid "Verbosely list archive (bare)" -msgstr "" - -#: share/completions/unrar.fish:14 #, fuzzy -msgid "Extract files with full path" -msgstr "Datei aus Datei extrahieren" - -#: share/completions/update-eix-remote.fish:16 -msgid "" -"Fetch the eix-caches of some layman overlays into a temporary file resp. " -"into FILE and add them to the eix database" -msgstr "" +#~ msgid "Extract files with full path" +#~ msgstr "Datei aus Datei extrahieren" -#: share/completions/update-eix-remote.fish:16 -msgid "Only fetch the overlays into FILE" -msgstr "" - -#: share/completions/update-eix-remote.fish:16 -msgid "Only add the overlays from FILE to the eix database" -msgstr "" - -#: share/completions/update-eix-remote.fish:16 -msgid "Remove all temporarily added virtual overlays from the eix database" -msgstr "" - -#: share/completions/vagrant.fish:3 #, fuzzy -msgid "Test if vagrant has yet to be given the main command" -msgstr "Test, ob an apt noch ein Unterbefehl gegeben werden muss" +#~ msgid "Test if vagrant has yet to be given the main command" +#~ msgstr "Test, ob an apt noch ein Unterbefehl gegeben werden muss" -#: share/completions/vagrant.fish:23 #, fuzzy -msgid "Lists all available Vagrant boxes" -msgstr "Namen der verfügbaren Signale auflisten" +#~ msgid "Lists all available Vagrant boxes" +#~ msgstr "Namen der verfügbaren Signale auflisten" -#: share/completions/valgrind.fish:12 -msgid "Skin" -msgstr "Oberfläche" +#~ msgid "Skin" +#~ msgstr "Oberfläche" -#: share/completions/valgrind.fish:78 -msgid "The number of bytes of heap overhead per allocation" -msgstr "Anzahl Bytes als Heap-Mehrverbrauch pro Zuordnung " +#~ msgid "The number of bytes of heap overhead per allocation" +#~ msgstr "Anzahl Bytes als Heap-Mehrverbrauch pro Zuordnung " -#: share/completions/valgrind.fish:79 -msgid "Profile stack usage" -msgstr "Profilstackauslastung" +#~ msgid "Profile stack usage" +#~ msgstr "Profilstackauslastung" -#: share/completions/valgrind.fish:80 -msgid "Depth of call chain" -msgstr "Tiefe der Aufrufkette" +#~ msgid "Depth of call chain" +#~ msgstr "Tiefe der Aufrufkette" -#: share/completions/valgrind.fish:81 -msgid "Profiling output format" -msgstr "Ausgabeformat für Profilierung" +#~ msgid "Profiling output format" +#~ msgstr "Ausgabeformat für Profilierung" -#: share/completions/vim-addons.fish:8 #, fuzzy -msgid "Test if vim-addons has yet to be given the subcommand" -msgstr "Test, ob an apt noch ein Unterbefehl gegeben werden muss" +#~ msgid "Test if vim-addons has yet to be given the subcommand" +#~ msgstr "Test, ob an apt noch ein Unterbefehl gegeben werden muss" -#: share/completions/w.fish:6 -msgid "Username" -msgstr "Benutzername" +#~ msgid "Username" +#~ msgstr "Benutzername" -#: share/completions/wajig.fish:1 #, fuzzy -msgid "Test if wajig has yet to be given the subcommand" -msgstr "Test, ob an apt noch ein Unterbefehl gegeben werden muss" +#~ msgid "Test if wajig has yet to be given the subcommand" +#~ msgstr "Test, ob an apt noch ein Unterbefehl gegeben werden muss" -#: share/completions/wajig.fish:10 #, fuzzy -msgid "Test if wajig command should have packages as potential completion" -msgstr "" -"Testen, ob der apt-Befehl Pakete zur möglichen Fertigstellung haben sollte" +#~ msgid "Test if wajig command should have packages as potential completion" +#~ msgstr "" +#~ "Testen, ob der apt-Befehl Pakete zur möglichen Fertigstellung haben sollte" -#: share/completions/wajig.fish:97 #, fuzzy -msgid "Download package and any packages it depends on" -msgstr "Pakete auflisten, von denen dieses Paket abhängt" - -#: share/completions/wajig.fish:98 -msgid "Install package and associated recommended packages" -msgstr "" +#~ msgid "Download package and any packages it depends on" +#~ msgstr "Pakete auflisten, von denen dieses Paket abhängt" -#: share/completions/wajig.fish:99 -msgid "Reconfigure the named installed packages or run gkdebconf" -msgstr "" - -#: share/completions/wajig.fish:100 #, fuzzy -msgid "Reinstall each of the named packages" -msgstr "Ein oder mehrere Paket(e) installieren" - -#: share/completions/wajig.fish:101 -msgid "Reload daemon configs, e.g., gdm, apache (see list-daemons)" -msgstr "" +#~ msgid "Reinstall each of the named packages" +#~ msgstr "Ein oder mehrere Paket(e) installieren" -#: share/completions/wajig.fish:102 #, fuzzy -msgid "Remove one or more packages (see also purge)" -msgstr "Ein oder mehrere Paket(e) entfernen" - -#: share/completions/wajig.fish:103 -msgid "Remove package and its dependees not required by others" -msgstr "" +#~ msgid "Remove one or more packages (see also purge)" +#~ msgstr "Ein oder mehrere Paket(e) entfernen" -#: share/completions/wajig.fish:104 -msgid "Remove orphaned libraries (not required by installed packages)" -msgstr "" - -#: share/completions/wajig.fish:105 #, fuzzy -msgid "Generate a .deb file for an installed package" -msgstr "Ein installiertes Paket neu erstellen und installieren" - -#: share/completions/wajig.fish:106 -msgid "Initialise or reset the JIG archive files" -msgstr "" +#~ msgid "Generate a .deb file for an installed package" +#~ msgstr "Ein installiertes Paket neu erstellen und installieren" -#: share/completions/wajig.fish:107 -msgid "Stop then start a daemon, e.g., gdm, apache (see list-daemons)" -msgstr "" - -#: share/completions/wajig.fish:108 #, fuzzy -msgid "Install a RedHat .rpm package" -msgstr "Neues Paket installieren" - -#: share/completions/wajig.fish:109 -msgid "Convert a RedHat .rpm file to a Debian .deb file" -msgstr "" +#~ msgid "Install a RedHat .rpm package" +#~ msgstr "Neues Paket installieren" -#: share/completions/wajig.fish:110 #, fuzzy -msgid "Search for packages containing listed words" -msgstr "Paket entsprechend Muster suchen" - -#: share/completions/wajig.fish:111 -msgid "Find local Debian archives suitable for sources.list" -msgstr "" - -#: share/completions/wajig.fish:112 -msgid "Configure the sources.list file which locates Debian archives" -msgstr "" - -#: share/completions/wajig.fish:113 -msgid "Provide a detailed description of package [same as detail]" -msgstr "" - -#: share/completions/wajig.fish:114 -msgid "Trace the steps that a dist-upgrade would perform" -msgstr "" +#~ msgid "Search for packages containing listed words" +#~ msgstr "Paket entsprechend Muster suchen" -#: share/completions/wajig.fish:115 -msgid "Trace the steps that an install would perform" -msgstr "" - -#: share/completions/wajig.fish:116 -msgid "Trace the steps that a remove would perform" -msgstr "" - -#: share/completions/wajig.fish:117 -msgid "Trace the steps that an upgrade would perform" -msgstr "" - -#: share/completions/wajig.fish:118 share/completions/wajig.fish:119 -msgid "Print out the size (in K) of all, or listed, installed packages" -msgstr "" - -#: share/completions/wajig.fish:120 -msgid "Generates list of package=version for all installed packages" -msgstr "" - -#: share/completions/wajig.fish:121 #, fuzzy -msgid "Retrieve and unpack sources for the named packages" -msgstr "Umgekehrte Abhängigkeiten für das Paket auflisten" - -#: share/completions/wajig.fish:122 -msgid "Start a daemon, e.g., gdm, apache (see list-daemons)" -msgstr "" +#~ msgid "Retrieve and unpack sources for the named packages" +#~ msgstr "Umgekehrte Abhängigkeiten für das Paket auflisten" -#: share/completions/wajig.fish:123 #, fuzzy -msgid "Show the version and available version of packages" -msgstr "Volle Versionen der Pakete anzeigen" - -#: share/completions/wajig.fish:124 share/completions/wajig.fish:125 -msgid "Show the version and available version of matching packages" -msgstr "" +#~ msgid "Show the version and available version of packages" +#~ msgstr "Volle Versionen der Pakete anzeigen" -#: share/completions/wajig.fish:126 -msgid "Stop a daemon, e.g., gdm, apache (see list-daemons)" -msgstr "" - -#: share/completions/wajig.fish:127 -msgid "Install package and associated suggested packages" -msgstr "" - -#: share/completions/wajig.fish:128 -msgid "Run the Gnome task selector to install groups of packages" -msgstr "" - -#: share/completions/wajig.fish:129 -msgid "List packages with newer versions available for upgrading" -msgstr "" - -#: share/completions/wajig.fish:130 -msgid "Remove listed packages from hold so they are again upgraded" -msgstr "" - -#: share/completions/wajig.fish:131 -msgid "Search for an unofficial Debian package at apt-get.org" -msgstr "" - -#: share/completions/wajig.fish:132 #, fuzzy -msgid "Update the list of down-loadable packages" -msgstr "Liste der Quellpakete aktualisieren" - -#: share/completions/wajig.fish:133 -msgid "Update default alternative for things like x-window-manager" -msgstr "" - -#: share/completions/wajig.fish:134 -msgid "Updates the local list of PCI ids from the internet master list" -msgstr "" +#~ msgid "Update the list of down-loadable packages" +#~ msgstr "Liste der Quellpakete aktualisieren" -#: share/completions/wajig.fish:135 -msgid "Updates the local list of USB ids from the internet master list" -msgstr "" - -#: share/completions/wajig.fish:136 -msgid "Upgrade all of the installed packages or just those listed" -msgstr "" - -#: share/completions/wajig.fish:137 #, fuzzy -msgid "List version and distribution of (all) packages." -msgstr "Keine Attribute der Paketdateien prüfen" +#~ msgid "List version and distribution of (all) packages." +#~ msgstr "Keine Attribute der Paketdateien prüfen" -#: share/completions/wajig.fish:138 #, fuzzy -msgid "A synonym for describe" -msgstr "Synonym für -i" - -#: share/completions/wajig.fish:139 -msgid "Find the package that supplies the given command or file" -msgstr "" - -#: share/completions/wpa_cli.fish:3 -msgid "get current WPA/EAPOL/EAP status" -msgstr "" +#~ msgid "A synonym for describe" +#~ msgstr "Synonym für -i" -#: share/completions/wpa_cli.fish:4 -msgid "get MIB variables (dot1x, dot11)" -msgstr "" - -#: share/completions/wpa_cli.fish:5 -msgid "show this usage help" -msgstr "" - -#: share/completions/wpa_cli.fish:6 #, fuzzy -msgid "show interfaces/select interface" -msgstr "Schnittstelle auswählen" +#~ msgid "show interfaces/select interface" +#~ msgstr "Schnittstelle auswählen" -#: share/completions/wpa_cli.fish:7 #, fuzzy -msgid "change debug level" -msgstr "Debug-Grad festlegen" - -#: share/completions/wpa_cli.fish:8 -msgid "show full wpa_cli license" -msgstr "" +#~ msgid "change debug level" +#~ msgstr "Debug-Grad festlegen" -#: share/completions/wpa_cli.fish:9 -msgid "IEEE 802.1X EAPOL state machine logoff" -msgstr "" - -#: share/completions/wpa_cli.fish:10 -msgid "IEEE 802.1X EAPOL state machine logon" -msgstr "" - -#: share/completions/wpa_cli.fish:11 #, fuzzy -msgid "set/list variables" -msgstr "Variable löschen" +#~ msgid "set/list variables" +#~ msgstr "Variable löschen" -#: share/completions/wpa_cli.fish:12 -msgid "show PMKSA cache" -msgstr "" - -#: share/completions/wpa_cli.fish:13 #, fuzzy -msgid "force reassociation" -msgstr "Simulation durchführen" - -#: share/completions/wpa_cli.fish:14 -msgid "force wpa_supplicant to re-read its config file" -msgstr "" +#~ msgid "force reassociation" +#~ msgstr "Simulation durchführen" -#: share/completions/wpa_cli.fish:15 #, fuzzy -msgid "force preauthentication" -msgstr "Pseudo-tty-Zuordnung erzwingen" +#~ msgid "force preauthentication" +#~ msgstr "Pseudo-tty-Zuordnung erzwingen" -#: share/completions/wpa_cli.fish:16 -msgid "configure identity for an SSID" -msgstr "" - -#: share/completions/wpa_cli.fish:17 -msgid "configure password for an SSID" -msgstr "" - -#: share/completions/wpa_cli.fish:18 -msgid "change password for an SSID" -msgstr "" - -#: share/completions/wpa_cli.fish:19 #, fuzzy -msgid "configure pin for an SSID" -msgstr "Konfiguration für das Erstellen auf BUILD" - -#: share/completions/wpa_cli.fish:20 -msgid "configure one-time-password for an SSID" -msgstr "" +#~ msgid "configure pin for an SSID" +#~ msgstr "Konfiguration für das Erstellen auf BUILD" -#: share/completions/wpa_cli.fish:21 -msgid "configure private key passphrase for an SSID" -msgstr "" - -#: share/completions/wpa_cli.fish:22 -msgid "set preferred BSSID for an SSID" -msgstr "" - -#: share/completions/wpa_cli.fish:23 -msgid "list configured networks" -msgstr "" - -#: share/completions/wpa_cli.fish:24 -msgid "select a network (disable others)" -msgstr "" - -#: share/completions/wpa_cli.fish:25 #, fuzzy -msgid "enable a network" -msgstr "Depot aktivieren" +#~ msgid "enable a network" +#~ msgstr "Depot aktivieren" -#: share/completions/wpa_cli.fish:26 #, fuzzy -msgid "disable a network" -msgstr "Depot deaktivieren" +#~ msgid "disable a network" +#~ msgstr "Depot deaktivieren" -#: share/completions/wpa_cli.fish:27 #, fuzzy -msgid "add a network" -msgstr "Neuen Schlüssel hinzufügen" +#~ msgid "add a network" +#~ msgstr "Neuen Schlüssel hinzufügen" -#: share/completions/wpa_cli.fish:28 #, fuzzy -msgid "remove a network" -msgstr "Schlüssel entfernen" +#~ msgid "remove a network" +#~ msgstr "Schlüssel entfernen" -#: share/completions/wpa_cli.fish:29 -msgid "set/list network variables" -msgstr "" - -#: share/completions/wpa_cli.fish:30 #, fuzzy -msgid "get network variables" -msgstr "CVS-Benutzervariable festlegen" +#~ msgid "get network variables" +#~ msgstr "CVS-Benutzervariable festlegen" -#: share/completions/wpa_cli.fish:31 #, fuzzy -msgid "save the current configuration" -msgstr "Dienstkonfiguration neu laden" - -#: share/completions/wpa_cli.fish:32 -msgid "disconnect and wait for reassociate command before connecting" -msgstr "" - -#: share/completions/wpa_cli.fish:33 -msgid "request new BSS scan" -msgstr "" +#~ msgid "save the current configuration" +#~ msgstr "Dienstkonfiguration neu laden" -#: share/completions/wpa_cli.fish:34 -msgid "get latest scan results" -msgstr "" +#~ msgid "Select window by id" +#~ msgstr "Fenster über Kennung auswählen" -#: share/completions/wpa_cli.fish:35 -msgid "get capabilies" -msgstr "" +#~ msgid "Display font properties" +#~ msgstr "Zeichensatzeigenschaften anzeigen" -#: share/completions/wpa_cli.fish:36 -msgid "request STAKey negotiation with " -msgstr "" +#~ msgid "Maximum display length" +#~ msgstr "Maximale Anzeigelänge" -#: share/completions/wpa_cli.fish:37 -msgid "set ap_scan parameter" -msgstr "" +#~ msgid "Set format file" +#~ msgstr "Formatdatei festlegen" -#: share/completions/wpa_cli.fish:38 -msgid "request STK negotiation with " -msgstr "" +#~ msgid "X server display" +#~ msgstr "X Server-Anzeige" -#: share/completions/wpa_cli.fish:39 -msgid "terminate wpa_supplicant" -msgstr "" +#~ msgid "Error log" +#~ msgstr "Fehler-Protokolldatei" -#: share/completions/xprop.fish:4 -msgid "Select window by id" -msgstr "Fenster über Kennung auswählen" - -#: share/completions/xprop.fish:6 -msgid "Display font properties" -msgstr "Zeichensatzeigenschaften anzeigen" - -#: share/completions/xprop.fish:9 -msgid "Maximum display length" -msgstr "Maximale Anzeigelänge" - -#: share/completions/xprop.fish:11 -msgid "Set format file" -msgstr "Formatdatei festlegen" - -#: share/completions/xsel.fish:12 -msgid "X server display" -msgstr "X Server-Anzeige" - -#: share/completions/xsel.fish:14 -msgid "Error log" -msgstr "Fehler-Protokolldatei" - -#: share/completions/xterm.fish:101 -msgid "Run program in xterm" -msgstr "" - -#: share/completions/xterm.fish:103 -msgid "Blinking cursor will be off for that many milliseconds" -msgstr "" - -#: share/completions/xterm.fish:104 -msgid "Blinking cursor will be on for that many milliseconds" -msgstr "" - -#: share/completions/xterm.fish:105 -msgid "Override xterm resource class" -msgstr "" - -#: share/completions/xterm.fish:106 -msgid "Color for the text cursor" -msgstr "" - -#: share/completions/xterm.fish:107 -msgid "xterm encoding" -msgstr "" - -#: share/completions/xterm.fish:108 -msgid "Bold font" -msgstr "" - -#: share/completions/xterm.fish:109 -msgid "FreeType font pattern" -msgstr "" - -#: share/completions/xterm.fish:110 -msgid "FreeType double-width font pattern" -msgstr "" - -#: share/completions/xterm.fish:111 #, fuzzy -msgid "Font for active icons" -msgstr "Interaktiven Modus erzwingen" +#~ msgid "Font for active icons" +#~ msgstr "Interaktiven Modus erzwingen" -#: share/completions/xterm.fish:112 -msgid "Font size for FreeType font" -msgstr "" - -#: share/completions/xterm.fish:113 -msgid "Font for displaying wide text" -msgstr "" - -#: share/completions/xterm.fish:114 -msgid "Font for displaying bold wide text" -msgstr "" - -#: share/completions/xterm.fish:115 -msgid "Font for the preedit string in \"OverTheSpot\"" -msgstr "" - -#: share/completions/xterm.fish:116 -msgid "Color for highlighted text" -msgstr "" - -#: share/completions/xterm.fish:117 -msgid "Embed xterm into window" -msgstr "" - -#: share/completions/xterm.fish:118 -msgid "Set keyboard type" -msgstr "" - -#: share/completions/xterm.fish:119 -msgid "File name for the encoding converter" -msgstr "" - -#: share/completions/xterm.fish:120 #, fuzzy -msgid "Log filename" -msgstr "Log in Datei schreiben" - -#: share/completions/xterm.fish:121 -msgid "Maximum time in milliseconds between multi-click selections" -msgstr "" - -#: share/completions/xterm.fish:122 -msgid "Color for the pointer cursor" -msgstr "" - -#: share/completions/xterm.fish:123 -msgid "Distance from the right end for ringing the margin bell" -msgstr "" +#~ msgid "Log filename" +#~ msgstr "Log in Datei schreiben" -#: share/completions/xterm.fish:124 #, fuzzy -msgid "Number of scrolled off lines" -msgstr "Alle Zeilen nummerieren" +#~ msgid "Number of scrolled off lines" +#~ msgstr "Alle Zeilen nummerieren" -#: share/completions/xterm.fish:125 #, fuzzy -msgid "Terminal identification" -msgstr "Alle Informationen ausgeben" +#~ msgid "Terminal identification" +#~ msgstr "Alle Informationen ausgeben" -#: share/completions/xterm.fish:126 -#, sh-format -msgid "Terminal name for $TERM" -msgstr "" - -#: share/completions/xterm.fish:127 #, fuzzy -msgid "zIconBeep percentage" -msgstr "Prompt mit Prozentanzeige" - -#: share/completions/xterm.fish:129 -msgid "Size of the inner border" -msgstr "" +#~ msgid "zIconBeep percentage" +#~ msgstr "Prompt mit Prozentanzeige" -#: share/completions/yum.fish:53 #, fuzzy -msgid "Delete cached package files" -msgstr "Veraltete Paketdateien löschen" +#~ msgid "Delete cached package files" +#~ msgstr "Veraltete Paketdateien löschen" -#: share/completions/yum.fish:54 #, fuzzy -msgid "Delete cached header files" -msgstr "Veraltete Paketdateien löschen" +#~ msgid "Delete cached header files" +#~ msgstr "Veraltete Paketdateien löschen" -#: share/completions/yum.fish:55 #, fuzzy -msgid "Delete all cache contents" -msgstr "Nach Fertigstellung Logdatei löschen" +#~ msgid "Delete all cache contents" +#~ msgstr "Nach Fertigstellung Logdatei löschen" -#: share/completions/zip.fish:19 -msgid "Exclude the following names" -msgstr "Folgende Namen ausschliessen" +#~ msgid "Exclude the following names" +#~ msgstr "Folgende Namen ausschliessen" -#: share/completions/zip.fish:20 -msgid "Include only the following names" -msgstr "Nur die folgenden Namen einschliessen" +#~ msgid "Include only the following names" +#~ msgstr "Nur die folgenden Namen einschliessen" -#: share/completions/zip.fish:30 -msgid "Don't compress files with these suffixes" -msgstr "Dateien mit diesen Endungen nicht komprimieren" +#~ msgid "Don't compress files with these suffixes" +#~ msgstr "Dateien mit diesen Endungen nicht komprimieren" -#: share/completions/zypper.fish:30 #, fuzzy -msgid "Print help" -msgstr "URIs ausgeben" - -#: share/completions/zypper.fish:31 -msgid "Accept multiple commands at once" -msgstr "" +#~ msgid "Print help" +#~ msgstr "URIs ausgeben" -#: share/completions/zypper.fish:32 #, fuzzy -msgid "List all defined repositories" -msgstr "Depot deaktivieren" +#~ msgid "List all defined repositories" +#~ msgstr "Depot deaktivieren" -#: share/completions/zypper.fish:33 #, fuzzy -msgid "Add a new repository" -msgstr "Paketdepot aktualisieren" +#~ msgid "Add a new repository" +#~ msgstr "Paketdepot aktualisieren" -#: share/completions/zypper.fish:34 #, fuzzy -msgid "Remove specified repository" -msgstr "Einen Eintrag aus dem Paketdepot entfernen" +#~ msgid "Remove specified repository" +#~ msgstr "Einen Eintrag aus dem Paketdepot entfernen" -#: share/completions/zypper.fish:35 #, fuzzy -msgid "Rename specified repository" -msgstr "Defektes Paketdepot reparieren" +#~ msgid "Rename specified repository" +#~ msgstr "Defektes Paketdepot reparieren" -#: share/completions/zypper.fish:36 #, fuzzy -msgid "Modify specified repository" -msgstr "Depot deaktivieren" +#~ msgid "Modify specified repository" +#~ msgstr "Depot deaktivieren" -#: share/completions/zypper.fish:37 #, fuzzy -msgid "Refresh all repositories" -msgstr "Depot deaktivieren" +#~ msgid "Refresh all repositories" +#~ msgstr "Depot deaktivieren" -#: share/completions/zypper.fish:38 #, fuzzy -msgid "Clean local caches" -msgstr "Lokalen Zwischenspeicher und Pakete bereinigen" +#~ msgid "Clean local caches" +#~ msgstr "Lokalen Zwischenspeicher und Pakete bereinigen" -#: share/completions/zypper.fish:39 -msgid "List all defined services" -msgstr "" - -#: share/completions/zypper.fish:40 #, fuzzy -msgid "Add a new service" -msgstr "Neuen Schlüssel hinzufügen" +#~ msgid "Add a new service" +#~ msgstr "Neuen Schlüssel hinzufügen" -#: share/completions/zypper.fish:41 #, fuzzy -msgid "Modify specified service" -msgstr "Angegebenen Schlüsselserver verwenden" +#~ msgid "Modify specified service" +#~ msgstr "Angegebenen Schlüsselserver verwenden" -#: share/completions/zypper.fish:42 #, fuzzy -msgid "Remove specified service" -msgstr "Angegebenen Schlüsselserver verwenden" - -#: share/completions/zypper.fish:43 -msgid "Refresh all services" -msgstr "" +#~ msgid "Remove specified service" +#~ msgstr "Angegebenen Schlüsselserver verwenden" -#: share/completions/zypper.fish:44 #, fuzzy -msgid "Install packages" -msgstr "Pakete erneut installieren" +#~ msgid "Install packages" +#~ msgstr "Pakete erneut installieren" -#: share/completions/zypper.fish:46 #, fuzzy -msgid "Verify integrity of package dependencies" -msgstr "Pakete für Abhängigkeiten installieren/entfernen" +#~ msgid "Verify integrity of package dependencies" +#~ msgstr "Pakete für Abhängigkeiten installieren/entfernen" -#: share/completions/zypper.fish:47 #, fuzzy -msgid "Install source packages and their build dependencies" -msgstr "Pakete für Abhängigkeiten installieren/entfernen" +#~ msgid "Install source packages and their build dependencies" +#~ msgstr "Pakete für Abhängigkeiten installieren/entfernen" -#: share/completions/zypper.fish:48 #, fuzzy -msgid "Install newly added packages recommended by installed packages" -msgstr "" -"Installiere diese Pakete, selbst wenn sie Dateien aus anderen, bereits " -"installierten Paketen ersetzen" +#~ msgid "Install newly added packages recommended by installed packages" +#~ msgstr "" +#~ "Installiere diese Pakete, selbst wenn sie Dateien aus anderen, bereits " +#~ "installierten Paketen ersetzen" -#: share/completions/zypper.fish:49 #, fuzzy -msgid "Update installed packages with newer versions" -msgstr "Alle Quellpakete mit Version ausgeben" +#~ msgid "Update installed packages with newer versions" +#~ msgstr "Alle Quellpakete mit Version ausgeben" -#: share/completions/zypper.fish:50 #, fuzzy -msgid "List available updates" -msgstr "Verfügbare Liste ausgeben" +#~ msgid "List available updates" +#~ msgstr "Verfügbare Liste ausgeben" -#: share/completions/zypper.fish:51 #, fuzzy -msgid "Install needed patches" -msgstr "Neues Paket installieren" +#~ msgid "Install needed patches" +#~ msgstr "Neues Paket installieren" -#: share/completions/zypper.fish:52 -msgid "List needed patches" -msgstr "" - -#: share/completions/zypper.fish:53 #, fuzzy -msgid "Perform a distribution upgrade" -msgstr "Simulation durchführen" +#~ msgid "Perform a distribution upgrade" +#~ msgstr "Simulation durchführen" -#: share/completions/zypper.fish:54 #, fuzzy -msgid "Check for patches" -msgstr "Komprimierte Patche erstellen" +#~ msgid "Check for patches" +#~ msgstr "Komprimierte Patche erstellen" -#: share/completions/zypper.fish:55 #, fuzzy -msgid "Search for packages matching a pattern" -msgstr "Paket entsprechend Muster suchen" +#~ msgid "Search for packages matching a pattern" +#~ msgstr "Paket entsprechend Muster suchen" -#: share/completions/zypper.fish:56 #, fuzzy -msgid "Show full information for specified packages" -msgstr "Volle Versionen der Pakete anzeigen" +#~ msgid "Show full information for specified packages" +#~ msgstr "Volle Versionen der Pakete anzeigen" -#: share/completions/zypper.fish:57 #, fuzzy -msgid "Show full information for specified patches" -msgstr "Profilierungsinformation in angegebene Datei ausgeben" +#~ msgid "Show full information for specified patches" +#~ msgstr "Profilierungsinformation in angegebene Datei ausgeben" -#: share/completions/zypper.fish:58 #, fuzzy -msgid "Show full information for specified patterns" -msgstr "Profilierungsinformation in angegebene Datei ausgeben" +#~ msgid "Show full information for specified patterns" +#~ msgstr "Profilierungsinformation in angegebene Datei ausgeben" -#: share/completions/zypper.fish:59 #, fuzzy -msgid "Show full information for specified products" -msgstr "Profilierungsinformation in angegebene Datei ausgeben" +#~ msgid "Show full information for specified products" +#~ msgstr "Profilierungsinformation in angegebene Datei ausgeben" -#: share/completions/zypper.fish:60 #, fuzzy -msgid "List all available patches" -msgstr "Namen der verfügbaren Signale auflisten" +#~ msgid "List all available patches" +#~ msgstr "Namen der verfügbaren Signale auflisten" -#: share/completions/zypper.fish:61 #, fuzzy -msgid "List all available packages" -msgstr "Pakete erneut installieren" +#~ msgid "List all available packages" +#~ msgstr "Pakete erneut installieren" -#: share/completions/zypper.fish:62 #, fuzzy -msgid "List all available patterns" -msgstr "Namen der verfügbaren Signale auflisten" +#~ msgid "List all available patterns" +#~ msgstr "Namen der verfügbaren Signale auflisten" -#: share/completions/zypper.fish:63 #, fuzzy -msgid "List all available products" -msgstr "Namen der verfügbaren Signale auflisten" +#~ msgid "List all available products" +#~ msgstr "Namen der verfügbaren Signale auflisten" -#: share/completions/zypper.fish:64 #, fuzzy -msgid "List packages providing specified capability" -msgstr "Alle Pakete abfragen, die die angegebene Eigenschaft bereitstellen" +#~ msgid "List packages providing specified capability" +#~ msgstr "Alle Pakete abfragen, die die angegebene Eigenschaft bereitstellen" -#: share/completions/zypper.fish:65 #, fuzzy -msgid "Add a package lock" -msgstr "Ein Paket neu erstellen" +#~ msgid "Add a package lock" +#~ msgstr "Ein Paket neu erstellen" -#: share/completions/zypper.fish:66 #, fuzzy -msgid "Remove a package lock" -msgstr "Pakete entfernen" +#~ msgid "Remove a package lock" +#~ msgstr "Pakete entfernen" -#: share/completions/zypper.fish:67 #, fuzzy -msgid "List current package locks" -msgstr "Fehler aus Paketen auflisten" +#~ msgid "List current package locks" +#~ msgstr "Fehler aus Paketen auflisten" -#: share/completions/zypper.fish:68 #, fuzzy -msgid "Remove unused locks" -msgstr "Quellpakete entfernen" - -#: share/completions/zypper.fish:69 -msgid "Compare two version strings" -msgstr "" +#~ msgid "Remove unused locks" +#~ msgstr "Quellpakete entfernen" -#: share/completions/zypper.fish:70 #, fuzzy -msgid "Print the target operating system ID string" -msgstr "Betriebssystem ausgeben" +#~ msgid "Print the target operating system ID string" +#~ msgstr "Betriebssystem ausgeben" -#: share/completions/zypper.fish:71 -msgid "Print report about licenses and EULAs of installed packages" -msgstr "" - -#: share/completions/zypper.fish:72 -msgid "Download source rpms for all installed packages to a local directory" -msgstr "" - -#: share/functions/N_.fish:3 -msgid "No-op" -msgstr "" - -#: share/functions/_.fish:8 share/functions/_.fish:12 #, fuzzy -msgid "Alias for the gettext command" -msgstr "Hilfe für den Befehl '%s'" - -#: share/functions/_.fish:9 -msgid "fish" -msgstr "fish" +#~ msgid "Alias for the gettext command" +#~ msgstr "Hilfe für den Befehl '%s'" -#: share/functions/__fish_complete_abook_formats.fish:1 -msgid "Complete abook formats" -msgstr "" +#~ msgid "fish" +#~ msgstr "fish" -#: share/functions/__fish_complete_atool.fish:1 -msgid "Complete atool" -msgstr "" - -#: share/functions/__fish_complete_atool_archive_contents.fish:1 #, fuzzy -msgid "List archive contents" -msgstr "Archiv auflisten" - -#: share/functions/__fish_complete_bittorrent.fish:9 -msgid "IP to report to the tracker" -msgstr "An den Tracker zu sendende IP-Adresse" +#~ msgid "List archive contents" +#~ msgstr "Archiv auflisten" -#: share/functions/__fish_complete_bittorrent.fish:10 -msgid "Minimum port to listen to" -msgstr "Niedrigster Port, an dem gelauscht wird" +#~ msgid "IP to report to the tracker" +#~ msgstr "An den Tracker zu sendende IP-Adresse" -#: share/functions/__fish_complete_bittorrent.fish:11 -msgid "Maximum port to listen to" -msgstr "Höchster Port, an dem gelauscht wird" +#~ msgid "Minimum port to listen to" +#~ msgstr "Niedrigster Port, an dem gelauscht wird" -#: share/functions/__fish_complete_command.fish:1 -msgid "Complete using all available commands" -msgstr "" +#~ msgid "Maximum port to listen to" +#~ msgstr "Höchster Port, an dem gelauscht wird" -#: share/functions/__fish_complete_convert_options.fish:1 #, fuzzy -msgid "Complete Convert options" -msgstr "Saloppe Einhäng-Optionen tolerieren" +#~ msgid "Complete Convert options" +#~ msgstr "Saloppe Einhäng-Optionen tolerieren" -#: share/functions/__fish_complete_diff.fish:3 -msgid "Ignore case differences" -msgstr "Unterschiede bei Groß-/Kleinschreibung ignorieren" +#~ msgid "Ignore case differences" +#~ msgstr "Unterschiede bei Groß-/Kleinschreibung ignorieren" -#: share/functions/__fish_complete_diff.fish:4 -msgid "Ignore case when comparing file names" -msgstr "Groß-/Kleinschreibung beim Dateinamenvergleich ignorieren" +#~ msgid "Ignore case when comparing file names" +#~ msgstr "Groß-/Kleinschreibung beim Dateinamenvergleich ignorieren" -#: share/functions/__fish_complete_diff.fish:5 -msgid "Consider case when comparing file names" -msgstr "Groß-/Kleinschreibung beim Dateinamenvergleich beachten" +#~ msgid "Consider case when comparing file names" +#~ msgstr "Groß-/Kleinschreibung beim Dateinamenvergleich beachten" -#: share/functions/__fish_complete_diff.fish:6 -msgid "Ignore changes due to tab expansion" -msgstr "Änderungen aufgrund von Tabulatorausweitung ignorieren" +#~ msgid "Ignore changes due to tab expansion" +#~ msgstr "Änderungen aufgrund von Tabulatorausweitung ignorieren" -#: share/functions/__fish_complete_diff.fish:7 -msgid "Ignore changes in the amount of white space" -msgstr "Änderung in der Anzahl von Worttrennern ignorieren" +#~ msgid "Ignore changes in the amount of white space" +#~ msgstr "Änderung in der Anzahl von Worttrennern ignorieren" -#: share/functions/__fish_complete_diff.fish:8 -msgid "Ignore all white space" -msgstr "white space (Worttrenner) ignorieren" +#~ msgid "Ignore all white space" +#~ msgstr "white space (Worttrenner) ignorieren" -#: share/functions/__fish_complete_diff.fish:9 -msgid "Ignore changes whose lines are all blank" -msgstr "Änderungen ignorieren, deren Zeilen alle leer sind" +#~ msgid "Ignore changes whose lines are all blank" +#~ msgstr "Änderungen ignorieren, deren Zeilen alle leer sind" -#: share/functions/__fish_complete_diff.fish:11 -msgid "Treat all files as text" -msgstr "Alle Dateien als Text behandeln" +#~ msgid "Treat all files as text" +#~ msgstr "Alle Dateien als Text behandeln" -#: share/functions/__fish_complete_diff.fish:12 -msgid "Recursively compare subdirectories" -msgstr "Unterverzeichnisse rekursiv vergleichen" +#~ msgid "Recursively compare subdirectories" +#~ msgstr "Unterverzeichnisse rekursiv vergleichen" -#: share/functions/__fish_complete_diff.fish:13 -msgid "Treat absent files as empty" -msgstr "Nicht vorhandene Dateien als leer behandeln" +#~ msgid "Treat absent files as empty" +#~ msgstr "Nicht vorhandene Dateien als leer behandeln" -#: share/functions/__fish_complete_diff.fish:15 -msgid "Output 3 lines of copied context" -msgstr "3 Zeilen des kopierten Kontextes ausgeben" +#~ msgid "Output 3 lines of copied context" +#~ msgstr "3 Zeilen des kopierten Kontextes ausgeben" -#: share/functions/__fish_complete_diff.fish:17 -msgid "Output 3 lines of unified context" -msgstr "3 Zeilen des vereinheitlichten Kontextes ausgeben" +#~ msgid "Output 3 lines of unified context" +#~ msgstr "3 Zeilen des vereinheitlichten Kontextes ausgeben" -#: share/functions/__fish_complete_diff.fish:18 -msgid "Output only whether the files differ" -msgstr "Nur Unterschiede der Dateien ausgeben" +#~ msgid "Output only whether the files differ" +#~ msgstr "Nur Unterschiede der Dateien ausgeben" -#: share/functions/__fish_complete_diff.fish:19 -msgid "Output a normal diff" -msgstr "Normalen Diff ausgeben" +#~ msgid "Output a normal diff" +#~ msgstr "Normalen Diff ausgeben" -#: share/functions/__fish_complete_diff.fish:20 -msgid "Output in two columns" -msgstr "Ausgabe in zwei Spalten" +#~ msgid "Output in two columns" +#~ msgstr "Ausgabe in zwei Spalten" -#: share/functions/__fish_complete_diff.fish:22 -msgid "Try to find a smaller set of changes" -msgstr "Versuche, eine kleinere Menge Änderungen zu finden" +#~ msgid "Try to find a smaller set of changes" +#~ msgstr "Versuche, eine kleinere Menge Änderungen zu finden" -#: share/functions/__fish_complete_diff.fish:25 -msgid "Pass the output through 'pr'" -msgstr "Ausgabe durch 'pr' schicken" +#~ msgid "Pass the output through 'pr'" +#~ msgstr "Ausgabe durch 'pr' schicken" -#: share/functions/__fish_complete_grep.fish:2 -msgid "Print NUM lines of trailing context" -msgstr "NUM folgende Kontext-Zeilen ausgeben" +#~ msgid "Print NUM lines of trailing context" +#~ msgstr "NUM folgende Kontext-Zeilen ausgeben" -#: share/functions/__fish_complete_grep.fish:3 -msgid "Process binary file as text" -msgstr "Binärdateien als Text behandeln" +#~ msgid "Process binary file as text" +#~ msgstr "Binärdateien als Text behandeln" -#: share/functions/__fish_complete_grep.fish:4 -msgid "Print NUM lines of leading context" -msgstr "NUM führende Kontext-Zeilen ausgeben" +#~ msgid "Print NUM lines of leading context" +#~ msgstr "NUM führende Kontext-Zeilen ausgeben" -#: share/functions/__fish_complete_grep.fish:5 -msgid "Print NUM lines of context" -msgstr "NUM Kontext-Zeilen ausgeben" +#~ msgid "Print NUM lines of context" +#~ msgstr "NUM Kontext-Zeilen ausgeben" -#: share/functions/__fish_complete_grep.fish:6 -msgid "Print byte offset of matches" -msgstr "Byte-Offset von Treffern ausgeben" +#~ msgid "Print byte offset of matches" +#~ msgstr "Byte-Offset von Treffern ausgeben" -#: share/functions/__fish_complete_grep.fish:7 -msgid "Assume data type for binary files" -msgstr "Datentyp für Binärdateien unterstellen" +#~ msgid "Assume data type for binary files" +#~ msgstr "Datentyp für Binärdateien unterstellen" -#: share/functions/__fish_complete_grep.fish:10 -msgid "Only print number of matches" -msgstr "Nur Anzahl von Treffern ausgeben" +#~ msgid "Only print number of matches" +#~ msgstr "Nur Anzahl von Treffern ausgeben" -#: share/functions/__fish_complete_grep.fish:13 -msgid "Pattern is extended regexp" -msgstr "Muster ist ein erweiterter regulärer Ausdruck" +#~ msgid "Pattern is extended regexp" +#~ msgstr "Muster ist ein erweiterter regulärer Ausdruck" -#: share/functions/__fish_complete_grep.fish:14 -msgid "Pattern is a regexp" -msgstr "Muster ist ein regulärer Ausdruck" +#~ msgid "Pattern is a regexp" +#~ msgstr "Muster ist ein regulärer Ausdruck" -#: share/functions/__fish_complete_grep.fish:15 -msgid "Read pattern list from file. Skip files whose base name matches list" -msgstr "" - -#: share/functions/__fish_complete_grep.fish:16 #, fuzzy -msgid "Exclude matching directories from recursive searches" -msgstr "Verzeichnisse nach Quelle durchsuchen" +#~ msgid "Exclude matching directories from recursive searches" +#~ msgstr "Verzeichnisse nach Quelle durchsuchen" -#: share/functions/__fish_complete_grep.fish:17 -msgid "Pattern is a fixed string" -msgstr "Muster ist eine feststehende Zeichenkette" +#~ msgid "Pattern is a fixed string" +#~ msgstr "Muster ist eine feststehende Zeichenkette" -#: share/functions/__fish_complete_grep.fish:19 -msgid "Pattern is basic regex" -msgstr "Muster ist ein einfacher regulärer Ausdruck" +#~ msgid "Pattern is basic regex" +#~ msgstr "Muster ist ein einfacher regulärer Ausdruck" -#: share/functions/__fish_complete_grep.fish:20 -msgid "Print filename" -msgstr "Dateiname ausgeben" +#~ msgid "Print filename" +#~ msgstr "Dateiname ausgeben" -#: share/functions/__fish_complete_grep.fish:21 #, fuzzy -msgid "Suppress printing filename" -msgstr "Dateinamenausgabe unterdrücken" +#~ msgid "Suppress printing filename" +#~ msgstr "Dateinamenausgabe unterdrücken" -#: share/functions/__fish_complete_grep.fish:23 -msgid "Skip binary files" -msgstr "Binärdateien überspringen" +#~ msgid "Skip binary files" +#~ msgstr "Binärdateien überspringen" -#: share/functions/__fish_complete_grep.fish:24 -msgid "Ignore case" -msgstr "Gross-/Kleinschreibung ignorieren" +#~ msgid "Ignore case" +#~ msgstr "Gross-/Kleinschreibung ignorieren" -#: share/functions/__fish_complete_grep.fish:25 -msgid "Print first non-matching file" -msgstr "Erste nicht zutreffende Datei ausgeben" +#~ msgid "Print first non-matching file" +#~ msgstr "Erste nicht zutreffende Datei ausgeben" -#: share/functions/__fish_complete_grep.fish:26 -msgid "Print first matching file" -msgstr "Erste zutreffende Datei ausgeben" +#~ msgid "Print first matching file" +#~ msgstr "Erste zutreffende Datei ausgeben" -#: share/functions/__fish_complete_grep.fish:27 -msgid "Stop reading after NUM matches" -msgstr "Lesen nach NUM Treffern beenden" +#~ msgid "Stop reading after NUM matches" +#~ msgstr "Lesen nach NUM Treffern beenden" -#: share/functions/__fish_complete_grep.fish:28 -msgid "Use the mmap system call to read input" -msgstr "mmap-Systemaufruf zum Lesen der Eingabe nutzen" +#~ msgid "Use the mmap system call to read input" +#~ msgstr "mmap-Systemaufruf zum Lesen der Eingabe nutzen" -#: share/functions/__fish_complete_grep.fish:29 #, fuzzy -msgid "Print line number" -msgstr "Zeilennummer ausgeben" +#~ msgid "Print line number" +#~ msgstr "Zeilennummer ausgeben" -#: share/functions/__fish_complete_grep.fish:30 -msgid "Show only matching part" -msgstr "Nur zutreffenden Teil anzeigen" +#~ msgid "Show only matching part" +#~ msgstr "Nur zutreffenden Teil anzeigen" -#: share/functions/__fish_complete_grep.fish:31 -msgid "Rename stdin" -msgstr "Standardeingabe umbenennen" +#~ msgid "Rename stdin" +#~ msgstr "Standardeingabe umbenennen" -#: share/functions/__fish_complete_grep.fish:32 -msgid "Use line buffering" -msgstr "Zeilenpufferung benutzen" +#~ msgid "Use line buffering" +#~ msgstr "Zeilenpufferung benutzen" -#: share/functions/__fish_complete_grep.fish:33 #, fuzzy -msgid "Pattern is a Perl regexp (PCRE) string" -msgstr "Muster ist ein regulärer Ausdruck" +#~ msgid "Pattern is a Perl regexp (PCRE) string" +#~ msgstr "Muster ist ein regulärer Ausdruck" -#: share/functions/__fish_complete_grep.fish:34 -#: share/functions/__fish_complete_grep.fish:35 -msgid "Do not write anything" -msgstr "Nichts schreiben" +#~ msgid "Do not write anything" +#~ msgstr "Nichts schreiben" -#: share/functions/__fish_complete_grep.fish:36 -#: share/functions/__fish_complete_grep.fish:37 #, fuzzy -msgid "Read files under each directory, recursively" -msgstr "Dateien unter jedem Verzeichnis lesen" +#~ msgid "Read files under each directory, recursively" +#~ msgstr "Dateien unter jedem Verzeichnis lesen" -#: share/functions/__fish_complete_grep.fish:38 #, fuzzy -msgid "Search only files matching PATTERN" -msgstr "Rekursiv, Dateien gemäß MUSTER suchen" +#~ msgid "Search only files matching PATTERN" +#~ msgstr "Rekursiv, Dateien gemäß MUSTER suchen" -#: share/functions/__fish_complete_grep.fish:39 #, fuzzy -msgid "Skip files matching PATTERN" -msgstr "Rekursiv, dem MUSTER entsprechende Dateien überspringen" - -#: share/functions/__fish_complete_grep.fish:40 -msgid "Suppress error messages" -msgstr "Fehlermeldungen unterdrücken" +#~ msgid "Skip files matching PATTERN" +#~ msgstr "Rekursiv, dem MUSTER entsprechende Dateien überspringen" -#: share/functions/__fish_complete_grep.fish:41 -msgid "Ensure first character of actual line content lies on a tab stop" -msgstr "" +#~ msgid "Suppress error messages" +#~ msgstr "Fehlermeldungen unterdrücken" -#: share/functions/__fish_complete_grep.fish:42 -msgid "Treat files as binary" -msgstr "Dateien als binär behandeln" +#~ msgid "Treat files as binary" +#~ msgstr "Dateien als binär behandeln" -#: share/functions/__fish_complete_grep.fish:43 -msgid "Report Unix-style byte offsets" -msgstr "Byte-Offset im Unix-Format angeben" +#~ msgid "Report Unix-style byte offsets" +#~ msgstr "Byte-Offset im Unix-Format angeben" -#: share/functions/__fish_complete_grep.fish:45 -msgid "Invert the sense of matching" -msgstr "Bedeutung der Treffer umkehren" +#~ msgid "Invert the sense of matching" +#~ msgstr "Bedeutung der Treffer umkehren" -#: share/functions/__fish_complete_grep.fish:46 -msgid "Only whole matching words" -msgstr "Nur vollständig übereinstimmende Worte" +#~ msgid "Only whole matching words" +#~ msgstr "Nur vollständig übereinstimmende Worte" -#: share/functions/__fish_complete_grep.fish:47 -msgid "Only whole matching lines" -msgstr "Nur vollständig übereinstimmende Zeilen" +#~ msgid "Only whole matching lines" +#~ msgstr "Nur vollständig übereinstimmende Zeilen" -#: share/functions/__fish_complete_grep.fish:48 #, fuzzy -msgid "Obsolete synonym for -i" -msgstr "Synonym für -i" +#~ msgid "Obsolete synonym for -i" +#~ msgstr "Synonym für -i" -#: share/functions/__fish_complete_grep.fish:49 -msgid "treat input as a set of lines each terminated by a zero byte" -msgstr "" +#~ msgid "Output a zero byte after filename" +#~ msgstr "Ein Null-Byte nach dem Dateinamen ausgeben" -#: share/functions/__fish_complete_grep.fish:50 -msgid "Output a zero byte after filename" -msgstr "Ein Null-Byte nach dem Dateinamen ausgeben" - -#: share/functions/__fish_complete_groups.fish:2 -msgid "Print a list of local groups, with group members as the description" -msgstr "" - -#: share/functions/__fish_complete_lpr_option.fish:1 #, fuzzy -msgid "Complete lpr option" -msgstr "Saloppe Einhäng-Optionen tolerieren" +#~ msgid "Complete lpr option" +#~ msgstr "Saloppe Einhäng-Optionen tolerieren" -#: share/functions/__fish_complete_ls.fish:16 -msgid "Show hidden" -msgstr "Zeige versteckte Dateien" +#~ msgid "Show hidden" +#~ msgstr "Zeige versteckte Dateien" -#: share/functions/__fish_complete_ls.fish:17 -msgid "Show hidden except . and .." -msgstr "Zeige versteckte Dateien ausser . und .." +#~ msgid "Show hidden except . and .." +#~ msgstr "Zeige versteckte Dateien ausser . und .." -#: share/functions/__fish_complete_ls.fish:18 -#: share/functions/__fish_complete_ls.fish:27 -msgid "Append filetype indicator" -msgstr "Dateityp-Anzeige anhängen" +#~ msgid "Append filetype indicator" +#~ msgstr "Dateityp-Anzeige anhängen" -#: share/functions/__fish_complete_ls.fish:19 -#: share/functions/__fish_complete_ls.fish:20 -msgid "Follow symlinks" -msgstr "Symbolischen Links folgen" +#~ msgid "Follow symlinks" +#~ msgstr "Symbolischen Links folgen" -#: share/functions/__fish_complete_ls.fish:21 -msgid "List subdirectory recursively" -msgstr "Unterverzeichnisse rekursiv auflisten" +#~ msgid "List subdirectory recursively" +#~ msgstr "Unterverzeichnisse rekursiv auflisten" -#: share/functions/__fish_complete_ls.fish:22 -#: share/functions/__fish_complete_ls.fish:102 -msgid "Octal escapes for non graphic characters" -msgstr "Oktaldarstellung für nichtgrafische Zeichen" +#~ msgid "Octal escapes for non graphic characters" +#~ msgstr "Oktaldarstellung für nichtgrafische Zeichen" -#: share/functions/__fish_complete_ls.fish:23 -msgid "List directories, not their content" -msgstr "Verzeichnisse, aber nicht deren Inhalt auflisten" +#~ msgid "List directories, not their content" +#~ msgstr "Verzeichnisse, aber nicht deren Inhalt auflisten" -#: share/functions/__fish_complete_ls.fish:24 -msgid "Human readable sizes" -msgstr "Lesbare Grössen" +#~ msgid "Human readable sizes" +#~ msgstr "Lesbare Grössen" -#: share/functions/__fish_complete_ls.fish:25 -msgid "Print inode number of files" -msgstr "Inode-Nummer der Dateien ausgeben" +#~ msgid "Print inode number of files" +#~ msgstr "Inode-Nummer der Dateien ausgeben" -#: share/functions/__fish_complete_ls.fish:26 -msgid "Long format, numeric IDs" -msgstr "Langformat, numerische IDs" +#~ msgid "Long format, numeric IDs" +#~ msgstr "Langformat, numerische IDs" -#: share/functions/__fish_complete_ls.fish:28 -msgid "Replace non-graphic characters with '?'" -msgstr "Nicht darstellbare Zeichen durch '?' ersetzen" +#~ msgid "Replace non-graphic characters with '?'" +#~ msgstr "Nicht darstellbare Zeichen durch '?' ersetzen" -#: share/functions/__fish_complete_ls.fish:29 -msgid "Reverse sort order" -msgstr "Sortierreihenfolge umkehren" +#~ msgid "Reverse sort order" +#~ msgstr "Sortierreihenfolge umkehren" -#: share/functions/__fish_complete_ls.fish:30 -msgid "Print size of files" -msgstr "Größe der Dateien ausgeben" +#~ msgid "Print size of files" +#~ msgstr "Größe der Dateien ausgeben" -#: share/functions/__fish_complete_ls.fish:32 -msgid "List by columns" -msgstr "Nach Spalten auflisten" +#~ msgid "List by columns" +#~ msgstr "Nach Spalten auflisten" -#: share/functions/__fish_complete_ls.fish:33 -msgid "Sort by size" -msgstr "Nach Größe sortieren" +#~ msgid "Sort by size" +#~ msgstr "Nach Größe sortieren" -#: share/functions/__fish_complete_ls.fish:34 -msgid "Show and sort by ctime" -msgstr "Nach ctime sortieren und anzeigen" +#~ msgid "Show and sort by ctime" +#~ msgstr "Nach ctime sortieren und anzeigen" -#: share/functions/__fish_complete_ls.fish:35 -msgid "Don't sort" -msgstr "Nicht sortieren" +#~ msgid "Don't sort" +#~ msgstr "Nicht sortieren" -#: share/functions/__fish_complete_ls.fish:36 -msgid "Long format without owner" -msgstr "Langformat ohne Eigentümer" +#~ msgid "Long format without owner" +#~ msgstr "Langformat ohne Eigentümer" -#: share/functions/__fish_complete_ls.fish:37 -msgid "Set blocksize to 1kB" -msgstr "Blockgröße auf 1kB festlegen" +#~ msgid "Set blocksize to 1kB" +#~ msgstr "Blockgröße auf 1kB festlegen" -#: share/functions/__fish_complete_ls.fish:38 -msgid "Long format" -msgstr "Langformat" +#~ msgid "Long format" +#~ msgstr "Langformat" -#: share/functions/__fish_complete_ls.fish:39 -msgid "Comma separated format" -msgstr "Komma-getrenntes Format" +#~ msgid "Comma separated format" +#~ msgstr "Komma-getrenntes Format" -#: share/functions/__fish_complete_ls.fish:40 -msgid "Sort by modification time" -msgstr "Nach Veränderungsdatum sortieren" +#~ msgid "Sort by modification time" +#~ msgstr "Nach Veränderungsdatum sortieren" -#: share/functions/__fish_complete_ls.fish:41 -msgid "Show access time" -msgstr "Zugriffszeit anzeigen" +#~ msgid "Show access time" +#~ msgstr "Zugriffszeit anzeigen" -#: share/functions/__fish_complete_ls.fish:42 -msgid "List entries by lines" -msgstr "Einträge auflisten" +#~ msgid "List entries by lines" +#~ msgstr "Einträge auflisten" -#: share/functions/__fish_complete_ls.fish:43 -msgid "List one file per line" -msgstr "Eine Datei pro Zeile auflisten" +#~ msgid "List one file per line" +#~ msgstr "Eine Datei pro Zeile auflisten" -#: share/functions/__fish_complete_ls.fish:49 #, fuzzy -msgid "Do not list implied entries matching specified shell pattern" -msgstr "Dem Muster entsprechende Einträge übergehen" +#~ msgid "Do not list implied entries matching specified shell pattern" +#~ msgstr "Dem Muster entsprechende Einträge übergehen" -#: share/functions/__fish_complete_ls.fish:50 #, fuzzy -msgid "Display security context" -msgstr "Version anzeigen und beenden" - -#: share/functions/__fish_complete_ls.fish:51 -msgid "Display security context so it fits on most displays" -msgstr "" +#~ msgid "Display security context" +#~ msgstr "Version anzeigen und beenden" -#: share/functions/__fish_complete_ls.fish:52 -msgid "Display only security context and file name" -msgstr "" +#~ msgid "Print author" +#~ msgstr "Autor ausgeben" -#: share/functions/__fish_complete_ls.fish:54 -msgid "Print author" -msgstr "Autor ausgeben" +#~ msgid "Ignore files ending with ~" +#~ msgstr "Dateien ignorieren, die mit ~ enden" -#: share/functions/__fish_complete_ls.fish:56 -msgid "Ignore files ending with ~" -msgstr "Dateien ignorieren, die mit ~ enden" +#~ msgid "Generate dired output" +#~ msgstr "dired-Ausgabe erzeugen" -#: share/functions/__fish_complete_ls.fish:58 -msgid "Generate dired output" -msgstr "dired-Ausgabe erzeugen" +#~ msgid "Long format, full-iso time" +#~ msgstr "Langformat, volle ISO-Zeit" -#: share/functions/__fish_complete_ls.fish:60 -msgid "Long format, full-iso time" -msgstr "Langformat, volle ISO-Zeit" +#~ msgid "Don't print group information" +#~ msgstr "Keine Gruppeninformation ausgeben" -#: share/functions/__fish_complete_ls.fish:61 -msgid "Don't print group information" -msgstr "Keine Gruppeninformation ausgeben" +#~ msgid "Human readable sizes, powers of 1000" +#~ msgstr "Lesbare Grössen, vielfaches von 1000" -#: share/functions/__fish_complete_ls.fish:62 -msgid "Human readable sizes, powers of 1000" -msgstr "Lesbare Grössen, vielfaches von 1000" +#~ msgid "Print raw entry names" +#~ msgstr "Roheinträge ausgeben" -#: share/functions/__fish_complete_ls.fish:66 -#: share/functions/__fish_complete_ls.fish:110 -msgid "Print raw entry names" -msgstr "Roheinträge ausgeben" +#~ msgid "Long format without groups" +#~ msgstr "Langformat ohne Gruppen" -#: share/functions/__fish_complete_ls.fish:67 -msgid "Long format without groups" -msgstr "Langformat ohne Gruppen" +#~ msgid "Non graphic as-is" +#~ msgstr "Nicht darstellbare Zeichen unverändert lassen" -#: share/functions/__fish_complete_ls.fish:68 -msgid "Non graphic as-is" -msgstr "Nicht darstellbare Zeichen unverändert lassen" +#~ msgid "Enclose entry in quotes" +#~ msgstr "Eintrag in Markierungen einschliessen" -#: share/functions/__fish_complete_ls.fish:69 -msgid "Enclose entry in quotes" -msgstr "Eintrag in Markierungen einschliessen" +#~ msgid "Do not sort" +#~ msgstr "Nicht sortieren" -#: share/functions/__fish_complete_ls.fish:91 -msgid "Do not sort" -msgstr "Nicht sortieren" +#~ msgid "Sort by version" +#~ msgstr "Sortierung nach Version" -#: share/functions/__fish_complete_ls.fish:92 -msgid "Sort by version" -msgstr "Sortierung nach Version" +#~ msgid "Sort by extension" +#~ msgstr "Sortierung nach Erweiterung" -#: share/functions/__fish_complete_ls.fish:94 -msgid "Sort by extension" -msgstr "Sortierung nach Erweiterung" +#~ msgid "Use colors" +#~ msgstr "Farben benutzen" -#: share/functions/__fish_complete_ls.fish:103 -msgid "Use colors" -msgstr "Farben benutzen" +#~ msgid "Prevent -A from being automatically set for root" +#~ msgstr "Für root nicht automatisch -A festlegen" -#: share/functions/__fish_complete_ls.fish:104 -msgid "Prevent -A from being automatically set for root" -msgstr "Für root nicht automatisch -A festlegen" +#~ msgid "Don't follow symlinks" +#~ msgstr "Symbolischen Links nicht folgen" -#: share/functions/__fish_complete_ls.fish:105 -msgid "Don't follow symlinks" -msgstr "Symbolischen Links nicht folgen" +#~ msgid "Show modification time" +#~ msgstr "Änderungsdatum anzeigen" -#: share/functions/__fish_complete_ls.fish:106 -msgid "Show modification time" -msgstr "Änderungsdatum anzeigen" +#~ msgid "Show whiteouts when scanning directories" +#~ msgstr "Überblendungen beim Scannen von Verzeichnissen anzeigen" -#: share/functions/__fish_complete_ls.fish:107 -msgid "Show whiteouts when scanning directories" -msgstr "Überblendungen beim Scannen von Verzeichnissen anzeigen" +#~ msgid "Display each file's MAC label" +#~ msgstr "MAC-Markierung jeder Datei anzeigen" -#: share/functions/__fish_complete_ls.fish:108 -msgid "Display each file's MAC label" -msgstr "MAC-Markierung jeder Datei anzeigen" +#~ msgid "Include the file flags in a long (-l) output" +#~ msgstr "Datei-Kennungen in langer (-l) Ausgabe einfügen" -#: share/functions/__fish_complete_ls.fish:109 -msgid "Include the file flags in a long (-l) output" -msgstr "Datei-Kennungen in langer (-l) Ausgabe einfügen" - -#: share/functions/__fish_complete_path.fish:1 #, fuzzy -msgid "Complete using path" -msgstr "Saloppe Einhäng-Optionen tolerieren" - -#: share/functions/__fish_complete_ppp_peer.fish:1 -msgid "Complete isp name for pon/poff" -msgstr "" +#~ msgid "Complete using path" +#~ msgstr "Saloppe Einhäng-Optionen tolerieren" -#: share/functions/__fish_complete_proc.fish:1 #, fuzzy -msgid "Complete by list of running processes" -msgstr "Liste laufender screen-Sitzungen ausgeben" +#~ msgid "Complete by list of running processes" +#~ msgstr "Liste laufender screen-Sitzungen ausgeben" -#: share/functions/__fish_complete_python.fish:2 -#: share/functions/__fish_complete_python.fish:28 -#: share/functions/__fish_complete_vi.fish:54 -msgid "Don\\t" -msgstr "" +#~ msgid "Disable import of site module" +#~ msgstr "Import des Seitenmoduls deaktivieren" -#: share/functions/__fish_complete_python.fish:12 -msgid "Disable import of site module" -msgstr "Import des Seitenmoduls deaktivieren" +#~ msgid "Unbuffered input and output" +#~ msgstr "ungepufferte Ein-/Ausgabe" -#: share/functions/__fish_complete_python.fish:13 -msgid "Unbuffered input and output" -msgstr "ungepufferte Ein-/Ausgabe" +#~ msgid "Warn on mixed tabs and spaces" +#~ msgstr "Warnung bei gemischten Tabulator- und Leerzeichen" -#: share/functions/__fish_complete_python.fish:24 -msgid "Warn on mixed tabs and spaces" -msgstr "Warnung bei gemischten Tabulator- und Leerzeichen" - -#: share/functions/__fish_complete_setxkbmap.fish:1 #, fuzzy -msgid "Complete setxkb options" -msgstr "Saloppe Einhäng-Optionen tolerieren" +#~ msgid "Complete setxkb options" +#~ msgstr "Saloppe Einhäng-Optionen tolerieren" -#: share/functions/__fish_complete_ssh.fish:4 #, fuzzy -msgid "Protocol version 1 only" -msgstr "Nur Protokoll-Version 1" +#~ msgid "Protocol version 1 only" +#~ msgstr "Nur Protokoll-Version 1" -#: share/functions/__fish_complete_ssh.fish:5 #, fuzzy -msgid "Protocol version 2 only" -msgstr "Nur Protokoll-Version 2" - -#: share/functions/__fish_complete_ssh.fish:6 -msgid "IPv4 addresses only" -msgstr "Nur IPv4-Adressen" +#~ msgid "Protocol version 2 only" +#~ msgstr "Nur Protokoll-Version 2" -#: share/functions/__fish_complete_ssh.fish:7 -msgid "IPv6 addresses only" -msgstr "Nur IPv6-Adressen" +#~ msgid "IPv4 addresses only" +#~ msgstr "Nur IPv4-Adressen" -#: share/functions/__fish_complete_ssh.fish:8 -msgid "Compress all data" -msgstr "Alle Daten komprimieren" +#~ msgid "IPv6 addresses only" +#~ msgstr "Nur IPv6-Adressen" -#: share/functions/__fish_complete_ssh.fish:9 -msgid "Encryption algorithm" -msgstr "Verschlüsselungs-Algorithmus" +#~ msgid "Compress all data" +#~ msgstr "Alle Daten komprimieren" -#: share/functions/__fish_complete_ssh.fish:10 -msgid "Configuration file" -msgstr "Konfigurationsdatei" +#~ msgid "Encryption algorithm" +#~ msgstr "Verschlüsselungs-Algorithmus" -#: share/functions/__fish_complete_ssh.fish:11 -msgid "Identity file" -msgstr "Datei identifizieren" +#~ msgid "Configuration file" +#~ msgstr "Konfigurationsdatei" -#: share/functions/__fish_complete_ssh.fish:12 -msgid "Options" -msgstr "Optionen" +#~ msgid "Identity file" +#~ msgstr "Datei identifizieren" -#: share/functions/__fish_complete_svn.fish:48 -msgid "" -"Put files and directories under version control, scheduling them for " -"addition to repository. They will be added in next commit." -msgstr "" +#~ msgid "Options" +#~ msgstr "Optionen" -#: share/functions/__fish_complete_svn.fish:49 -#: share/functions/__fish_complete_svn.fish:51 -msgid "" -"Output the content of specified files or URLs with revision and author " -"information in-line." -msgstr "" - -#: share/functions/__fish_complete_svn.fish:50 #, fuzzy -msgid "Output the content of specified files or URLs." -msgstr "Profilierungsinformation in angegebene Datei ausgeben" +#~ msgid "Output the content of specified files or URLs." +#~ msgstr "Profilierungsinformation in angegebene Datei ausgeben" -#: share/functions/__fish_complete_svn.fish:52 #, fuzzy -msgid "Check out a working copy from a repository." -msgstr "Eine lokale Kopie eines weiteren Paketdepots erstellen" - -#: share/functions/__fish_complete_svn.fish:53 -msgid "" -"Recursively clean up the working copy, removing locks, resuming unfinished " -"operations, etc." -msgstr "" +#~ msgid "Check out a working copy from a repository." +#~ msgstr "Eine lokale Kopie eines weiteren Paketdepots erstellen" -#: share/functions/__fish_complete_svn.fish:54 #, fuzzy -msgid "Send changes from your working copy to the repository." -msgstr "Änderungen der Arbeitskopie als Patch zum Paketdepot sichern" +#~ msgid "Send changes from your working copy to the repository." +#~ msgstr "Änderungen der Arbeitskopie als Patch zum Paketdepot sichern" -#: share/functions/__fish_complete_svn.fish:55 -msgid "Duplicate something in working copy or repository, remembering history." -msgstr "" - -#: share/functions/__fish_complete_svn.fish:56 #, fuzzy -msgid "Display the differences between two revisions or paths." -msgstr "Unterschiede zwischen Revisionen anzeigen" - -#: share/functions/__fish_complete_svn.fish:57 -msgid "Create an unversioned copy of a tree." -msgstr "" +#~ msgid "Display the differences between two revisions or paths." +#~ msgstr "Unterschiede zwischen Revisionen anzeigen" -#: share/functions/__fish_complete_svn.fish:58 -msgid "Describe the usage of this program or its subcommands." -msgstr "" - -#: share/functions/__fish_complete_svn.fish:59 #, fuzzy -msgid "Commit an unversioned file or tree into the repository." -msgstr "Neue/s Datei/Verzeichnis zum Paketdepot hinzufügen" +#~ msgid "Commit an unversioned file or tree into the repository." +#~ msgstr "Neue/s Datei/Verzeichnis zum Paketdepot hinzufügen" -#: share/functions/__fish_complete_svn.fish:60 #, fuzzy -msgid "Display information about a local or remote item." -msgstr "Statusinformationen zu ausgecheckten Dateien anzeigen" +#~ msgid "Display information about a local or remote item." +#~ msgstr "Statusinformationen zu ausgecheckten Dateien anzeigen" -#: share/functions/__fish_complete_svn.fish:61 #, fuzzy -msgid "List directory entries in the repository." -msgstr "Dateien in das Paketdepot übertragen" - -#: share/functions/__fish_complete_svn.fish:62 -msgid "" -"Lock working copy paths or URLs in the repository, so that no other user can " -"commit changes to them." -msgstr "" - -#: share/functions/__fish_complete_svn.fish:63 -msgid "Show the log messages for a set of revision(s) and/or file(s)." -msgstr "" - -#: share/functions/__fish_complete_svn.fish:64 -msgid "Apply the differences between two sources to a working copy path." -msgstr "" +#~ msgid "List directory entries in the repository." +#~ msgstr "Dateien in das Paketdepot übertragen" -#: share/functions/__fish_complete_svn.fish:65 #, fuzzy -msgid "Display information related to merges" -msgstr "Statusinformationen zu ausgecheckten Dateien anzeigen" +#~ msgid "Display information related to merges" +#~ msgstr "Statusinformationen zu ausgecheckten Dateien anzeigen" -#: share/functions/__fish_complete_svn.fish:66 -msgid "Create a new directory under version control." -msgstr "" - -#: share/functions/__fish_complete_svn.fish:67 #, fuzzy -msgid "Move and/or rename something in working copy or repository." -msgstr "Änderungen der Arbeitskopie als Patch zum Paketdepot sichern" +#~ msgid "Move and/or rename something in working copy or repository." +#~ msgstr "Änderungen der Arbeitskopie als Patch zum Paketdepot sichern" -#: share/functions/__fish_complete_svn.fish:68 #, fuzzy -msgid "Apply a unidiff patch to the working copy" -msgstr "Nicht aufgezeichnete Änderungen in der Arbeitskopie anzeigen" - -#: share/functions/__fish_complete_svn.fish:69 -msgid "Remove a property from files, dirs, or revisions." -msgstr "" - -#: share/functions/__fish_complete_svn.fish:70 -msgid "Edit a property with an external editor." -msgstr "" +#~ msgid "Apply a unidiff patch to the working copy" +#~ msgstr "Nicht aufgezeichnete Änderungen in der Arbeitskopie anzeigen" -#: share/functions/__fish_complete_svn.fish:71 -msgid "Print the value of a property on files, dirs, or revisions." -msgstr "" - -#: share/functions/__fish_complete_svn.fish:72 -msgid "List all properties on files, dirs, or revisions." -msgstr "" - -#: share/functions/__fish_complete_svn.fish:73 -msgid "Set the value of a property on files, dirs, or revisions." -msgstr "" - -#: share/functions/__fish_complete_svn.fish:74 -msgid "Rewrite working copy url metadata" -msgstr "" - -#: share/functions/__fish_complete_svn.fish:75 #, fuzzy -msgid "Remove files and directories from version control." -msgstr "Ein oder mehrere Dateien/Verzeichnisse aus dem Paketdepot entfernen" +#~ msgid "Remove files and directories from version control." +#~ msgstr "Ein oder mehrere Dateien/Verzeichnisse aus dem Paketdepot entfernen" -#: share/functions/__fish_complete_svn.fish:76 #, fuzzy -msgid "Remove conflicts on working copy files or directories." -msgstr "Eine/mehrere Datei/en oder Verzeichnis/se verschieben/umbenennen" +#~ msgid "Remove conflicts on working copy files or directories." +#~ msgstr "Eine/mehrere Datei/en oder Verzeichnis/se verschieben/umbenennen" -#: share/functions/__fish_complete_svn.fish:77 #, fuzzy -msgid "Remove \\conflicted state on working copy files or directories." -msgstr "Eine/mehrere Datei/en oder Verzeichnis/se verschieben/umbenennen" - -#: share/functions/__fish_complete_svn.fish:78 -msgid "Restore pristine working copy file (undo most local edits)." -msgstr "" - -#: share/functions/__fish_complete_svn.fish:79 -msgid "Print the status of working copy files and directories." -msgstr "" - -#: share/functions/__fish_complete_svn.fish:80 -msgid "Update the working copy to a different URL." -msgstr "" - -#: share/functions/__fish_complete_svn.fish:81 -msgid "Unlock working copy paths or URLs." -msgstr "" +#~ msgid "Remove \\conflicted state on working copy files or directories." +#~ msgstr "Eine/mehrere Datei/en oder Verzeichnis/se verschieben/umbenennen" -#: share/functions/__fish_complete_svn.fish:82 #, fuzzy -msgid "Bring changes from the repository into the working copy." -msgstr "Patches von einem anderen Paketdepot auf dieses kopieren und anwenden" +#~ msgid "Bring changes from the repository into the working copy." +#~ msgstr "" +#~ "Patches von einem anderen Paketdepot auf dieses kopieren und anwenden" -#: share/functions/__fish_complete_svn.fish:83 -msgid "Upgrade the metadata storage format for a working copy." -msgstr "" - -#: share/functions/__fish_complete_svn.fish:90 #, fuzzy -msgid "Do not cache authentication tokens" -msgstr "Überprüfungsstatus von Schlüsselsignaturen nicht zwischenspeichern" +#~ msgid "Do not cache authentication tokens" +#~ msgstr "Überprüfungsstatus von Schlüsselsignaturen nicht zwischenspeichern" -#: share/functions/__fish_complete_svn.fish:91 #, fuzzy -msgid "Do no interactive prompting" -msgstr "Ausführung im interaktiven Modus" - -#: share/functions/__fish_complete_svn.fish:92 -msgid "" -"Accept SSL server certificates from unknown authorities (ony with --non-" -"interactive)" -msgstr "" +#~ msgid "Do no interactive prompting" +#~ msgstr "Ausführung im interaktiven Modus" -#: share/functions/__fish_complete_svn.fish:103 #, fuzzy -msgid "Specify log message" -msgstr "E-Mail-Adresse angeben" +#~ msgid "Specify log message" +#~ msgstr "E-Mail-Adresse angeben" -#: share/functions/__fish_complete_svn.fish:105 #, fuzzy -msgid "Read log message from file" -msgstr "Paket aus Datei lesen" +#~ msgid "Read log message from file" +#~ msgstr "Paket aus Datei lesen" -#: share/functions/__fish_complete_svn.fish:106 -msgid "Force validity of log message source" -msgstr "" - -#: share/functions/__fish_complete_svn.fish:118 #, fuzzy -msgid "Print nothing, or only summary information" -msgstr "Verlaufsinformationen für Dateien ausgeben" +#~ msgid "Print nothing, or only summary information" +#~ msgstr "Verlaufsinformationen für Dateien ausgeben" -#: share/functions/__fish_complete_svn.fish:122 #, fuzzy -msgid "Force operation to run" -msgstr "Löschung erzwingen" - -#: share/functions/__fish_complete_svn.fish:126 -msgid "Process contents of file ARG as additional args" -msgstr "" +#~ msgid "Force operation to run" +#~ msgstr "Löschung erzwingen" -#: share/functions/__fish_complete_svn.fish:130 -msgid "Operate only on members of changelist" -msgstr "" - -#: share/functions/__fish_complete_svn.fish:134 #, fuzzy -msgid "Output in xml" -msgstr "Ausgabedatei" +#~ msgid "Output in xml" +#~ msgstr "Ausgabedatei" -#: share/functions/__fish_complete_svn.fish:138 #, fuzzy -msgid "Retrieve revision property" -msgstr "Eigenschaft entfernen" +#~ msgid "Retrieve revision property" +#~ msgstr "Eigenschaft entfernen" -#: share/functions/__fish_complete_svn.fish:150 #, fuzzy -msgid "Ignore externals definitions" -msgstr "Sämtliche Versions-Informationen ignorieren" +#~ msgid "Ignore externals definitions" +#~ msgstr "Sämtliche Versions-Informationen ignorieren" -#: share/functions/__fish_complete_svn.fish:154 #, fuzzy -msgid "Print extra information" -msgstr "Alle Informationen ausgeben" - -#: share/functions/__fish_complete_svn.fish:158 -msgid "Operate on a revision property (use with -r)" -msgstr "" - -#: share/functions/__fish_complete_svn.fish:162 -msgid "Add intermediate parents" -msgstr "" +#~ msgid "Print extra information" +#~ msgstr "Alle Informationen ausgeben" -#: share/functions/__fish_complete_svn.fish:189 #, fuzzy -msgid "Try operation but make no changes" -msgstr "Versuche, eine kleinere Menge Änderungen zu finden" +#~ msgid "Try operation but make no changes" +#~ msgstr "Versuche, eine kleinere Menge Änderungen zu finden" -#: share/functions/__fish_complete_svn.fish:193 #, fuzzy -msgid "Ignore ancestry when calculating merges" -msgstr "Benutzername für Zeitberechnungen ignorieren" +#~ msgid "Ignore ancestry when calculating merges" +#~ msgstr "Benutzername für Zeitberechnungen ignorieren" -#: share/functions/__fish_complete_svn.fish:197 -msgid "Override diff-cmd specified in config file" -msgstr "" - -#: share/functions/__fish_complete_svn.fish:198 #, fuzzy -msgid "Use external diff command" -msgstr "Bearbeiten-Befehl rückgängig machen" +#~ msgid "Use external diff command" +#~ msgstr "Bearbeiten-Befehl rückgängig machen" -#: share/functions/__fish_complete_svn.fish:202 #, fuzzy -msgid "Disable automatic properties" -msgstr "Zeichensatzeigenschaften anzeigen" - -#: share/functions/__fish_complete_svn.fish:206 -msgid "Set new working copy depth" -msgstr "" - -#: share/functions/__fish_complete_svn.fish:230 -msgid "don\\t" -msgstr "" - -#: share/functions/__fish_complete_svn.fish:241 -msgid "Use ARG as the older target" -msgstr "" +#~ msgid "Disable automatic properties" +#~ msgstr "Zeichensatzeigenschaften anzeigen" -#: share/functions/__fish_complete_svn.fish:242 -msgid "Use ARG as the newer target" -msgstr "" - -#: share/functions/__fish_complete_svn.fish:243 #, fuzzy -msgid "Do not print differences for deleted files" -msgstr "Zeilen nicht ohne Begrenzer ausgeben" - -#: share/functions/__fish_complete_svn.fish:244 -msgid "Notice ancestry when calculating differences" -msgstr "" - -#: share/functions/__fish_complete_svn.fish:245 -msgid "Show a summary of the results" -msgstr "" - -#: share/functions/__fish_complete_svn.fish:257 -msgid "Do not cross copies while traversing history" -msgstr "" +#~ msgid "Do not print differences for deleted files" +#~ msgstr "Zeilen nicht ohne Begrenzer ausgeben" -#: share/functions/__fish_complete_svn.fish:259 #, fuzzy -msgid "Produce diff output" -msgstr "Audio-Ausgabe" +#~ msgid "Produce diff output" +#~ msgstr "Audio-Ausgabe" -#: share/functions/__fish_complete_svn.fish:279 #, fuzzy -msgid "Use strict semantics" -msgstr "Einstellung für Schnelligkeit verwenden" +#~ msgid "Use strict semantics" +#~ msgstr "Einstellung für Schnelligkeit verwenden" -#: share/functions/__fish_complete_svn.fish:306 -msgid "Relocate via URL-rewriting" -msgstr "" - -#: share/functions/__fish_complete_svn_diff.fish:1 -msgid "Complete \"svn diff\" arguments" -msgstr "" - -#: share/functions/__fish_complete_tar.fish:14 -#: share/functions/__fish_complete_tar.fish:21 -#: share/functions/__fish_complete_tar.fish:28 -#: share/functions/__fish_complete_unrar.fish:14 #, fuzzy -msgid "%s\\tArchived file\\n" -msgstr "Archiv-Datei" +#~ msgid "%s\\tArchived file\\n" +#~ msgstr "Archiv-Datei" -#: share/functions/__fish_complete_users.fish:2 -msgid "Print a list of local users, with the real user name as a description" -msgstr "" - -#: share/functions/__fish_complete_vi.fish:37 #, fuzzy -msgid "Start in Arabic mode" -msgstr "Schnittstelle starten" +#~ msgid "Start in Arabic mode" +#~ msgstr "Schnittstelle starten" -#: share/functions/__fish_complete_vi.fish:38 #, fuzzy -msgid "Start in binary mode" -msgstr "Standardmodus" - -#: share/functions/__fish_complete_vi.fish:39 -msgid "Behave mostly like vi" -msgstr "" +#~ msgid "Start in binary mode" +#~ msgstr "Standardmodus" -#: share/functions/__fish_complete_vi.fish:40 #, fuzzy -msgid "Start in diff mode" -msgstr "Im Ordner-Index starten" +#~ msgid "Start in diff mode" +#~ msgstr "Im Ordner-Index starten" -#: share/functions/__fish_complete_vi.fish:41 #, fuzzy -msgid "Debugging mode" -msgstr "Debug-Modus" +#~ msgid "Debugging mode" +#~ msgstr "Debug-Modus" -#: share/functions/__fish_complete_vi.fish:42 #, fuzzy -msgid "Start in Ex mode" -msgstr "Im Ordner-Index starten" +#~ msgid "Start in Ex mode" +#~ msgstr "Im Ordner-Index starten" -#: share/functions/__fish_complete_vi.fish:43 #, fuzzy -msgid "Start in improved Ex mode" -msgstr "Im Ordner-Index starten" +#~ msgid "Start in improved Ex mode" +#~ msgstr "Im Ordner-Index starten" -#: share/functions/__fish_complete_vi.fish:44 -#: share/functions/__fish_complete_vi.fish:67 #, fuzzy -msgid "Start in foreground mode" -msgstr "Im Ordner-Index starten" +#~ msgid "Start in foreground mode" +#~ msgstr "Im Ordner-Index starten" -#: share/functions/__fish_complete_vi.fish:45 #, fuzzy -msgid "Start in Farsi mode" -msgstr "Standardmodus" +#~ msgid "Start in Farsi mode" +#~ msgstr "Standardmodus" -#: share/functions/__fish_complete_vi.fish:46 #, fuzzy -msgid "Start in GUI mode" -msgstr "Im Ordner-Index starten" +#~ msgid "Start in GUI mode" +#~ msgstr "Im Ordner-Index starten" -#: share/functions/__fish_complete_vi.fish:47 -#: share/functions/__fish_complete_vi.fish:69 #, fuzzy -msgid "Print help message and exit" -msgstr "Hilfe anzeigen und beenden" +#~ msgid "Print help message and exit" +#~ msgstr "Hilfe anzeigen und beenden" -#: share/functions/__fish_complete_vi.fish:48 #, fuzzy -msgid "Start in Hebrew mode" -msgstr "Im Ordner-Index starten" +#~ msgid "Start in Hebrew mode" +#~ msgstr "Im Ordner-Index starten" -#: share/functions/__fish_complete_vi.fish:49 -msgid "List swap files" -msgstr "" - -#: share/functions/__fish_complete_vi.fish:50 #, fuzzy -msgid "Start in lisp mode" -msgstr "Im Ordner-Index starten" +#~ msgid "Start in lisp mode" +#~ msgstr "Im Ordner-Index starten" -#: share/functions/__fish_complete_vi.fish:51 #, fuzzy -msgid "Disable file modification" -msgstr "Nicht auf die Veränderungszeiten der Dateien vertrauen" +#~ msgid "Disable file modification" +#~ msgstr "Nicht auf die Veränderungszeiten der Dateien vertrauen" -#: share/functions/__fish_complete_vi.fish:52 #, fuzzy -msgid "Disallow file modification" -msgstr "Änderungsdatum anzeigen" - -#: share/functions/__fish_complete_vi.fish:53 -msgid "Reset compatibility mode" -msgstr "" +#~ msgid "Disallow file modification" +#~ msgstr "Änderungsdatum anzeigen" -#: share/functions/__fish_complete_vi.fish:62 #, fuzzy -msgid "Start in easy mode" -msgstr "Im Ordner-Index starten" +#~ msgid "Start in easy mode" +#~ msgstr "Im Ordner-Index starten" -#: share/functions/__fish_complete_vi.fish:63 #, fuzzy -msgid "Start in restricted mode" -msgstr "Beschränkter Modus" - -#: share/functions/__fish_complete_vi.fish:65 -msgid "Become an editor server for NetBeans" -msgstr "" +#~ msgid "Start in restricted mode" +#~ msgstr "Beschränkter Modus" -#: share/functions/__fish_complete_vi.fish:68 -msgid "Echo the Window ID on stdout (GTK GUI only)" -msgstr "" - -#: share/functions/__fish_complete_vi.fish:70 #, fuzzy -msgid "Do not expand wildcards" -msgstr "Erweitern Sie das Muster nicht" - -#: share/functions/__fish_complete_vi.fish:71 -msgid "Skip loading plugins" -msgstr "" +#~ msgid "Do not expand wildcards" +#~ msgstr "Erweitern Sie das Muster nicht" -#: share/functions/__fish_complete_vi.fish:72 -#: share/functions/__fish_complete_vi.fish:75 -#: share/functions/__fish_complete_vi.fish:76 -#: share/functions/__fish_complete_vi.fish:77 #, fuzzy -msgid "Edit files on Vim server" -msgstr "Originaldateien editieren" +#~ msgid "Edit files on Vim server" +#~ msgstr "Originaldateien editieren" -#: share/functions/__fish_complete_vi.fish:73 #, fuzzy -msgid "Evaluate expr on Vim server" -msgstr "Ausdruck auswerten" +#~ msgid "Evaluate expr on Vim server" +#~ msgstr "Ausdruck auswerten" -#: share/functions/__fish_complete_vi.fish:74 #, fuzzy -msgid "Send keys to Vim server" -msgstr "Mail an Benutzer senden" +#~ msgid "Send keys to Vim server" +#~ msgstr "Mail an Benutzer senden" -#: share/functions/__fish_complete_vi.fish:78 -msgid "List all Vim servers that can be found" -msgstr "" - -#: share/functions/__fish_complete_vi.fish:79 #, fuzzy -msgid "Set server name" -msgstr "Dienstname" +#~ msgid "Set server name" +#~ msgstr "Dienstname" -#: share/functions/__fish_complete_vi.fish:80 #, fuzzy -msgid "Print version information and exit" -msgstr "Sämtliche Versions-Informationen ignorieren" - -#: share/functions/__fish_complete_vi.fish:91 -msgid "Suppress all interactive user feedback" -msgstr "" +#~ msgid "Print version information and exit" +#~ msgstr "Sämtliche Versions-Informationen ignorieren" -#: share/functions/__fish_complete_vi.fish:92 -#: share/functions/__fish_complete_vi.fish:99 -msgid "Encrypt/decrypt text" -msgstr "" - -#: share/functions/__fish_complete_vi.fish:93 -msgid "Set up for editing LISP programs" -msgstr "" - -#: share/functions/__fish_complete_vi.fish:94 -msgid "List saved file names after crash" -msgstr "" - -#: share/functions/__fish_complete_vi.fish:95 #, fuzzy -msgid "Read-only mode" -msgstr "Nur lesen" - -#: share/functions/__fish_complete_vi.fish:96 -msgid "Use linear search for tags if tag file not sorted" -msgstr "" +#~ msgid "Read-only mode" +#~ msgstr "Nur lesen" -#: share/functions/__fish_complete_vi.fish:97 -msgid "Start in display editing state" -msgstr "" +#~ msgid "Welcome to fish, the friendly interactive shell" +#~ msgstr "Willkommen zu fish, der freundlichen interaktiven Shell" -#: share/functions/__fish_complete_wvdial_peers.fish:1 -msgid "Complete wvdial peers" -msgstr "" +#~ msgid "Type %shelp%s for instructions on how to use fish" +#~ msgstr "Anweisungen zur fish-Benutzung erhalten Sie über %shelp%s" -#: share/functions/__fish_complete_xsum.fish:1 -msgid "Complete md5sum sha1 etc" -msgstr "" +#~ msgid "Start service" +#~ msgstr "Dienst starten" -#: share/functions/__fish_config_interactive.fish:34 -msgid "Welcome to fish, the friendly interactive shell" -msgstr "Willkommen zu fish, der freundlichen interaktiven Shell" +#~ msgid "Stop service" +#~ msgstr "Dienst anhalten" -#: share/functions/__fish_config_interactive.fish:35 -msgid "Type %shelp%s for instructions on how to use fish" -msgstr "Anweisungen zur fish-Benutzung erhalten Sie über %shelp%s" - -#: share/functions/__fish_config_interactive.fish:130 -msgid "Event handler, repaints the prompt when fish_color_cwd changes" -msgstr "" - -#: share/functions/__fish_config_interactive.fish:137 -msgid "Event handler, repaints the prompt when fish_color_cwd_root changes" -msgstr "" - -#: share/functions/__fish_config_interactive.fish:149 -msgid "Start service" -msgstr "Dienst starten" - -#: share/functions/__fish_config_interactive.fish:150 -msgid "Stop service" -msgstr "Dienst anhalten" - -#: share/functions/__fish_config_interactive.fish:151 #, fuzzy -msgid "Print service status" -msgstr "Dienststatus ausgeben" - -#: share/functions/__fish_config_interactive.fish:152 -msgid "Stop and then start service" -msgstr "Stoppe und starte Dienst" - -#: share/functions/__fish_config_interactive.fish:153 -msgid "Reload service configuration" -msgstr "Dienstkonfiguration neu laden" +#~ msgid "Print service status" +#~ msgstr "Dienststatus ausgeben" -#: share/functions/__fish_config_interactive.fish:193 -#, sh-format -msgid "Notify VTE of change to $PWD" -msgstr "" +#~ msgid "Stop and then start service" +#~ msgstr "Stoppe und starte Dienst" -#: share/functions/__fish_git_prompt.fish:173 -msgid "Helper function for __fish_git_prompt" -msgstr "" +#~ msgid "Reload service configuration" +#~ msgstr "Dienstkonfiguration neu laden" -#: share/functions/__fish_git_prompt.fish:348 #, fuzzy -msgid "Prompt function for Git" -msgstr "Aktuelle Funktionen sind: " +#~ msgid "Prompt function for Git" +#~ msgstr "Aktuelle Funktionen sind: " -#: share/functions/__fish_git_prompt.fish:458 -msgid "" -"__fish_git_prompt helper, tells whether or not the current branch has staged " -"files" -msgstr "" - -#: share/functions/__fish_git_prompt.fish:471 -msgid "" -"__fish_git_prompt helper, tells whether or not the current branch has " -"tracked, modified files" -msgstr "" - -#: share/functions/__fish_git_prompt.fish:526 -msgid "__fish_git_prompt helper, returns the current Git operation and branch" -msgstr "" - -#: share/functions/__fish_git_prompt.fish:639 -msgid "__fish_git_prompt helper, checks char variables" -msgstr "" - -#: share/functions/__fish_git_prompt.fish:690 -msgid "__fish_git_prompt helper, checks color variables" -msgstr "" - -#: share/functions/__fish_git_prompt.fish:730 -msgid "Event handler, repaints prompt when functionality changes" -msgstr "" - -#: share/functions/__fish_git_prompt.fish:748 -msgid "Event handler, repaints prompt when any color changes" -msgstr "" - -#: share/functions/__fish_git_prompt.fish:768 -msgid "Event handler, repaints prompt when any char changes" -msgstr "" - -#: share/functions/__fish_hg_prompt.fish:23 #, fuzzy -msgid "Write out the hg prompt" -msgstr "Prompt ausgeben" +#~ msgid "Write out the hg prompt" +#~ msgstr "Prompt ausgeben" -#: share/functions/__fish_is_token_n.fish:1 -msgid "Test if current token is on Nth place" -msgstr "" +#~ msgid "Hit end of history...\\n" +#~ msgstr "Ende des Befehlsverlaufs errreicht ...\\n" -#: share/functions/__fish_make_completion_signals.fish:1 -msgid "Make list of kill signals for completion" -msgstr "" - -#: share/functions/__fish_move_last.fish:9 -msgid "Hit end of history...\\n" -msgstr "Ende des Befehlsverlaufs errreicht ...\\n" - -#: share/functions/__fish_print_abook_emails.fish:1 #, fuzzy -msgid "Print email addresses (abook)" -msgstr "Tote Prozesse ausgeben" +#~ msgid "Print email addresses (abook)" +#~ msgstr "Tote Prozesse ausgeben" -#: share/functions/__fish_print_addresses.fish:1 #, fuzzy -msgid "Print a list of known network addresses" -msgstr "Liste laufender screen-Sitzungen ausgeben" +#~ msgid "Print a list of known network addresses" +#~ msgstr "Liste laufender screen-Sitzungen ausgeben" -#: share/functions/__fish_print_arch_daemons.fish:1 #, fuzzy -msgid "Print arch daemons" -msgstr "Alle Namen ausgeben" +#~ msgid "Print arch daemons" +#~ msgstr "Alle Namen ausgeben" -#: share/functions/__fish_print_commands.fish:1 #, fuzzy -msgid "Print a list of documented fish commands" -msgstr "Liste laufender screen-Sitzungen ausgeben" +#~ msgid "Print a list of documented fish commands" +#~ msgstr "Liste laufender screen-Sitzungen ausgeben" -#: share/functions/__fish_print_debian_services.fish:1 #, fuzzy -msgid "Prints services installed" -msgstr "Dienststatus ausgeben" +#~ msgid "Prints services installed" +#~ msgstr "Dienststatus ausgeben" -#: share/functions/__fish_print_help.fish:1 -msgid "Print help message for the specified fish function or builtin" -msgstr "" - -#: share/functions/__fish_print_interfaces.fish:1 #, fuzzy -msgid "Print a list of known network interfaces" -msgstr "Liste laufender screen-Sitzungen ausgeben" +#~ msgid "Print a list of known network interfaces" +#~ msgstr "Liste laufender screen-Sitzungen ausgeben" -#: share/functions/__fish_print_lpr_options.fish:1 #, fuzzy -msgid "Print lpr options" -msgstr "Alle Versionen ausgeben" +#~ msgid "Print lpr options" +#~ msgstr "Alle Versionen ausgeben" -#: share/functions/__fish_print_lpr_printers.fish:1 #, fuzzy -msgid "Print lpr printers" -msgstr "Vollständige Datensätze ausgeben" +#~ msgid "Print lpr printers" +#~ msgstr "Vollständige Datensätze ausgeben" -#: share/functions/__fish_print_lsblk_columns.fish:1 #, fuzzy -msgid "Print available lsblk columns" -msgstr "Verfügbare Liste ausgeben" +#~ msgid "Print available lsblk columns" +#~ msgstr "Verfügbare Liste ausgeben" -#: share/functions/__fish_print_mounted.fish:1 #, fuzzy -msgid "Print mounted devices" -msgstr "Wichtige Abhängigkeiten ausgeben" +#~ msgid "Print mounted devices" +#~ msgstr "Wichtige Abhängigkeiten ausgeben" -#: share/functions/__fish_print_packages.fish:13 -msgid "Package" -msgstr "Paket" +#~ msgid "Package" +#~ msgstr "Paket" -#: share/functions/__fish_print_svn_rev.fish:1 #, fuzzy -msgid "Print svn revisions" -msgstr "PKG-Versionen ausgeben" +#~ msgid "Print svn revisions" +#~ msgstr "PKG-Versionen ausgeben" -#: share/functions/__fish_print_users.fish:2 #, fuzzy -msgid "Print a list of local users" -msgstr "Liste laufender screen-Sitzungen ausgeben" - -#: share/functions/__fish_print_xdg_mimeapps.fish:1 -msgid "Print xdg mime applications" -msgstr "" +#~ msgid "Print a list of local users" +#~ msgstr "Liste laufender screen-Sitzungen ausgeben" -#: share/functions/__fish_print_xdg_mimetypes.fish:1 #, fuzzy -msgid "Print XDG mime types" -msgstr "Befehlstyp ausgeben" +#~ msgid "Print XDG mime types" +#~ msgstr "Befehlstyp ausgeben" -#: share/functions/__fish_print_xrandr_modes.fish:1 #, fuzzy -msgid "Print xrandr modes" -msgstr "Roheinträge ausgeben" +#~ msgid "Print xrandr modes" +#~ msgstr "Roheinträge ausgeben" -#: share/functions/__fish_print_xrandr_outputs.fish:1 #, fuzzy -msgid "Print xrandr outputs" -msgstr "Wortzählung ausgeben" +#~ msgid "Print xrandr outputs" +#~ msgstr "Wortzählung ausgeben" -#: share/functions/__fish_print_xwindows.fish:1 #, fuzzy -msgid "Print X windows" -msgstr "APM-Informationen ausgeben" +#~ msgid "Print X windows" +#~ msgstr "APM-Informationen ausgeben" -#: share/functions/__fish_pwd.fish:3 share/functions/__fish_pwd.fish:7 #, fuzzy -msgid "Show current path" -msgstr "Quellpaket anzeigen" +#~ msgid "Show current path" +#~ msgstr "Quellpaket anzeigen" -#: share/functions/__fish_test_arg.fish:2 -msgid "Test if the token under the cursor matches the specified wildcard" -msgstr "" - -#: share/functions/__fish_urlencode.fish:1 #, fuzzy -msgid "URL-encode stdin" -msgstr "Standardeingabe umbenennen" +#~ msgid "URL-encode stdin" +#~ msgstr "Standardeingabe umbenennen" -#: share/functions/__terlar_git_prompt.fish:23 #, fuzzy -msgid "Write out the git prompt" -msgstr "Prompt ausgeben" +#~ msgid "Write out the git prompt" +#~ msgstr "Prompt ausgeben" -#: share/functions/abbr.fish:1 #, fuzzy -msgid "Manage abbreviations" -msgstr "Handbuch-Sektionen" +#~ msgid "Manage abbreviations" +#~ msgstr "Handbuch-Sektionen" -#: share/functions/abbr.fish:40 #, fuzzy -msgid "%s: invalid option -- %s\\n" -msgstr "%ls: Ungültige Prozesskennung %ls\n" +#~ msgid "%s: invalid option -- %s\\n" +#~ msgstr "%ls: Ungültige Prozesskennung %ls\n" -#: share/functions/abbr.fish:47 #, fuzzy -msgid "%s: %s cannot be specified along with %s\\n" -msgstr "" -"%ls: Bei erase können keine Werte angegeben werden\n" -"%ls\n" +#~ msgid "%s: %s cannot be specified along with %s\\n" +#~ msgstr "" +#~ "%ls: Bei erase können keine Werte angegeben werden\n" +#~ "%ls\n" -#: share/functions/abbr.fish:56 #, fuzzy -msgid "%s: option requires an argument -- %s\\n" -msgstr "%ls: Erwartete ein Argument, erhielt %d\n" +#~ msgid "%s: option requires an argument -- %s\\n" +#~ msgstr "%ls: Erwartete ein Argument, erhielt %d\n" -#: share/functions/abbr.fish:62 #, fuzzy -msgid "%s: Unexpected argument -- %s\\n" -msgstr "%ls: Argument erwartet\n" - -#: share/functions/abbr.fish:75 -msgid "%s: abbreviation must have a non-empty key\\n" -msgstr "" - -#: share/functions/abbr.fish:79 -msgid "%s: abbreviation must have a value\\n" -msgstr "" +#~ msgid "%s: no such abbreviation '%s'\\n" +#~ msgstr "Unbekannte Funktion '%ls'" -#: share/functions/abbr.fish:101 #, fuzzy -msgid "%s: no such abbreviation '%s'\\n" -msgstr "Unbekannte Funktion '%ls'" +#~ msgid "%s: Expected one or two arguments, got %d\\n" +#~ msgstr "%ls: Erwartete ein Argument, erhielt %d\n" -#: share/functions/alias.fish:2 -msgid "" -"Legacy function for creating shellscript functions using an alias-like syntax" -msgstr "" - -#: share/functions/alias.fish:36 #, fuzzy -msgid "%s: Expected one or two arguments, got %d\\n" -msgstr "%ls: Erwartete ein Argument, erhielt %d\n" +#~ msgid "%s: Name cannot be empty\\n" +#~ msgstr "%ls: Variablenname kann nicht leer sein\n" -#: share/functions/alias.fish:42 #, fuzzy -msgid "%s: Name cannot be empty\\n" -msgstr "%ls: Variablenname kann nicht leer sein\n" - -#: share/functions/alias.fish:45 -msgid "%s: Body cannot be empty\\n" -msgstr "" +#~ msgid "Print directory stack" +#~ msgstr "Verzeichnisnamen ausgeben" -#: share/functions/contains_seq.fish:1 -msgid "Return true if array contains a sequence" -msgstr "" +#~ msgid "Write out the prompt" +#~ msgstr "Prompt ausgeben" -#: share/functions/dirh.fish:2 -msgid "Print the current directory history (the back- and fwd- lists)" -msgstr "" - -#: share/functions/dirs.fish:1 #, fuzzy -msgid "Print directory stack" -msgstr "Verzeichnisnamen ausgeben" - -#: share/functions/export.fish:1 -msgid "Set global variable. Alias for set -g, made for bash compatibility" -msgstr "" +#~ msgid "Update man-page based completions" +#~ msgstr "Befehlsspezifische Erweiterungen bearbeiten" -#: share/functions/fish_config.fish:1 -msgid "Launch fish's web based configuration" -msgstr "" - -#: share/functions/fish_indent.fish:1 -msgid "Indenter and prettifier for fish code" -msgstr "" - -#: share/functions/fish_prompt.fish:5 -msgid "Write out the prompt" -msgstr "Prompt ausgeben" - -#: share/functions/fish_update_completions.fish:1 #, fuzzy -msgid "Update man-page based completions" -msgstr "Befehlsspezifische Erweiterungen bearbeiten" +#~ msgid "vi-like key bindings for fish" +#~ msgstr "Datei mit Tastaturbindungen angeben" -#: share/functions/fish_vi_key_bindings.fish:1 #, fuzzy -msgid "vi-like key bindings for fish" -msgstr "Datei mit Tastaturbindungen angeben" +#~ msgid "Displays the current mode" +#~ msgstr "Version anzeigen und beenden" -#: share/functions/fish_vi_prompt.fish:1 #, fuzzy -msgid "Displays the current mode" -msgstr "Version anzeigen und beenden" - -#: share/functions/fish_vi_prompt.fish:17 -msgid "Simple vi prompt" -msgstr "" +#~ msgid "Edit function definition" +#~ msgstr "Funktionsdefinitonsblock" -#: share/functions/funced.fish:1 #, fuzzy -msgid "Edit function definition" -msgstr "Funktionsdefinitonsblock" +#~ msgid "%s: Unknown option %s\\n" +#~ msgstr "%ls: Unbekannte Option '%ls'\n" -#: share/functions/funced.fish:24 share/functions/nextd.fish:22 -#: share/functions/prevd.fish:22 share/functions/vared.fish:15 #, fuzzy -msgid "%s: Unknown option %s\\n" -msgstr "%ls: Unbekannte Option '%ls'\n" +#~ msgid "funced: You must specify one function name\n" +#~ msgstr "%ls: Erwartete genau einen Funktionsnamen\n" -#: share/functions/funced.fish:36 #, fuzzy -msgid "funced: You must specify one function name\n" -msgstr "%ls: Erwartete genau einen Funktionsnamen\n" +#~ msgid "Cancelled function editing" +#~ msgstr "Funktionsdefinitonsblock" -#: share/functions/funced.fish:96 -msgid "Editing failed or was cancelled" -msgstr "" - -#: share/functions/funced.fish:103 -msgid "Edit the file again\\? [Y/n]" -msgstr "" - -#: share/functions/funced.fish:110 #, fuzzy -msgid "Cancelled function editing" -msgstr "Funktionsdefinitonsblock" +#~ msgid "%s: Expected function name\\n" +#~ msgstr "%ls: Erwartete genau einen Funktionsnamen\n" -#: share/functions/funcsave.fish:2 -msgid "Save the current definition of all specified functions to file" -msgstr "" - -#: share/functions/funcsave.fish:11 #, fuzzy -msgid "%s: Expected function name\\n" -msgstr "%ls: Erwartete genau einen Funktionsnamen\n" +#~ msgid "%s: Could not create configuration directory\\n" +#~ msgstr "%ls: Konnte Startverzeichnis nicht finden\n" -#: share/functions/funcsave.fish:26 #, fuzzy -msgid "%s: Could not create configuration directory\\n" -msgstr "%ls: Konnte Startverzeichnis nicht finden\n" - -#: share/functions/funcsave.fish:36 -#, fuzzy -msgid "%s: Unknown function '%s'\\n" -msgstr "Unbekannte Funktion '%ls'" - -#: share/functions/help.fish:1 -msgid "Show help for the fish shell" -msgstr "" - -#: share/functions/help.fish:76 -msgid "%s: Could not find a web browser.\\n" -msgstr "Konnte keinen Webbrowser finden.\\n" +#~ msgid "%s: Unknown function '%s'\\n" +#~ msgstr "Unbekannte Funktion '%ls'" -#: share/functions/help.fish:77 -#, fuzzy, sh-format -msgid "" -"Please set the variable $BROWSER to a suitable browser and try again.\\n\\n" -msgstr "" -"Legen Sie bitte die Variable $BROWSER auf einen passenden Browser festund " -"versuchen Sie es erneut\\n\\n" +#~ msgid "%s: Could not find a web browser.\\n" +#~ msgstr "Konnte keinen Webbrowser finden.\\n" -#: share/functions/help.fish:129 -msgid "help: Help is being displayed in your default browser.\\n" -msgstr "" - -#: share/functions/help.fish:132 -msgid "help: Help is being displayed in %s.\\n" -msgstr "" - -#: share/functions/history.fish:5 #, fuzzy -msgid "Deletes an item from history" -msgstr "Einen Eintrag aus dem Paketdepot entfernen" - -#: share/functions/hostname.fish:7 -msgid "Show or set the system's host name\r" -msgstr "" - -#: share/functions/la.fish:4 -msgid "" -"List contents of directory, including hidden files in directory using long " -"format" -msgstr "" +#~ msgid "" +#~ "Please set the variable $BROWSER to a suitable browser and try again.\\n" +#~ "\\n" +#~ msgstr "" +#~ "Legen Sie bitte die Variable $BROWSER auf einen passenden Browser festund " +#~ "versuchen Sie es erneut\\n\\n" -#: share/functions/ll.fish:4 -msgid "List contents of directory using long format" -msgstr "" - -#: share/functions/ls.fish:7 share/functions/ls.fish:32 #, fuzzy -msgid "List contents of directory" -msgstr "Startverzeichnis festlegen" - -#: share/functions/man.fish:1 -msgid "Format and display the on-line manual pages" -msgstr "" +#~ msgid "Deletes an item from history" +#~ msgstr "Einen Eintrag aus dem Paketdepot entfernen" -#: share/functions/math.fish:2 #, fuzzy -msgid "Perform math calculations in bc" -msgstr "Simulation durchführen" - -#: share/functions/mimedb.fish:8 -msgid "Look up file information via the mimedb database" -msgstr "" +#~ msgid "List contents of directory" +#~ msgstr "Startverzeichnis festlegen" -#: share/functions/nextd.fish:2 #, fuzzy -msgid "Move forward in the directory history" -msgstr "Auch Verzeichnisverlauf ausgeben" +#~ msgid "Perform math calculations in bc" +#~ msgstr "Simulation durchführen" -#: share/functions/nextd.fish:28 #, fuzzy -msgid "%s: The number of positions to skip must be a non-negative integer\\n" -msgstr "" -"Anzahl zu überspringender Positionen muss eine positive Ganzzahl sein\\n" +#~ msgid "Move forward in the directory history" +#~ msgstr "Auch Verzeichnisverlauf ausgeben" -#: share/functions/open.fish:8 -msgid "Open file in default application" -msgstr "" - -#: share/functions/popd.fish:2 -msgid "Pop dir from stack" -msgstr "" - -#: share/functions/popd.fish:14 -msgid "%s: Directory stack is empty...\\n" -msgstr "" - -#: share/functions/prevd.fish:2 #, fuzzy -msgid "Move back in the directory history" -msgstr "Auch Verzeichnisverlauf ausgeben" - -#: share/functions/prevd.fish:28 -msgid "The number of positions to skip must be a non-negative integer\\n" -msgstr "" -"Anzahl zu überspringender Positionen muss eine positive Ganzzahl sein\\n" +#~ msgid "" +#~ "%s: The number of positions to skip must be a non-negative integer\\n" +#~ msgstr "" +#~ "Anzahl zu überspringender Positionen muss eine positive Ganzzahl sein\\n" -#: share/functions/prompt_pwd.fish:11 -msgid "Print the current working directory, shortened to fit the prompt" -msgstr "" +#, fuzzy +#~ msgid "Move back in the directory history" +#~ msgstr "Auch Verzeichnisverlauf ausgeben" -#: share/functions/psub.fish:3 -msgid "" -"Read from stdin into a file and output the filename. Remove the file when " -"the command that called psub exits." -msgstr "" +#~ msgid "The number of positions to skip must be a non-negative integer\\n" +#~ msgstr "" +#~ "Anzahl zu überspringender Positionen muss eine positive Ganzzahl sein\\n" -#: share/functions/pushd.fish:3 #, fuzzy -msgid "Push directory to stack" -msgstr "Verzeichnis nach makefile durchsuchen" +#~ msgid "Push directory to stack" +#~ msgstr "Verzeichnis nach makefile durchsuchen" -#: share/functions/seq.fish:7 #, fuzzy -msgid "Print sequences of numbers" -msgstr "Name statt Nummer ausgeben" - -#: share/functions/seq.fish:11 -msgid "Fallback implementation of the seq command" -msgstr "" +#~ msgid "Print sequences of numbers" +#~ msgstr "Name statt Nummer ausgeben" -#: share/functions/seq.fish:31 #, fuzzy -msgid "%s: Expected 1, 2 or 3 arguments, got %d\\n" -msgstr "%ls: Erwartete ein Argument, erhielt %d\n" +#~ msgid "%s: Expected 1, 2 or 3 arguments, got %d\\n" +#~ msgstr "%ls: Erwartete ein Argument, erhielt %d\n" -#: share/functions/seq.fish:38 #, fuzzy -msgid "%s: '%s' is not a number\\n" -msgstr "%ls: '%ls' ist kein Job\n" - -#: share/functions/setenv.fish:2 -msgid "Set global variable. Alias for set -g, made for csh compatibility" -msgstr "" +#~ msgid "%s: '%s' is not a number\\n" +#~ msgstr "%ls: '%ls' ist kein Job\n" -#: share/functions/type.fish:2 #, fuzzy -msgid "Print the type of a command" -msgstr "Pfad zu Befehl ausgeben" +#~ msgid "Print the type of a command" +#~ msgstr "Pfad zu Befehl ausgeben" -#: share/functions/type.fish:90 -msgid "%s is a function with definition\\n" -msgstr "%s ist eine Funktion mit der Definition\\n" +#~ msgid "%s is a function with definition\\n" +#~ msgstr "%s ist eine Funktion mit der Definition\\n" -#: share/functions/type.fish:94 -msgid "function" -msgstr "Funktion" +#~ msgid "function" +#~ msgstr "Funktion" -#: share/functions/type.fish:107 -msgid "%s is a builtin\\n" -msgstr "%s ist ein eingebauter Befehl\\n" +#~ msgid "%s is a builtin\\n" +#~ msgstr "%s ist ein eingebauter Befehl\\n" -#: share/functions/type.fish:110 #, fuzzy -msgid "builtin" -msgstr "eingebauter Befehl\\n" +#~ msgid "builtin" +#~ msgstr "eingebauter Befehl\\n" -#: share/functions/type.fish:130 -msgid "%s is %s\\n" -msgstr "%s ist %s\\n" +#~ msgid "%s is %s\\n" +#~ msgstr "%s ist %s\\n" -#: share/functions/type.fish:133 -msgid "file" -msgstr "Datei" +#~ msgid "file" +#~ msgstr "Datei" -#: share/functions/type.fish:144 #, fuzzy -msgid "%s: Could not find '%s'\\n" -msgstr "%s: Konnte '%s' nicht finden" +#~ msgid "%s: Could not find '%s'\\n" +#~ msgstr "%s: Konnte '%s' nicht finden" -#: share/functions/umask.fish:11 share/functions/umask.fish:69 -#: share/functions/umask.fish:76 -msgid "%s: Invalid mask '%s'\\n" -msgstr "%s: Ungültige Maske '%s'\\n" +#~ msgid "%s: Invalid mask '%s'\\n" +#~ msgstr "%s: Ungültige Maske '%s'\\n" -#: share/functions/umask.fish:137 #, fuzzy -msgid "Set default file permission mask" -msgstr "Alle Rechte extrahieren" +#~ msgid "Set default file permission mask" +#~ msgstr "Alle Rechte extrahieren" -#: share/functions/umask.fish:212 -msgid "%s: Too many arguments\\n" -msgstr "%s: Zu viele Argumente\\n" +#~ msgid "%s: Too many arguments\\n" +#~ msgstr "%s: Zu viele Argumente\\n" -#: share/functions/vared.fish:6 #, fuzzy -msgid "Edit variable value" -msgstr "Verfügbare Liste ausgeben" +#~ msgid "Edit variable value" +#~ msgstr "Verfügbare Liste ausgeben" -#: share/functions/vared.fish:40 #, fuzzy -msgid "" -"%s: %s is an array variable. Use %svared%s %s[n]%s to edit the n:th element " -"of %s\\n" -msgstr "" -"vared: %s ist eine Feldvariable. Benutzen Sie %svared%s %s[n] zum Editieren " -"den n. Elementes von %s\\n" +#~ msgid "" +#~ "%s: %s is an array variable. Use %svared%s %s[n]%s to edit the n:th " +#~ "element of %s\\n" +#~ msgstr "" +#~ "vared: %s ist eine Feldvariable. Benutzen Sie %svared%s %s[n] zum " +#~ "Editieren den n. Elementes von %s\\n" -#: share/functions/vared.fish:44 #, fuzzy -msgid "" -"%s: Expected exactly one argument, got %s.\\n\\nSynopsis:\\n\\t%svared%s " -"VARIABLE\\n" -msgstr "" -"vared: Erwartete genau ein Argument, erhielt %s.\\n\\nSynopsis:\\n\\t%svared" -"%s VARIABLE\\n" +#~ msgid "" +#~ "%s: Expected exactly one argument, got %s.\\n\\nSynopsis:\\n\\t%svared%s " +#~ "VARIABLE\\n" +#~ msgstr "" +#~ "vared: Erwartete genau ein Argument, erhielt %s.\\n\\nSynopsis:\\n\\t" +#~ "%svared%s VARIABLE\\n" #, fuzzy #~ msgid "%ls: Expected zero or two parameters, got %d\n" @@ -9134,10 +6128,6 @@ msgstr "" #~ msgid "Diff Formats" #~ msgstr "Listenformat" -#, fuzzy -#~ msgid "Environment Variables" -#~ msgstr "Behandlung von Umgebungsvariablen" - #, fuzzy #~ msgid "Specifying File Sets" #~ msgstr "Konfigurationsdatei angeben" @@ -9321,11 +6311,6 @@ msgstr "" #~ msgid "Error while reading input information from file '%ls'" #~ msgstr "Fehler beim Lesen der Eingabeinformationen aus Datei '%ls'" -#~ msgid "If this error can be reproduced, please send a bug report to %s." -#~ msgstr "" -#~ "Wenn dieser Fehler reproduziert werden kann, senden Sie bitte einen " -#~ "Fehlerbereicht an %s." - #~ msgid "Short circut command requires additional command" #~ msgstr "Ein kurzer Kreisbefehl erfordert einen zusätzlichen Befehl" @@ -9344,9 +6329,6 @@ msgstr "" #~ msgid "Tried to evaluate null pointer." #~ msgstr "Versuchte, einen Nullzeiger auszuwerten." -#~ msgid "Unknown command '%ls'" -#~ msgstr "Unbekannter Befehl '%ls'" - #~ msgid "Job command" #~ msgstr "Jobbefehl" @@ -9918,9 +6900,6 @@ msgstr "" #~ msgid "Run the test script" #~ msgstr "Das test-Skript ausführen" -#~ msgid "Don't remove the test directory" -#~ msgstr "Das test-Verzeichnis nicht entfernen" - #~ msgid "Remove the test directory" #~ msgstr "Das test-Verzeichnis entfernen" diff --git a/po/fr.po b/po/fr.po index ac35c1e8f..f483343b4 100644 --- a/po/fr.po +++ b/po/fr.po @@ -22,7 +22,7 @@ msgstr "" #: autoload.cpp:113 #, c-format msgid "Could not autoload item '%ls', it is already being autoloaded. " -msgstr "" +msgstr "Chargement automatique de '%ls' impossible car il a déjà été chargé automatiquement." #: builtin.cpp:84 #, c-format @@ -35,11 +35,13 @@ msgid "" "%ls: Type 'help %ls' for related documentation\n" "\n" msgstr "" +"%ls: Tapez 'help %ls' pour sa documentation\n" +"\n" #: builtin.cpp:531 #, c-format msgid "%ls: No key with name '%ls' found\n" -msgstr "" +msgstr "%ls: Aucune clef avec le nom '%ls' n'a été trouvée\n" #: builtin.cpp:537 #, fuzzy, c-format @@ -59,7 +61,7 @@ msgstr "%s: Aucune description pour le type %s\n" #: builtin.cpp:798 #, c-format msgid "%ls: No binding found for sequence '%ls'\n" -msgstr "" +msgstr "Aucune description trouvée pour la séquence '%ls'\n" #: builtin.cpp:834 #, fuzzy, c-format @@ -339,7 +341,7 @@ msgstr "Définir une option de config" #: builtin.cpp:4070 msgid "Try out the new parser" -msgstr "" +msgstr "Essayez le nouveau parseur" #: builtin.cpp:4071 msgid "Execute command if previous command suceeded" @@ -368,7 +370,7 @@ msgstr "Arrêter la boucle interne" #: builtin.cpp:4077 msgid "" "Temporarily halt execution of a script and launch an interactive debug prompt" -msgstr "" +msgstr "Arrête temporairement l'exécution du script and lance une invite de débogage interactif" #: builtin.cpp:4078 msgid "Run a builtin command instead of a function" @@ -396,7 +398,7 @@ msgstr "Éditer les complétions spécifiques aux commandes" #: builtin.cpp:4084 msgid "Search for a specified string in a list" -msgstr "" +msgstr "Rechercher une chaine de caractères donnée dans une liste" #: builtin.cpp:4085 msgid "Skip the rest of the current lap of the innermost loop" @@ -435,7 +437,7 @@ msgstr "Quitter le shell" #: builtin.cpp:4093 msgid "Return an unsuccessful result" -msgstr "" +msgstr "Retourne un résulat d'échec" #: builtin.cpp:4094 msgid "Send job to foreground" @@ -455,7 +457,7 @@ msgstr "Lister ou enlever des fonctions" #: builtin.cpp:4098 msgid "History of commands executed by user" -msgstr "" +msgstr "Historique des commandes exécutées par l'utilisateur" #: builtin.cpp:4099 msgid "Evaluate block if condition is true" @@ -475,7 +477,7 @@ msgstr "Exécuter la commande si la précédente a échoué" #: builtin.cpp:4103 msgid "Prints formatted text" -msgstr "" +msgstr "Affiche le texte formaté" #: builtin.cpp:4104 #, fuzzy @@ -500,7 +502,7 @@ msgstr "Gérer les variables d'environnement" #: builtin.cpp:4109 msgid "Set the terminal color" -msgstr "" +msgstr "Définir la couleur du terminal" #: builtin.cpp:4110 msgid "Evaluate contents of file" @@ -512,7 +514,7 @@ msgstr "Retourner l'information sur l'état de fish" #: builtin.cpp:4114 msgid "Return a successful result" -msgstr "" +msgstr "Retourne un résultat d'échec" #: builtin.cpp:4115 msgid "Set or get the shells resource usage limits" @@ -574,30 +576,30 @@ msgstr "" #: builtin_printf.cpp:256 #, fuzzy, c-format msgid "%ls: expected a numeric value" -msgstr "%s: Un argument attendu\n" +msgstr "%ls: valeur numérique attendue" #: builtin_printf.cpp:258 #, c-format msgid "%ls: value not completely converted" -msgstr "" +msgstr "%ls: la valeur n'a pas été entièrement convertie" #: builtin_printf.cpp:359 msgid "missing hexadecimal number in escape" -msgstr "" +msgstr "manque un nombre hexadecimal dans l'échappement" #: builtin_printf.cpp:388 msgid "Missing hexadecimal number in Unicode escape" -msgstr "" +msgstr "Manque un nombre hexadecimal dans l'échappement Unicode" #: builtin_printf.cpp:402 #, c-format msgid "Unicode character out of range: \\%c%0*x" -msgstr "" +msgstr "Caractère unicode hors limite" #: builtin_printf.cpp:670 #, c-format msgid "invalid field width: %ls" -msgstr "" +msgstr "largeur de champ invalide: %ls" #: builtin_printf.cpp:708 #, fuzzy, c-format @@ -611,7 +613,7 @@ msgstr "%ls: Combinaison d'options invalide\n" #: builtin_printf.cpp:771 msgid "printf: not enough arguments" -msgstr "" +msgstr "printf: pas assez d'arguments" #: builtin_set.cpp:155 #, c-format @@ -662,6 +664,7 @@ msgstr "" msgid "" "%ls: Warning: universal scope selected, but a global variable '%ls' exists.\n" msgstr "" +"%ls: Attention: portée universelle selectionnée, mais une variable globale '%ls' existe.\n" #: builtin_set_color.cpp:144 builtin_set_color.cpp:166 #, fuzzy, c-format @@ -718,6 +721,9 @@ msgid "" "will not be saved. Please set the $XDG_CONFIG_HOME variable to a directory " "where the current user has write access." msgstr "" +"Impossible de créer un repertoire de configuration pour fish. Vos paramètres personnels" +"ne seront pas enregistés. Définissez la variable $XDG_CONFIG_HOME sur un repertoire" +"où l'utilisateur actuel a les droits d'écriture." #: event.cpp:178 #, c-format @@ -824,6 +830,9 @@ msgid "" "variable values between old and new fish sessions. For best results, restart " "all running instances of fish." msgstr "" +"Une veille version de fish semble en fonctionnement. Vous ne pourrez pas partager" +"des variables entre la veille et la nouvelle version de fish. Redémarrez" +"toutes les instances de fish." #: fish.cpp:420 #, c-format @@ -837,8 +846,7 @@ msgstr "%s, version %s\n" #: fish.cpp:516 msgid "Can not use the no-execute mode when running an interactive session" -msgstr "" -"Le mode no-execute ne peut pas être utilisé dans une session interactive" +msgstr "Le mode no-execute ne peut pas être utilisé dans une session interactive" #: fish.cpp:619 #, c-format @@ -857,12 +865,12 @@ msgstr "Paramétrage du terminal impossible" #: input.cpp:486 #, c-format msgid "Check that your terminal type, '%ls', is supported on this system" -msgstr "" +msgstr "Vérifiez que votre type de terminal '%ls' est supporté sur ce système" #: input.cpp:488 #, c-format msgid "Attempting to use '%ls' instead" -msgstr "" +msgstr "Tentative d'essai avec '%ls' à la place" #: input.cpp:535 #, fuzzy @@ -946,17 +954,17 @@ msgstr "Définir l'architecture" #: pager.cpp:562 #, c-format msgid "%lsand 1 more row" -msgstr "" +msgstr "%lset 1 ligne de plus" #: pager.cpp:566 #, c-format msgid "%lsand %lu more rows" -msgstr "" +msgstr "%lset %lu lignes de plus" #: pager.cpp:571 #, c-format msgid "rows %lu to %lu of %lu" -msgstr "" +msgstr "lignes %lu à %lu de %lu" #: pager.cpp:576 #, fuzzy @@ -1015,7 +1023,7 @@ msgstr "" #: parse_execution.cpp:848 #, c-format msgid "The file '%ls' is not executable by this user" -msgstr "" +msgstr "Le fichier '%ls' n'est pas executable par cet utilisateur" #: parse_execution.cpp:1057 #, fuzzy, c-format @@ -1176,7 +1184,7 @@ msgstr "%ls (ligne %d): " #: parser.cpp:760 msgid "Startup" -msgstr "" +msgstr "Démarrage" #: parser.cpp:803 msgid "Job inconsistency" @@ -1194,7 +1202,7 @@ msgstr "%ls (ligne %d): " #: parser.cpp:1051 #, c-format msgid "%ls: " -msgstr "" +msgstr "%ls: " #: path.cpp:24 #, c-format @@ -1278,13 +1286,14 @@ msgstr "Impossible de définir le mode du terminal pour le shell" #: reader.cpp:2059 msgid "No TTY for interactive shell (tcgetpgrp failed)" -msgstr "" +msgstr "Pas de TTY pour shell interactif (tcgetpgrp a échoué)" #: reader.cpp:2074 #, c-format msgid "" "I appear to be an orphaned process, so I am quitting politely. My pid is %d." msgstr "" +"Il semblerait que je sois un processus orphelin, je m'arrête donc. Mon pid est %d." #: reader.cpp:2105 msgid "Couldn't put the shell in its own process group" @@ -1488,7 +1497,7 @@ msgstr "Fin de jeton inattendue" #: tokenizer.cpp:37 msgid "Unexpected end of string, parenthesis do not match" -msgstr "" +msgstr "Fin de chaine inattendue, les parenthèses ne correspondent pas" #: tokenizer.cpp:42 msgid "Unexpected end of string, square brackets do not match" @@ -1747,7 +1756,7 @@ msgstr "Une erreur est survenue lors du paramétrage du tube" #: expand.h:135 msgid "Array index out of bounds" -msgstr "" +msgstr "Indice de liste hors limite" #: parse_constants.h:185 #, c-format @@ -1761,6 +1770,8 @@ msgid "" "The function call stack limit has been exceeded. Do you have an accidental " "infinite loop?" msgstr "" +"La taille de la pile d'appels de fonctions a atteint sa limite. Avez-vous" +"une boucle infinie involontaire?" #: parse_constants.h:192 #, fuzzy @@ -2413,7 +2424,7 @@ msgstr "Ignorer les bogues dans votre système" #: share/completions/apt-listbugs.fish:7 msgid "Ignore newer bugs than upgrade packages" -msgstr "" +msgstr "Ignorer les nouveaux bugs et mettre à jour les paquets" #: share/completions/apt-listbugs.fish:8 msgid "Bugs for downgrade packages" @@ -2511,7 +2522,7 @@ msgstr "Synchroniser les paquets installés" #: share/completions/apt-mark.fish:26 msgid "Hold a package, prevent automatic installation or removal" -msgstr "" +msgstr "Mentienir un paquet, empêchant suppression ou installation automatique" #: share/completions/apt-mark.fish:27 #, fuzzy @@ -2847,7 +2858,7 @@ msgstr "Nettoyer les paquets ne pouvant plus être téléchargés" #: share/completions/aptitude.fish:25 msgid "Remove all downloaded .deb files from the package cache directory" -msgstr "" +msgstr "Supprimer tous les fichiers .deb du cache" #: share/completions/aptitude.fish:26 msgid "Forget all internal information about what packages are \\new" @@ -2868,7 +2879,7 @@ msgstr "Afficher tous les paquets source avec version" #: share/completions/aptitude.fish:30 msgid "Download and displays the Debian changelog for the packages" -msgstr "" +msgstr "Télécharger et afficher le changelog pour le paquet Debian" #: share/completions/aptitude.fish:31 #, fuzzy @@ -2877,15 +2888,15 @@ msgstr "Mettre à niveau ou installer les plus nouveaux paquets" #: share/completions/aptitude.fish:32 msgid "Download the packages to the current directory" -msgstr "" +msgstr "Télécharger le paquet dans le répertoire courant" #: share/completions/aptitude.fish:33 msgid "Forbid the upgrade to a particular version" -msgstr "" +msgstr "Interdir la mise à jour vers une version précise" #: share/completions/aptitude.fish:34 msgid "Ignore the packages by future upgrade commands" -msgstr "" +msgstr "Ignorer le paquet pour les futures commandes de mise à jour" #: share/completions/aptitude.fish:35 #, fuzzy @@ -2894,7 +2905,7 @@ msgstr "Installer des paquets source" #: share/completions/aptitude.fish:36 msgid "Cancel any scheduled actions on the packages" -msgstr "" +msgstr "Annuler toute action programmée pour un paquet" #: share/completions/aptitude.fish:37 #, fuzzy @@ -2903,7 +2914,7 @@ msgstr "Synchroniser les paquets installés" #: share/completions/aptitude.fish:38 msgid "Remove and delete all associated configuration and data files" -msgstr "" +msgstr "Supprimer tous les fichiers de configuration associés" #: share/completions/aptitude.fish:39 #, fuzzy @@ -2936,7 +2947,7 @@ msgstr "Cherche les paquet contenant le motif" #: share/completions/aptitude.fish:45 msgid "Display brief summary of the available commands and options" -msgstr "" +msgstr "Afficher un sommaire des commandes et options disponibles" #: share/completions/arp.fish:4 msgid "Class of hw type" @@ -2992,7 +3003,7 @@ msgstr "Afficher les tâches listées" #: share/completions/atd.fish:2 msgid "Limiting load factor" -msgstr "" +msgstr "Limiter le facteur de charge" #: share/completions/atd.fish:3 msgid "Minimum interval in seconds" diff --git a/po/pl.po b/po/pl.po new file mode 100644 index 000000000..f993019e4 --- /dev/null +++ b/po/pl.po @@ -0,0 +1,1544 @@ +# Translation of fish in Polish +# This file is distributed under the same license as the fish package. +# Author: m4sk1n +msgid "" +msgstr "" +"PO-Revision-Date: 2017-01-07 10:24:59+0000\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: GlotPress/2.2.2\n" +"Language: pl\n" +"Project-Id-Version: fish\n" + +#: src/expand.h:100 +msgid "Array index out of bounds" +msgstr "" + +#: src/builtin.h:74 +msgid "Send job %d, '%ls' to foreground\n" +msgstr "Wysłano zadanie %d, '%ls' na pierwszy plan\n" + +#: src/builtin.h:71 +msgid "%ls: Argument '%ls' is not a number\n" +msgstr "%ls: Argument '%ls' nie jest liczbą \n" + +#: src/builtin.h:65 +msgid "%ls: Variable name can not be the empty string\n" +msgstr "%ls: Nazwa zmiennej nie może być pustym ciągiem znaków \n" + +#: src/builtin.h:61 +msgid "%ls: Invalid character '%lc' in variable name. Only alphanumerical characters and underscores are valid in a variable name.\n" +msgstr "%ls: Nieprawidłowy znak '%lc' w nazwie zmiennej. Możesz używać tylko znaków alfanumerycznych i podkreślników w nazwach zmiennych.\n" + +#: src/builtin.h:57 +msgid "%ls: %ls expected %d args, got %d\n" +msgstr "%ls: %ls oczekiwał %d argumentów, otrzymał %d\n" + +#: src/builtin.h:56 +msgid "%ls: expected %d args, got %d\n" +msgstr "%ls: oczekiwano %d argumentów, otrzymano %d\n" + +#: src/builtin.h:53 +msgid "%ls: Unknown option '%ls'\n" +msgstr "%ls: Nieznana opcja '%ls'\n" + +#: src/builtin.h:50 +msgid "%ls: Variable can't be both exported and unexported\n" +msgstr "" + +#: src/builtin.h:47 +msgid "%ls: Variable scope can only be one of universal, global and local\n" +msgstr "" + +#: src/builtin.h:43 +msgid "" +"%ls: Invalid combination of options,\n" +"%ls\n" +msgstr "" +"%ls: Nieprawidłowa kombinacja opcji,\n" +"%ls\n" + +#: src/builtin.h:37 +msgid "%ls: Expected argument for option %ls\n" +msgstr "%ls: Oczekiwano argumentu dla funkcji %ls\n" + +#: src/parse_constants.h:271 +msgid "Unsupported use of '='. In fish, please use 'set %ls %ls'." +msgstr "Nieobsługiwane użycie '='. W fish używane jest 'set %ls %ls'." + +#: src/parse_constants.h:266 +msgid "Unsupported use of '='. To run '%ls' with a modified environment, please use 'env %ls=%ls %ls%ls'" +msgstr "Nieobsługiwane użycie '='. Aby uruchomić '%ls' w zmodyfikowanym środowisku, użyj 'env %ls=%ls %ls%ls'" + +#: src/parse_constants.h:262 +msgid "Unsupported use of '&&'. In fish, please use 'COMMAND; and COMMAND'." +msgstr "Nieobsługiwane użycie '&&'. W fish używane jest 'COMMAND; and COMMAND'." + +#: src/parse_constants.h:259 +msgid "Unsupported use of '||'. In fish, please use 'COMMAND; or COMMAND'." +msgstr "Nieobsługiwane użycie '||'. W fish używane jest 'COMMAND; or COMMAND'." + +#: src/parse_constants.h:256 +msgid "Expected a variable name after this $." +msgstr "Oczekiwano nazwy zmiennej po znaku $." + +#: src/parse_constants.h:253 +msgid "$* is not supported. In fish, please use $argv." +msgstr "$* nie jest obsługiwane. W fish używane jest $argv." + +#: src/parse_constants.h:250 +msgid "$(...) is not supported. In fish, please use '(%ls)'." +msgstr "$(...) nie jest obsługiwane. W fish używane jest '(%ls)'." + +#: src/parse_constants.h:247 +msgid "$@ is not supported. In fish, please use $argv." +msgstr "$@ nie jest obsługiwane. W fish używane jest $argv." + +#: src/parse_constants.h:244 +msgid "$# is not supported. In fish, please use 'count $argv'." +msgstr "$# nie jest obsługiwane. W fish używane jest 'count $argv'." + +#: src/parse_constants.h:241 +msgid "$$ is not the pid. In fish, please use %%self." +msgstr "$$ nie jest numerem identyfikacyjnym procesu. W fish używane jest %%self." + +#: src/parse_constants.h:238 +msgid "$? is not the exit status. In fish, please use $status." +msgstr "" + +#: src/parse_constants.h:235 +msgid "Variables cannot be bracketed. In fish, please use \"$%ls\"." +msgstr "Zmienne nie mogą znajdować się w nawiasach. W fish używane jest \"$%ls\"." + +#: src/parse_constants.h:231 +msgid "Variables cannot be bracketed. In fish, please use {$%ls}." +msgstr "Zmienne nie mogą znajdować się w nawiasach. W fish używane jest {$%ls}." + +#: src/parse_constants.h:228 +msgid "$%lc is not a valid variable in fish." +msgstr "$%lc nie jest prawidłową zmienną w fish." + +#: src/parse_constants.h:223 +msgid "'return' outside of function definition" +msgstr "'return' poza definicją funkcji" + +#: src/parse_constants.h:220 +msgid "'continue' while not inside of loop" +msgstr "'continue' użyte poza pętlą" + +#: src/parse_constants.h:217 +msgid "'break' while not inside of loop" +msgstr "'break' użyte poza pętlą" + +#: src/parse_constants.h:213 +msgid "No matches for wildcard '%ls'. (Tip: empty matches are allowed in 'set', 'count', 'for'.)" +msgstr "" + +#: src/parse_constants.h:209 +msgid "Illegal file descriptor in redirection '%ls'" +msgstr "" + +#: src/parse_constants.h:206 +msgid "Unable to find a process '%ls'" +msgstr "Nie udało się odnaleźć procesu '%ls'" + +#: src/parse_constants.h:203 +msgid "Unable to expand variable name '%ls'" +msgstr "Nie udało się rozszerzyć nazwy zmiennej '%ls'" + +#: src/parse_constants.h:200 +msgid "Unknown builtin '%ls'" +msgstr "" + +#: src/parse_constants.h:197 +msgid "Illegal command name '%ls'" +msgstr "Niedozwolona nazwa komendy '%ls'" + +#: src/parse_constants.h:193 +msgid "The function call stack limit has been exceeded. Do you have an accidental infinite loop?" +msgstr "" + +#: src/parse_constants.h:189 +msgid "The function '%ls' calls itself immediately, which would result in an infinite loop." +msgstr "Funkcja '%ls' wywołuje natychmiastowo siebie. Może to skutkować nieskończoną pętlą." + +#: src/exec.h:11 +msgid "An error occurred while setting up pipe" +msgstr "" + +#: src/builtin.cpp:3237 +msgid "Perform a command multiple times" +msgstr "Wykonaj komendę wielokrotnie" + +#: src/builtin.cpp:3236 +msgid "Set or get the shells resource usage limits" +msgstr "" + +#: src/builtin.cpp:3235 +msgid "Return a successful result" +msgstr "Zwróć pomyślny wynik" + +#: src/builtin.cpp:3232 +msgid "Manipulate strings" +msgstr "Zmień wartości ciągów znaków" + +#: src/builtin.cpp:3231 +msgid "Return status information about fish" +msgstr "Zwróć informacje o fish" + +#: src/builtin.cpp:3230 +msgid "Evaluate contents of file" +msgstr "" + +#: src/builtin.cpp:3229 +msgid "Set the terminal color" +msgstr "Ustaw kolor terminala" + +#: src/builtin.cpp:3228 +msgid "Handle environment variables" +msgstr "Operuj zmiennymi środowiskowymi" + +#: src/builtin.cpp:3227 +msgid "Stop the currently evaluated function" +msgstr "Zatrzymaj obecnie używaną funkcję" + +#: src/builtin.cpp:3226 +msgid "Convert path to absolute path without symlinks" +msgstr "Zamień ścieżkę na ścieżkę bezwzględną bez nawiązań symbolicznych" + +#: src/builtin.cpp:3225 +msgid "Read a line of input into variables" +msgstr "" + +#: src/builtin.cpp:3224 +msgid "Generate random number" +msgstr "Zwróć losową liczbę" + +#: src/builtin.cpp:3223 +msgid "Print the working directory" +msgstr "Zwróć katalog roboczy" + +#: src/builtin.cpp:3222 +msgid "Prints formatted text" +msgstr "Zwraca sformatowany tekst" + +#: src/builtin.cpp:3221 +msgid "Execute command if previous command failed" +msgstr "Wykonaj komendę jeżeli poprzednia komenda zakończy się niepowodzeniem" + +#: src/builtin.cpp:3220 +msgid "Negate exit status of job" +msgstr "" + +#: src/builtin.cpp:3219 +msgid "Print currently running jobs" +msgstr "Wypisz obecnie uruchomione zadania" + +#: src/builtin.cpp:3218 +msgid "Evaluate block if condition is true" +msgstr "" + +#: src/builtin.cpp:3217 +msgid "History of commands executed by user" +msgstr "Historia komend wykonanych przez użytkownika" + +#: src/builtin.cpp:3216 +msgid "List or remove functions" +msgstr "Wypisz lub usuń funkcje" + +#: src/builtin.cpp:3215 +msgid "Define a new function" +msgstr "Zdefiniuj nową funkcję" + +#: src/builtin.cpp:3214 +msgid "Perform a set of commands multiple times" +msgstr "Wykonaj zestaw komend wielokrotnie" + +#: src/builtin.cpp:3213 +msgid "Send job to foreground" +msgstr "" + +#: src/builtin.cpp:3212 +msgid "Return an unsuccessful result" +msgstr "Zwróć niepomyślny wynik" + +#: src/builtin.cpp:3211 +msgid "Exit the shell" +msgstr "Opuść powłokę" + +#: src/builtin.cpp:3210 +msgid "Run command in current process" +msgstr "Uruchom komendę w obecnym procesie" + +#: src/builtin.cpp:3209 +msgid "End a block of commands" +msgstr "Zakończ zestaw komend" + +#: src/builtin.cpp:3208 +msgid "Emit an event" +msgstr "" + +#: src/builtin.cpp:3207 +msgid "Evaluate block if condition is false" +msgstr "" + +#: src/builtin.cpp:3206 +msgid "Print arguments" +msgstr "Wypisz argumenty" + +#: src/builtin.cpp:3205 +msgid "Count the number of arguments" +msgstr "Wylicz liczbę argumentów" + +#: src/builtin.cpp:3204 +msgid "Skip the rest of the current lap of the innermost loop" +msgstr "" + +#: src/builtin.cpp:3202 +msgid "Search for a specified string in a list" +msgstr "Szukaj określonego ciągu znaków w liście" + +#: src/builtin.cpp:3201 +msgid "Edit command specific completions" +msgstr "Edytuj sugestie do określonej komendy" + +#: src/builtin.cpp:3200 +msgid "Set or get the commandline" +msgstr "" + +#: src/builtin.cpp:3199 +msgid "Run a program instead of a function or builtin" +msgstr "" + +#: src/builtin.cpp:3198 +msgid "Change working directory" +msgstr "Zmień katalog roboczy" + +#: src/builtin.cpp:3197 src/builtin.cpp:3233 +msgid "Conditionally execute a block of commands" +msgstr "" + +#: src/builtin.cpp:3196 +msgid "Run a builtin command instead of a function" +msgstr "" + +#: src/builtin.cpp:3195 +msgid "Temporarily halt execution of a script and launch an interactive debug prompt" +msgstr "" + +#: src/builtin.cpp:3193 +msgid "Stop the innermost loop" +msgstr "" + +#: src/builtin.cpp:3192 +msgid "Temporarily block delivery of events" +msgstr "" + +#: src/builtin.cpp:3191 +msgid "Handle fish key bindings" +msgstr "Steruj przypisaniami klawiszy fish'a" + +#: src/builtin.cpp:3190 +msgid "Send job to background" +msgstr "Przenieś zadanie w tło" + +#: src/builtin.cpp:3189 +msgid "Create a block of code" +msgstr "Stwórz blok kodu" + +#: src/builtin.cpp:3188 +msgid "Execute command if previous command suceeded" +msgstr "Wykonaj komendę jeżeli poprzednia komenda zakończy się powodzeniem" + +#: src/builtin.cpp:3186 +msgid "Try out the new parser" +msgstr "" + +#: src/builtin.cpp:3183 src/builtin.cpp:3234 +msgid "Test a condition" +msgstr "" + +#: src/builtin.cpp:3168 +msgid "%ls: Invalid path: %ls\n" +msgstr "%ls: Nieprawidłowa ścieżka: %ls\n" + +#: src/builtin.cpp:3046 +msgid "builtin history delete only supports --case-sensitive\n" +msgstr "" + +#: src/builtin.cpp:3040 +msgid "builtin history delete only supports --exact\n" +msgstr "" + +#: src/builtin.cpp:2966 src/builtin.cpp:3000 +msgid "%ls: max value '%ls' is not a valid number\n" +msgstr "%ls: maksymalna wartość '%ls' nie jest prawidłową liczbą\n" + +#: src/builtin.cpp:2857 +msgid "%ls: you cannot use any options with the %ls command\n" +msgstr "%ls: nie możesz używać opcji z komendą %ls\n" + +#: src/builtin.cpp:2845 +msgid "you cannot do both '%ls' and '%ls' in the same invocation" +msgstr "" + +#: src/builtin.cpp:2788 +msgid "%ls: Not inside of function\n" +msgstr "" + +#: src/builtin.cpp:2718 +msgid "%ls: Not inside of loop\n" +msgstr "" + +#: src/builtin.cpp:2675 +msgid "(default)" +msgstr "(domyślne)" + +#: src/builtin.cpp:2650 +msgid "Send job %d '%ls' to background\n" +msgstr "Wyślij zadanie %d '%ls' w tło\n" + +#: src/builtin.cpp:2644 +msgid "%ls: Can't put job %d, '%ls' to background because it is not under job control\n" +msgstr "" + +#: src/builtin.cpp:2639 +msgid "%ls: Unknown job '%ls'\n" +msgstr "%ls: Nieznane zadanie '%ls'\n" + +#: src/builtin.cpp:2607 +msgid "%ls: Can't put job %d, '%ls' to foreground because it is not under job control\n" +msgstr "" + +#: src/builtin.cpp:2583 +msgid "%ls: Ambiguous job\n" +msgstr "" + +#: src/builtin.cpp:2565 src/builtin.cpp:2672 +msgid "%ls: There are no suitable jobs\n" +msgstr "%ls: Brak pasujących zadań\n" + +#: src/builtin.cpp:2532 +msgid "%ls: Error while reading file '%ls'\n" +msgstr "%ls: Nie udało się odczytać '%ls'\n" + +#: src/builtin.cpp:2515 +msgid "%ls: '%ls' is not a file\n" +msgstr "%ls: '%ls' nie jest plikiem\n" + +#: src/builtin.cpp:2499 src/builtin.cpp:2507 +msgid "%ls: Error encountered while sourcing file '%ls':\n" +msgstr "" + +#: src/builtin.cpp:2469 +msgid "%ls: Key not specified\n" +msgstr "%ls: Nie określono klawisza\n" + +#: src/builtin.cpp:2405 +msgid "%ls: Could not set PWD variable\n" +msgstr "%ls: Nie można ustawić zmiennej PWD\n" + +#: src/builtin.cpp:2392 +msgid "%ls: Permission denied: '%ls'\n" +msgstr "%ls: Brak uprawnień: '%ls'\n" + +#: src/builtin.cpp:2377 +msgid "%ls: Unknown error trying to locate directory '%ls'\n" +msgstr "%ls: Nieokreślony błąd podczas wyszukiwania lokalizacji '%ls'\n" + +#: src/builtin.cpp:2373 +msgid "%ls: '%ls' is a rotten symlink\n" +msgstr "" + +#: src/builtin.cpp:2370 +msgid "%ls: The directory '%ls' does not exist\n" +msgstr "%ls: Ścieżka '%ls' nie istnieje\n" + +#: src/builtin.cpp:2367 src/builtin.cpp:2395 +msgid "%ls: '%ls' is not a directory\n" +msgstr "%ls: '%ls' nie jest ścieżką\n" + +#: src/builtin.cpp:2354 +msgid "%ls: Could not find home directory\n" +msgstr "%ls: Nie można odnaleźć katalogu domowego\n" + +#: src/builtin.cpp:2299 +msgid "Always" +msgstr "Zawsze" + +#: src/builtin.cpp:2299 +msgid "Never" +msgstr "Nigdy" + +#: src/builtin.cpp:2298 +msgid "Only on interactive jobs" +msgstr "Tylko dla zadań interaktywnych" + +#: src/builtin.cpp:2296 +msgid "Job control: %ls\n" +msgstr "Kontrola zadania: %ls\n" + +#: src/builtin.cpp:2293 +msgid "This is not a login shell\n" +msgstr "To nie jest powłoka logowania \n" + +#: src/builtin.cpp:2291 +msgid "This is a login shell\n" +msgstr "To jest powłoka logowania \n" + +#: src/builtin.cpp:1960 +msgid "%ls: --array option requires a single variable name.\n" +msgstr "%ls: opcja --array wymaga nazwy jednej zmiennej.\n" + +#: src/builtin.cpp:1912 src/builtin.cpp:2324 src/builtin.cpp:2766 +msgid "%ls: Argument '%ls' must be an integer\n" +msgstr "%ls: Argument '%ls' musi być liczbą całkowitą\n" + +#: src/builtin.cpp:1905 +msgid "%ls: Argument '%ls' is out of range\n" +msgstr "%ls: Argument '%ls' jest poza zasięgiem\n" + +#: src/builtin.cpp:1807 +msgid "%ls: Expected zero or one argument, got %d\n" +msgstr "%ls: Oczekiwano 0 lub 1 argument, otrzymano %d\n" + +#: src/builtin.cpp:1797 +msgid "%ls: Seed value '%ls' is not a valid number\n" +msgstr "" + +#: src/builtin.cpp:1707 +msgid "%ls: Expected one argument, got %lu" +msgstr "%ls: Oczekiwano jeden argument, otrzymano %lu" + +#: src/builtin.cpp:1691 +msgid "%ls: No function name given" +msgstr "%ls: Nie podano nazwy funkcji" + +#: src/builtin.cpp:1686 +msgid "" +"%ls: The name '%ls' is reserved,\n" +"and can not be used as a function name" +msgstr "" +"%ls: Nazwa '%ls' jest zastrzeżona\n" +"i nie może być wykorzystywana jako nazwa funkcji" + +#: src/builtin.cpp:1679 +msgid "%ls: Illegal function name '%ls'" +msgstr "%ls: Niedozwolona nazwa funkcji '%ls'" + +#: src/builtin.cpp:1676 +msgid "%ls: Expected function name" +msgstr "%ls: Oczekiwano nazwy funkcji" + +#: src/builtin.cpp:1605 +msgid "%ls: Invalid process id %ls" +msgstr "%ls: Nieprawidłowy identyfikator procesu %ls" + +#: src/builtin.cpp:1594 +msgid "%ls: Cannot find calling job for event handler" +msgstr "" + +#: src/builtin.cpp:1554 src/builtin.cpp:1635 src/builtin.cpp:1699 +msgid "%ls: Invalid variable name '%ls'" +msgstr "%ls: Nieprawidłowa nazwa zmiennej '%ls'" + +#: src/builtin.cpp:1545 +msgid "%ls: Unknown signal '%ls'" +msgstr "%ls: Nieznany sygnał '%ls'" + +#: src/builtin.cpp:1156 +msgid "%ls: Function '%ls' already exists. Cannot create copy '%ls'\n" +msgstr "%ls: Funkcja '%ls' już istnieje. Nie można utworzyć kopii '%ls'\n" + +#: src/builtin.cpp:1147 +msgid "%ls: Illegal function name '%ls'\n" +msgstr "%ls: Niedozwolona nazwa funkcji '%ls'\n" + +#: src/builtin.cpp:1128 +msgid "%ls: Expected exactly two names (current function name, and new function name)\n" +msgstr "%ls: Oczekiwano dokładnie dwóch nazw (nazwa obecnej funkcji i nazwa nowej)\n" + +#: src/builtin.cpp:1091 src/builtin.cpp:1139 +msgid "%ls: Function '%ls' does not exist\n" +msgstr "%ls: Funkcja '%ls' nie istnieje\n" + +#: src/builtin.cpp:1084 +msgid "%ls: Expected exactly one function name\n" +msgstr "%ls: Oczekiwano dokładnie jednej nazwy funkcji\n" + +#: src/builtin.cpp:1069 src/builtin.h:40 +msgid "%ls: Invalid combination of options\n" +msgstr "%ls: Nieprawidłowe połączenie opcji\n" + +#: src/builtin.cpp:652 +msgid "%ls: No blocks defined\n" +msgstr "%ls: Nie określono bloków\n" + +#: src/builtin.cpp:646 +msgid "%ls: Can not specify scope when removing block\n" +msgstr "" + +#: src/builtin.cpp:579 +msgid "%ls: Invalid state\n" +msgstr "%ls: Nieprawidłowy stan\n" + +#: src/builtin.cpp:552 +msgid "%ls: No binding found for sequence '%ls'\n" +msgstr "" + +#: src/builtin.cpp:548 +msgid "%ls: No binding found for key '%ls'\n" +msgstr "" + +#: src/builtin.cpp:361 +msgid "%ls: Unknown error trying to bind to key named '%ls'\n" +msgstr "%ls: Nieznany błąd podczas próby przypisania do klawisza '%ls'\n" + +#: src/builtin.cpp:356 +msgid "%ls: Key with name '%ls' does not have any mapping\n" +msgstr "%ls: Klawisz '%ls' nie ma żadnego przypisania\n" + +#: src/builtin.cpp:351 +msgid "%ls: No key with name '%ls' found\n" +msgstr "%ls: Nie znaleziono klaiwsza '%ls'\n" + +#: src/builtin.cpp:223 +msgid "" +"%ls: Type 'help %ls' for related documentation\n" +"\n" +msgstr "" +"%ls: Wpisz 'help %ls' aby uzyskać informacje z tym związane\n" +"\n" + +#: src/io.cpp:55 +msgid "An error occured while reading output from code block on file descriptor %d" +msgstr "" + +#: src/builtin_string.cpp:1154 +msgid "string: Unknown subcommand '%ls'\n" +msgstr "string: Nieznane podpolecenie '%ls'\n" + +#: src/builtin_string.cpp:1139 +msgid "string: Expected subcommand\n" +msgstr "string: Oczekiwano podpolecenia\n" + +#: src/builtin_string.cpp:978 +msgid "%ls: Invalid start value '%ls'\n" +msgstr "%ls: Nieprawidłową wartość początkowa '%ls'\n" + +#: src/builtin_string.cpp:960 +msgid "%ls: Invalid length value '%ls'\n" +msgstr "%ls: Nieprawidłowa wartość długości '%ls'\n" + +#: src/builtin_string.cpp:706 +msgid "%ls: Regular expression substitute error: %ls\n" +msgstr "" + +#: src/builtin_string.cpp:393 +msgid "%ls: Regular expression internal error\n" +msgstr "" + +#: src/builtin_string.cpp:388 +msgid "%ls: Regular expression match error: %ls\n" +msgstr "" + +#: src/builtin_string.cpp:347 +msgid "%ls: Regular expression compile error: %ls\n" +msgstr "" + +#: src/builtin_string.cpp:33 +msgid "%ls: Expected argument\n" +msgstr "%ls: Oczekiwano argumentu\n" + +#: src/pager.cpp:491 +msgid "(no matches)" +msgstr "(brak pasujących wyników)" + +#: src/pager.cpp:488 +msgid "rows %lu to %lu of %lu" +msgstr "rzędy od %lu do %lu z %lu" + +#: src/pager.cpp:481 +msgid "%lsand %lu more rows" +msgstr "%lsand %lu więcej rzędów" + +#: src/pager.cpp:479 +msgid "%lsand 1 more row" +msgstr "%lsand 1 rząd więcej" + +#: src/pager.cpp:36 +msgid "search: " +msgstr "wyszukiwanie:" + +#: src/signal.cpp:394 +msgid "Signal block mismatch" +msgstr "" + +#: src/signal.cpp:178 src/signal.cpp:190 +msgid "Unknown" +msgstr "Nieznany" + +#: src/signal.cpp:142 +msgid "Unused signal" +msgstr "Niewykorzystywany sygnał" + +#: src/signal.cpp:139 +msgid "Abort (Alias for SIGABRT)" +msgstr "" + +#: src/signal.cpp:136 +msgid "Emulator trap" +msgstr "" + +#: src/signal.cpp:133 +msgid "Stack fault" +msgstr "" + +#: src/signal.cpp:130 +msgid "Information request" +msgstr "Żądanie informacji" + +#: src/signal.cpp:127 +msgid "Bad system call" +msgstr "" + +#: src/signal.cpp:124 +msgid "Power failure" +msgstr "" + +#: src/signal.cpp:121 +msgid "I/O on asynchronous file descriptor is possible" +msgstr "" + +#: src/signal.cpp:115 src/signal.cpp:118 +msgid "Window size change" +msgstr "Zmiana rozmiaru okna" + +#: src/signal.cpp:112 +msgid "Profiling timer expired" +msgstr "" + +#: src/signal.cpp:109 +msgid "Virtual timer expired" +msgstr "" + +#: src/signal.cpp:106 +msgid "File size limit exceeded" +msgstr "Przekroczony limit rozmiaru pliku" + +#: src/signal.cpp:103 +msgid "CPU time limit exceeded" +msgstr "" + +#: src/signal.cpp:100 +msgid "Urgent socket condition" +msgstr "" + +#: src/signal.cpp:97 +msgid "Stop from terminal output" +msgstr "" + +#: src/signal.cpp:94 +msgid "Stop from terminal input" +msgstr "" + +#: src/signal.cpp:91 +msgid "Stop request from job control (^Z)" +msgstr "" + +#: src/signal.cpp:88 +msgid "Forced stop" +msgstr "Wymuszono zatrzymanie" + +#: src/signal.cpp:85 +msgid "Continue previously stopped process" +msgstr "Kontynuuj wcześniej zatrzymany proces" + +#: src/signal.cpp:82 +msgid "Child process status changed" +msgstr "Zmieniono status procesu potomnego" + +#: src/signal.cpp:79 +msgid "Polite quit request" +msgstr "" + +#: src/signal.cpp:76 +msgid "Timer expired" +msgstr "" + +#: src/signal.cpp:73 +msgid "Broken pipe" +msgstr "" + +#: src/signal.cpp:70 +msgid "Address boundary error" +msgstr "" + +#: src/signal.cpp:67 +msgid "User defined signal 2" +msgstr "Sygnał zdefiniowany przez użytkownika 2" + +#: src/signal.cpp:64 +msgid "User defined signal 1" +msgstr "Sygnał zdefiniowany przez użytkownika 1" + +#: src/signal.cpp:61 +msgid "Forced quit" +msgstr "Przymusowe wyjście" + +#: src/signal.cpp:58 +msgid "Floating point exception" +msgstr "" + +#: src/signal.cpp:55 +msgid "Misaligned address error" +msgstr "" + +#: src/signal.cpp:52 +msgid "Abort" +msgstr "Przerwij" + +#: src/signal.cpp:49 +msgid "Trace or breakpoint trap" +msgstr "" + +#: src/signal.cpp:46 +msgid "Illegal instruction" +msgstr "Niedozwolona instrukcja" + +#: src/signal.cpp:43 +msgid "Quit request from job control with core dump (^\\)" +msgstr "" + +#: src/signal.cpp:40 +msgid "Quit request from job control (^C)" +msgstr "" + +#: src/signal.cpp:37 +msgid "Terminal hung up" +msgstr "Terminal zawieszony" + +#: src/autoload.cpp:105 +msgid "Could not autoload item '%ls', it is already being autoloaded. This is a circular dependency in the autoloading scripts, please remove it." +msgstr "" + +#: src/event.cpp:440 +msgid "Signal list overflow. Signals have been ignored." +msgstr "" + +#: src/event.cpp:151 +msgid "Unknown event type '0x%x'" +msgstr "Nieznany typ zdarzenia '0x%x'" + +#: src/event.cpp:147 +msgid "handler for generic event '%ls'" +msgstr "" + +#: src/event.cpp:142 +msgid "exit handler for job with job id %d" +msgstr "" + +#: src/event.cpp:131 +msgid "exit handler for job with process group %d" +msgstr "" + +#: src/event.cpp:128 src/event.cpp:139 +msgid "exit handler for job %d, '%ls'" +msgstr "zakończ obsługę zadania %d, '%ls'" + +#: src/event.cpp:124 +msgid "exit handler for process %d" +msgstr "zakończ obsługę procesu %d" + +#: src/event.cpp:119 +msgid "handler for variable '%ls'" +msgstr "obsługa zmiennej '%ls'" + +#: src/event.cpp:114 +msgid "signal handler for %ls (%ls)" +msgstr "obsługa sygnału dla %ls (%ls)" + +#: src/common.cpp:1547 +msgid "empty" +msgstr "pusto" + +#: src/common.cpp:1535 +msgid "This is a bug. Break on bugreport to debug. If you can reproduce it, please send a bug report to %s." +msgstr "" + +#: src/parser.cpp:783 +msgid "%ls: " +msgstr "%ls: " + +#: src/parser.cpp:780 +msgid "%ls (line %lu): " +msgstr "%ls (linia %lu): " + +#: src/parser.cpp:697 +msgid "End of block mismatch. Program terminating." +msgstr "" + +#: src/parser.cpp:567 +msgid "Job inconsistency" +msgstr "" + +#: src/parser.cpp:531 +msgid "Startup" +msgstr "Uruchamianie" + +#: src/parser.cpp:528 +msgid "%ls (line %d): " +msgstr "%ls (linia %d): " + +#: src/parser.cpp:439 +msgid "\twith parameter list '%ls'\n" +msgstr "\tz listą parametrów '%ls'\n" + +#: src/parser.cpp:426 +msgid "\tcalled on standard input\n" +msgstr "" + +#: src/parser.cpp:424 +msgid "\tcalled during startup\n" +msgstr "\tprzywołano podczas rozruchu\n" + +#: src/parser.cpp:421 +msgid "\tcalled on line %d of file %ls\n" +msgstr "" + +#: src/parser.cpp:410 +msgid "in command substitution\n" +msgstr "w zastępstwie polecenia \n" + +#: src/parser.cpp:406 +msgid "in function '%ls'\n" +msgstr "w funkcji '%ls'\n" + +#: src/parser.cpp:399 +msgid "from sourcing file %ls\n" +msgstr "" + +#: src/parser.cpp:380 +msgid "in event handler: %ls\n" +msgstr "w procedurze obsługi zdarzeń: %ls\n" + +#: src/parser.cpp:322 +msgid "Time\tSum\tCommand\n" +msgstr "Czas\tSuma\tKomenda\n" + +#: src/parser.cpp:320 +msgid "Could not write profiling information to file '%s'" +msgstr "" + +#: src/parser.cpp:76 +msgid "unknown/invalid block" +msgstr "nieznany/nieprawidłowy blok" + +#: src/parser.cpp:73 +msgid "event handler block" +msgstr "blok obsługi zdarzenia" + +#: src/parser.cpp:70 +msgid "block created by the . builtin" +msgstr "" + +#: src/parser.cpp:67 +msgid "'begin' unconditional block" +msgstr "" + +#: src/parser.cpp:64 +msgid "command substitution block" +msgstr "" + +#: src/parser.cpp:61 +msgid "global root block" +msgstr "" + +#: src/parser.cpp:58 +msgid "unexecutable block" +msgstr "blok niewykonywalny" + +#: src/parser.cpp:55 +msgid "'switch' block" +msgstr "blok 'switch'" + +#: src/parser.cpp:52 +msgid "function invocation block with no variable shadowing" +msgstr "" + +#: src/parser.cpp:49 +msgid "function invocation block" +msgstr "" + +#: src/parser.cpp:46 +msgid "function definition block" +msgstr "" + +#: src/parser.cpp:43 +msgid "'if' conditional block" +msgstr "blok warunkowy 'if'" + +#: src/parser.cpp:40 +msgid "block created by breakpoint" +msgstr "" + +#: src/parser.cpp:37 +msgid "'for' block" +msgstr "blok 'for'" + +#: src/parser.cpp:34 +msgid "'while' block" +msgstr "blok 'while'" + +#: src/parser.cpp:31 +msgid "Tried to evaluate commands using invalid block type '%ls'" +msgstr "" + +#: src/env.cpp:907 +msgid "Tried to pop empty environment stack." +msgstr "" + +#: src/env.cpp:318 +msgid "Could not determine current working directory. Is your locale set correctly?" +msgstr "" + +#: src/output.cpp:461 +msgid "Tried to use terminfo string %s on line %ld of %s, which is undefined in terminal of type \"%ls\". Please report this error to %s" +msgstr "" + +#: src/builtin_printf.cpp:706 +msgid "printf: not enough arguments" +msgstr "printf: brak wystarczających argumentów" + +#: src/builtin_printf.cpp:677 +msgid "%.*ls: invalid conversion specification" +msgstr "" + +#: src/builtin_printf.cpp:652 +msgid "invalid precision: %ls" +msgstr "" + +#: src/builtin_printf.cpp:625 +msgid "invalid field width: %ls" +msgstr "" + +#: src/builtin_printf.cpp:395 +msgid "Unicode character out of range: \\%c%0*x" +msgstr "" + +#: src/builtin_printf.cpp:378 +msgid "Missing hexadecimal number in Unicode escape" +msgstr "" + +#: src/builtin_printf.cpp:358 +msgid "missing hexadecimal number in escape" +msgstr "" + +#: src/builtin_printf.cpp:246 +msgid "%ls: value not completely converted" +msgstr "" + +#: src/builtin_printf.cpp:244 +msgid "%ls: expected a numeric value" +msgstr "%ls: oczekiwano wartości liczbowej" + +#: src/fish.cpp:527 src/parser.cpp:533 src/builtin.cpp:2254 +msgid "Standard input" +msgstr "Standardowe wejście" + +#: src/fish.cpp:525 +msgid "Error while reading file %ls\n" +msgstr "Wystąpił błąd podczas odczytywania pliku %ls\n" + +#: src/fish.cpp:452 +msgid "Can not use the no-execute mode when running an interactive session" +msgstr "Nie możesz użyć trybu niewykonywalnego kiedy uruchomiona jest sesja interaktywna" + +#: src/fish.cpp:359 +msgid "%s, version %s\n" +msgstr "%s, wersja %s\n" + +#: src/fish.cpp:275 +msgid "Old versions of fish appear to be running. You will not be able to share variable values between old and new fish sessions. For best results, restart all running instances of fish." +msgstr "Stara wersja fish wydaje się być uruchomiona. Nie możesz dzielić wartości zmiennych między sesjami starszej i nowszej wersji fish. Dla najlepszych wyników, uruchom ponownie wszystkie sesję fish." + +#: src/path.cpp:280 +msgid "Unable to create a data directory for fish. Your history will not be saved. Please set the $XDG_DATA_HOME variable to a directory where the current user has write access." +msgstr "Nie udało się utworzyć katalogu danych dla fish. Twoja historia nie zostanie zapisana. Przypisz zmienną $XDG_DATA_HOME do katalogu, do którego obecny użytkownik ma uprawnienia zapisu." + +#: src/path.cpp:250 src/env_universal_common.cpp:533 +msgid "Unable to create a configuration directory for fish. Your personal settings will not be saved. Please set the $XDG_CONFIG_HOME variable to a directory where the current user has write access." +msgstr "Nie udało się utworzyć katalogu konfiguracji dla fish. Twoje ustawienia nie zostaną zapisane. Przypisz zmienną $XDG_CONFIG_HOME do katalogu, do którego obecny użytkownik ma uprawnienia zapisu." + +#: src/path.cpp:22 +msgid "Error while searching for command '%ls'" +msgstr "Wystąpił błąd podczas wyszukiwania komendy '%ls'" + +#: src/fish_indent.cpp:472 +msgid "Too many arguments\n" +msgstr "Zbyt dużo argumentów\n" + +#: src/fish_indent.cpp:468 src/fish_indent.cpp:498 +msgid "Opening \"%s\" failed: %s\n" +msgstr "Otwieranie '%s' nie powiodło się: %s\n" + +#: src/fish_indent.cpp:456 +msgid "" +"Expected file path to read/write for -w:\n" +"\n" +" $ %ls -w foo.fish\n" +msgstr "" + +#: src/fish_indent.cpp:437 src/fish.cpp:372 src/fish_key_reader.cpp:349 +msgid "Invalid value '%s' for debug-stack-frames flag" +msgstr "" + +#: src/fish_indent.cpp:422 src/fish.cpp:332 src/fish_key_reader.cpp:334 +msgid "Invalid value '%s' for debug-level flag" +msgstr "" + +#: src/fish_indent.cpp:392 +msgid "%ls, version %s\n" +msgstr "%ls, wersja %s\n" + +#: src/fish_indent.cpp:378 src/fish.cpp:315 +msgid "getopt_long() unexpectedly returned zero\n" +msgstr "getopt_long() nieoczekiwanie zwrócił 0\n" + +#: src/wutil.cpp:137 +msgid "getcwd() failed with errno %d/%s" +msgstr "" + +#: src/parse_execution.cpp:1006 +msgid "Requested redirection to '%ls', which is not a valid file descriptor" +msgstr "" + +#: src/parse_execution.cpp:990 +msgid "Invalid redirection target: %ls" +msgstr "Nieprawidłowy cel przekierowania: %ls" + +#: src/parse_execution.cpp:779 +msgid "The file '%ls' is not executable by this user" +msgstr "Plik '%ls' nie jest wykonywalny dla tego użytkownika" + +#: src/parse_execution.cpp:775 +msgid "Variables may not be used as commands. In fish, please define a function or use 'eval %ls'." +msgstr "Zmienne nie mogą być używane jako komendy. W fish należy zdefiniować funkcję lub użyć 'eval %ls'." + +#: src/parse_execution.cpp:541 +msgid "switch: Expected exactly one argument, got %lu\n" +msgstr "switch: Oczekiwano dokładnie jednego argumentu, otrzymano %lu\n" + +#: src/builtin_commandline.cpp:364 +msgid "%ls: Unknown input function '%ls'\n" +msgstr "%ls: Nieznane wejście funkcji '%ls'\n" + +#: src/proc.cpp:1020 +msgid "Job '%ls', process '%ls' has inconsistent state 'completed'=%d" +msgstr "" + +#: src/proc.cpp:1014 +msgid "Job '%ls', process '%ls' has inconsistent state 'stopped'=%d" +msgstr "" + +#: src/proc.cpp:1010 +msgid "Process name" +msgstr "Nazwa procesu" + +#: src/proc.cpp:1009 +msgid "Process argument list" +msgstr "Lista argumentów procesu" + +#: src/proc.cpp:998 +msgid "More than one job in foreground: job 1: '%ls' job 2: '%ls'" +msgstr "Więcej niż jedno zadanie na pierwszym planie: zadanie 1: '%ls' zadanie 2: '%ls'" + +#: src/proc.cpp:993 src/proc.cpp:1011 +msgid "Process list pointer" +msgstr "" + +#: src/proc.cpp:821 src/proc.cpp:830 src/proc.cpp:842 +msgid "Could not return shell to foreground" +msgstr "Nie można przywrócić powłoki na pierwszy plan" + +#: src/proc.cpp:801 src/proc.cpp:808 +msgid "Could not send job %d ('%ls') to foreground" +msgstr "Nie można przenieść zadania %d ('%ls') na pierwszy plan" + +#: src/proc.cpp:783 +msgid "An error occured while reading output from code block" +msgstr "Wystąpił błąd podczas odczytywania wyjścia z bloku kodu" + +#: src/proc.cpp:634 +msgid "ended" +msgstr "zakończono" + +#: src/proc.cpp:604 +msgid "%ls: Process %d, '%ls' %ls'%ls' terminated by signal %ls (%ls)" +msgstr "%ls: Proces %d, '%ls' %ls'%ls' zakończony sygnałem %ls (%ls)" + +#: src/proc.cpp:595 +msgid "%ls: %ls'%ls' terminated by signal %ls (%ls)" +msgstr "%ls: %ls'%ls' zakończony sygnałem %ls (%ls)" + +#: src/proc.cpp:502 +msgid "Job %d, '%ls' has %ls" +msgstr "Zadanie %d, '%ls' ma %ls" + +#: src/proc.cpp:500 +msgid "'%ls' has %ls" +msgstr "'%ls' ma %ls" + +#: src/builtin_set.cpp:630 +msgid "%ls: Warning: universal scope selected, but a global variable '%ls' exists.\n" +msgstr "" + +#: src/builtin_set.cpp:611 +msgid "%ls: Values cannot be specfied with erase\n" +msgstr "" + +#: src/builtin_set.cpp:511 +msgid "%ls: Erase needs a variable name\n" +msgstr "" + +#: src/builtin_set.cpp:204 +msgid "%ls: Invalid index starting at '%ls'\n" +msgstr "" + +#: src/builtin_set.cpp:183 +msgid "%ls: Multiple variable names specified in single call (%ls and %.*ls)\n" +msgstr "" + +#: src/builtin_set.cpp:141 +msgid "%ls: Tried to set the special variable '%ls' to an invalid value\n" +msgstr "%ls: Próbowano nadać nieprawidłową wartość specjalnej zmiennej '%ls'\n" + +#: src/builtin_set.cpp:134 +msgid "%ls: Tried to set the special variable '%ls' with the wrong scope\n" +msgstr "" + +#: src/builtin_set.cpp:127 +msgid "%ls: Tried to change the read-only variable '%ls'\n" +msgstr "%ls: Próbowano zmienić wartość zmiennej tylko do odczytu '%ls'\n" + +#: src/builtin_set_color.cpp:145 +msgid "%ls: Could not set up terminal\n" +msgstr "%ls: Nie można skonfigurować terminala\n" + +#: src/builtin_set_color.cpp:128 +msgid "%ls: Expected an argument\n" +msgstr "%ls: Oczekiwano argumentu\n" + +#: src/builtin_set_color.cpp:121 src/builtin_set_color.cpp:139 +msgid "%ls: Unknown color '%ls'\n" +msgstr "%ls: Nieznany kolor '%ls'\n" + +#: src/wgetopt.cpp:419 +msgid "%ls: Option requires an argument -- %lc\n" +msgstr "%ls: Opcja wymaga argumentu -- %lc\n" + +#: src/wgetopt.cpp:392 +msgid "%ls: Invalid option -- %lc\n" +msgstr "%ls: Nieprawidłowa opcja -- %lc\n" + +#: src/wgetopt.cpp:373 +msgid "%ls: Unrecognized option '%lc%ls'\n" +msgstr "%ls: Nierozpoznana opcja '%lc%ls'\n" + +#: src/wgetopt.cpp:370 +msgid "%ls: Unrecognized option '--%ls'\n" +msgstr "%ls: Nierozpoznana opcja '--%ls'\n" + +#: src/wgetopt.cpp:349 +msgid "%ls: Option '%ls' requires an argument\n" +msgstr "%ls: Opcja '%ls' wymaga argumentu\n" + +#: src/wgetopt.cpp:338 +msgid "%ls: Option '%lc%ls' doesn't allow an argument\n" +msgstr "%ls: Opcja '%lc%ls' nie pozwala na argumenty\n" + +#: src/wgetopt.cpp:334 +msgid "%ls: Option '--%ls' doesn't allow an argument\n" +msgstr "%ls: Opcja '--%ls' nie pozwala na argumenty\n" + +#: src/wgetopt.cpp:317 +msgid "%ls: Option '%ls' is ambiguous\n" +msgstr "" + +#: src/exec.cpp:760 +msgid "Unknown input redirection type %d" +msgstr "Nieznany typ przekierowania %d" + +#: src/exec.cpp:644 +msgid "Unknown function '%ls'" +msgstr "Nieznana funkcja '%ls'" + +#: src/exec.cpp:51 +msgid "An error occurred while redirecting file '%s'" +msgstr "Wystąpił błąd podczas przekierowywania pliku '%s'" + +#: src/exec.cpp:48 +msgid "An error occurred while writing output" +msgstr "" + +#: src/exec.cpp:45 +msgid "An error occurred while redirecting file descriptor %d" +msgstr "" + +#: src/reader.cpp:3392 +msgid "Error while opening input stream" +msgstr "" + +#: src/reader.cpp:3371 +msgid "Error while closing input stream" +msgstr "" + +#: src/reader.cpp:3357 +msgid "Error while reading from file descriptor" +msgstr "" + +#: src/reader.cpp:3269 +msgid "Unknown key binding 0x%X" +msgstr "" + +#: src/reader.cpp:2255 +msgid "There are stopped jobs. A second attempt to exit will enforce their termination.\n" +msgstr "" + +#: src/reader.cpp:2042 +msgid "Pop null reader block" +msgstr "" + +#: src/reader.cpp:1659 +msgid "Couldn't grab control of terminal" +msgstr "" + +#: src/reader.cpp:1651 +msgid "Couldn't put the shell in its own process group" +msgstr "" + +#: src/reader.cpp:1625 +msgid "I appear to be an orphaned process, so I am quitting politely. My pid is %d." +msgstr "" + +#: src/reader.cpp:1616 +msgid "No TTY for interactive shell (tcgetpgrp failed)" +msgstr "" + +#: src/reader.cpp:345 +msgid "Could not set terminal mode for shell" +msgstr "" + +#: src/reader.cpp:317 +msgid "Could not set terminal mode for new job" +msgstr "Nie można ustawić trybu terminala dla nowego zadania" + +#: src/parse_util.cpp:36 +msgid "Backgrounded commands can not be used as conditionals" +msgstr "" + +#: src/parse_util.cpp:32 +msgid "The '%ls' command can not be used immediately after a backgrounded job" +msgstr "Komenda '%ls' nie może zostać użyta bezpośrednio po zadaniu w tle" + +#: src/parse_util.cpp:28 +msgid "The '%ls' command can not be used in a pipeline" +msgstr "" + +#: src/tokenizer.cpp:41 +msgid "Cannot use stdin (fd 0) as pipe output" +msgstr "" + +#: src/tokenizer.cpp:38 +msgid "Invalid input/output redirection" +msgstr "" + +#: src/tokenizer.cpp:35 +msgid "Unexpected end of string, incomplete escape sequence" +msgstr "" + +#: src/tokenizer.cpp:32 +msgid "Unexpected end of string, square brackets do not match" +msgstr "" + +#: src/tokenizer.cpp:29 +msgid "Unexpected end of string, parenthesis do not match" +msgstr "" + +#: src/tokenizer.cpp:26 +msgid "Unexpected end of string, quotes are not balanced" +msgstr "" + +#: src/builtin_complete.cpp:379 src/builtin.cpp:2774 src/builtin.h:68 +msgid "%ls: Too many arguments\n" +msgstr "%ls: Zbyt dużo argumentów\n" + +#: src/expand.cpp:1014 +msgid "Mismatched brackets" +msgstr "" + +#: src/expand.cpp:67 +msgid "Last background job" +msgstr "Ostatnie zadanie działające w tle" + +#: src/expand.cpp:64 +msgid "Shell process" +msgstr "Proces powłoki" + +#: src/expand.cpp:61 +msgid "Job: %ls" +msgstr "Zadanie: %ls" + +#: src/expand.cpp:58 +msgid "Job" +msgstr "Zadanie" + +#: src/expand.cpp:55 +msgid "Process" +msgstr "Proces" + +#: src/expand.cpp:52 +msgid "Child process" +msgstr "Proces potomny" + +#: src/complete.cpp:52 +msgid "Variable: %ls" +msgstr "Zmienna: %ls" + +#: src/complete.cpp:49 +msgid "Home for %ls" +msgstr "Katalog domowy dla %ls" + +#: src/input.cpp:407 +msgid "Error while closing terminfo" +msgstr "Wystąpił błąd podczas zamykania termingo" + +#: src/input.cpp:379 +msgid "Using fallback terminal type '%ls'" +msgstr "Używanie zapasowego typu terminala '%ls'" + +#: src/input.cpp:375 +msgid "Could not set up terminal using the fallback terminal type '%ls' - exiting" +msgstr "Nie można skonfigurować terminala używając zapasowego typu terminala '%ls' - opuszczanie" + +#: src/input.cpp:369 +msgid "Check that this terminal type is supported on this system" +msgstr "Sprawdź czy ten typ terminala jest obsługiwany przez ten system" + +#: src/input.cpp:368 +msgid "TERM environment variable set to '%ls'" +msgstr "Zmienna środowiskowa TERM ustawiona jest do '%ls'" + +#: src/input.cpp:366 +msgid "TERM environment variable not set" +msgstr "Zmienna środowiskowa TERM ustawiona jest do '%ls'" + +#: src/input.cpp:363 +msgid "Could not set up terminal" +msgstr "Nie mozna skonfigurować terminala" + +#: src/wildcard.cpp:48 +msgid "Directory" +msgstr "Katalog" + +#: src/wildcard.cpp:46 +msgid "Socket" +msgstr "Gniazdo" + +#: src/wildcard.cpp:44 +msgid "Symbolic link loop" +msgstr "Pętla nawiązań symbolicznych" + +#: src/wildcard.cpp:42 +msgid "Rotten symbolic link" +msgstr "" + +#: src/wildcard.cpp:40 +msgid "Symbolic link to directory" +msgstr "Nawiązanie symboliczne do katalogu" + +#: src/wildcard.cpp:38 +msgid "Symbolic link" +msgstr "Nawiązanie symboliczne" + +#: src/wildcard.cpp:36 +msgid "Fifo" +msgstr "" + +#: src/wildcard.cpp:34 +msgid "Block device" +msgstr "" + +#: src/wildcard.cpp:32 +msgid "Character device" +msgstr "" + +#: src/wildcard.cpp:30 +msgid "File" +msgstr "Plik" + +#: src/wildcard.cpp:28 +msgid "Executable link" +msgstr "Link wykonywalny" + +#: src/wildcard.cpp:26 +msgid "Executable" +msgstr "Wykonywalny" + +#: src/sanity.cpp:39 +msgid "The pointer '%ls' is null" +msgstr "" + +#: src/sanity.cpp:34 +msgid "The pointer '%ls' is invalid" +msgstr "" + +#: src/sanity.cpp:18 +msgid "Errors detected, shutting down. Break on sanity_lose() to debug." +msgstr "" + +#: src/builtin_jobs.cpp:216 +msgid "%ls: There are no jobs\n" +msgstr "%ls: Nie ma żadnych zadań\n" + +#: src/builtin_jobs.cpp:196 src/builtin.cpp:2604 +msgid "%ls: No suitable job: %d\n" +msgstr "%ls: Brak pasujących zadań: %d\n" + +#: src/builtin_jobs.cpp:186 src/builtin.cpp:2585 src/builtin.cpp:2686 +msgid "%ls: '%ls' is not a job\n" +msgstr "%ls: '%ls' nie jest zadaniem\n" + +#: src/builtin_jobs.cpp:96 +msgid "Command\n" +msgstr "Komenda\n" + +#: src/builtin_jobs.cpp:85 +msgid "Process\n" +msgstr "Proces\n" + +#: src/builtin_jobs.cpp:77 +msgid "Group\n" +msgstr "Grupa\n" + +#: src/builtin_jobs.cpp:68 +msgid "running" +msgstr "uruchomiona" + +#: src/builtin_jobs.cpp:68 src/proc.cpp:644 +msgid "stopped" +msgstr "zatrzymana" + +#: src/builtin_jobs.cpp:60 +msgid "State\tCommand\n" +msgstr "Stan\tKomenda\n" + +#: src/builtin_jobs.cpp:58 +msgid "CPU\t" +msgstr "CPU\t" + +#: src/builtin_jobs.cpp:56 +msgid "Job\tGroup\t" +msgstr "Zadanie\tGrupa\t" diff --git a/share/completions/VBoxHeadless.fish b/share/completions/VBoxHeadless.fish new file mode 100644 index 000000000..4dbbce6cd --- /dev/null +++ b/share/completions/VBoxHeadless.fish @@ -0,0 +1,12 @@ +complete -c VBoxHeadless -l startvm -o startvm -s s -x -d "Start given VM" -a "(__fish_print_VBox_vms)" + +complete -c VBoxHeadless -l vrde -o vrde -s v -d "Enable or disamble VRDE server or don't change setting" -a "on off config" +complete -c VBoxHeadless -l vrdeproperty -o vrdeproperty -s e -x -d "Set VRDE property" +complete -c VBoxHeadless -l settingspw -x -d "Specify settings password" +complete -c VBoxHeadless -l settingspwfile -f -d "Specify file containing setting password" +complete -c VBoxHeadless -l start-paused -o start-paused -d "Start VM in paused state" +complete -c VBoxHeadless -l capture -o capture -s c -x -d "Record VM screen ouput to file" +complete -c VBoxHeadless -l width -s w -x -d "Frame width when recording" +complete -c VBoxHeadless -l height -s h -x -d "Frame height when recording" +complete -c VBoxHeadless -l bitrate -s r -x -d "Recording bit rate when recording" +complete -c VBoxHeadless -l filename -s f -f -d "File name when recording" diff --git a/share/completions/VBoxSDL.fish b/share/completions/VBoxSDL.fish new file mode 100644 index 000000000..f4ceef703 --- /dev/null +++ b/share/completions/VBoxSDL.fish @@ -0,0 +1,34 @@ +complete -c VBoxSDL -l startvm -x -d "Set virtual machine to start" -a "(__fish_print_VBox_vms)" + +complete -c VBoxSDL -l seperate -d "Run separate VM process or attach to a running VM" +complete -c VBoxSDL -l hda -f -d "Set temporary first hard disk" +complete -c VBoxSDL -l fda -f -d "Set temporary first floppy disk" +complete -c VBoxSDL -l cdrom -r -d "Set temporary CDROM/DVD" -a "none\tunmount" +complete -c VBoxSDL -l boot -x -d "Set temporary boot device" -a "a\tFloppy c\tFirst\ HD d\tDVD n\tNetwork" +complete -c VBoxSDL -l memory -x -d "Set temporary memory size in MB" +complete -c VBoxSDL -l vram -x -d "Set temporary video memory size in MB" +complete -c VBoxSDL -l fullscreen -d "Start VM in fullscreen mode" +complete -c VBoxSDL -l fullscreenresize -d "Resize guest on fullscreen" +complete -c VBoxSDL -l fixedmode -r -d "Use fixed SDL video mode with given width height and bit/pixel" +complete -c VBoxSDL -l nofstoggle -d "Forbid switching to/from fullscreen mode" +complete -c VBoxSDL -l noresize -d "Make SDL frame non resizable" +complete -c VBoxSDL -l nohostkey -d "Disable all hoskey combinations" +complete -c VBoxSDL -l nohostkeys -d "Disable specific hostkey combinations" +complete -c VBoxSDL -l nograbonclick -d "Disable mouse/keyboard grabbing on mouse click w/o additions" +complete -c VBoxSDL -l detecthostkey -d "Get hostkey identifier and modifier state" +complete -c VBoxSDL -l hostkey -r -d "Set host key to values obtained using --detecthostkey" +complete -c VBoxSDL -l termacpi -d "Send APCI power button when closing window" +complete -c VBoxSDL -l vrdp -d "Listen for VRDP connexions on if one of specified" +complete -c VBoxSDL -l discardstate -d "Discard saved state (if present) and revert to last snapshot (if present)" +complete -c VBoxSDL -l settingspw -x -d "Specify settings password" +complete -c VBoxSDL -l settingspwfile -f -d "Specify file containing setting password" +complete -c VBoxSDL -l rowr0 -d "Enable raw ring 3" +complete -c VBoxSDL -l rowr3 -d "Enable raw ring 0" +complete -c VBoxSDL -l patm -d "Enable PATM" +complete -c VBoxSDL -l csam -d "Enable CSAM" +complete -c VBoxSDL -l hwvirtex -d "Permit usage of VT-x/AMD-V" +complete -c VBoxSDL -l norowr0 -d "Disable raw ring 3" +complete -c VBoxSDL -l norowr3 -d "Disable raw ring 0" +complete -c VBoxSDL -l nopatm -d "Disable PATM" +complete -c VBoxSDL -l nocsam -d "Disable CSAM" +complete -c VBoxSDL -l nohwvirtex -d "Deny usage of VT-x/AMD-V" diff --git a/share/completions/adb.fish b/share/completions/adb.fish index bea9c784a..3db1888bb 100644 --- a/share/completions/adb.fish +++ b/share/completions/adb.fish @@ -110,7 +110,7 @@ complete -n '__fish_seen_subcommand_from install' -c adb -l 'iv' -d 'Hex-encoded # uninstall complete -n '__fish_seen_subcommand_from uninstall' -c adb -s k -d 'Keep the data and cache directories' -complete -n '__fish_seen_subcommand_from uninstall' -c adb -f -u -a "(__fish_adb_list_uninstallable_packages)" +complete -n '__fish_seen_subcommand_from uninstall' -c adb -f -a "(__fish_adb_list_uninstallable_packages)" # devices complete -n '__fish_seen_subcommand_from devices' -c adb -s l -d 'Also list device qualifiers' diff --git a/share/completions/adduser.fish b/share/completions/adduser.fish index 33d28182a..e55ff1c7d 100644 --- a/share/completions/adduser.fish +++ b/share/completions/adduser.fish @@ -16,7 +16,7 @@ complete -c adduser -l group --description 'When combined with --system, a group complete -c adduser -l help --description 'Display brief instructions' complete -c adduser -l home --description 'Use specified directory as the user\'s home directory' -x -a '(__fish_complete_directories)' complete -c adduser -l shell --description 'Use shell as the user\'s login shell, rather than the default specified by the configuration file' -x -a '(cat /etc/shells)' -complete -c adduser -l ingroup --description 'Add the new user to GROUP instead of a usergroup or the default group defined by USERS_GID in the configuration file' -x -a '(cat /etc/group|cut -d : -f 1)' +complete -c adduser -l ingroup --description 'Add the new user to GROUP instead of a usergroup or the default group defined by USERS_GID in the configuration file' -x -a '(cut -d : -f 1 /etc/group)' complete -c adduser -l no-create-home --description 'Do not create the home directory, even if it doesni\'t exist' complete -c adduser -l quiet --description 'Suppress informational messages, only show warnings and errors' complete -c adduser -l debug --description 'Be verbose, most useful if you want to nail down a problem with adduser' diff --git a/share/completions/apt.fish b/share/completions/apt.fish index c0bd654ec..6139fe43d 100644 --- a/share/completions/apt.fish +++ b/share/completions/apt.fish @@ -2,7 +2,7 @@ function __fish_apt_no_subcommand --description 'Test if apt has yet to be given the subcommand' for i in (commandline -opc) - if contains -- $i update upgrade full-upgrade search list install show remove edit-sources purge + if contains -- $i update upgrade full-upgrade search list install show remove edit-sources purge changelog autoremove return 1 end end @@ -11,7 +11,7 @@ end function __fish_apt_use_package --description 'Test if apt command should have packages as potential completion' for i in (commandline -opc) - if contains -- $i install remove upgrade full-upgrade show search purge + if contains -- $i install remove upgrade full-upgrade show search purge changelog return 0 end end @@ -66,3 +66,9 @@ __fish_apt_subcommand full-upgrade -r --description 'Upgrade packages, removing # Purge __fish_apt_subcommand purge -x --description 'Remove packages and delete their config files' + +# Changelog +__fish_apt_subcommand changelog -r --description 'Download and display package changelog' + +# Autoremove +__fish_apt_subcommand autoremove --description 'Remove packages no longer needed as dependencies' diff --git a/share/completions/base64.fish b/share/completions/base64.fish new file mode 100644 index 000000000..d7488c69d --- /dev/null +++ b/share/completions/base64.fish @@ -0,0 +1,5 @@ +complete -c base64 -l decode -s d -d "Decode data" +complete -c base64 -l ignore-garbage -s i -d "When decoding, ignore non-alphabet characters" +complete -c base64 -l wrap -s w -x -d "Wrap encoded line after given number of caracters (default 76)" +complete -c base64 -l help -d "Display help" +complete -c base64 -l version -d "Display version" diff --git a/share/completions/bc.fish b/share/completions/bc.fish index d7e9d38f8..c56903edd 100644 --- a/share/completions/bc.fish +++ b/share/completions/bc.fish @@ -1,7 +1,7 @@ # Completions for the binary calculator complete -c bc -s i -l interactive --description "Force interactive mode" -complete -c bc -s l -l math-lib --description "Define math library" +complete -c bc -s l -l mathlib --description "Define math library" complete -c bc -s w -l warn --description "Give warnings for extensions to POSIX bc" complete -c bc -s s -l standard --description "Process exactly POSIX bc" complete -c bc -s q -l quiet --description "Do not print the GNU welcome" diff --git a/share/completions/busctl.fish b/share/completions/busctl.fish index 695c30355..b103612fa 100644 --- a/share/completions/busctl.fish +++ b/share/completions/busctl.fish @@ -17,7 +17,7 @@ function __fish_busctl end command busctl $mode $argv --no-legend --no-pager ^/dev/null end - + # Only get the arguments to the actual command, skipping all options and arguments to options function __fish_busctl_get_command_args set -l skip @@ -49,7 +49,7 @@ function __fish_busctl_get_command_args end end end - + function __fish_busctl_busnames __fish_busctl list --acquired | string replace -r '\s+.*$' '' # Describe unique names (":1.32") with their process (e.g. `:1.32\tsteam`) @@ -63,7 +63,7 @@ end function __fish_busctl_interfaces -a busname -a object __fish_busctl introspect --list $busname $object | string replace -r '\s+.*$' '' end - + function __fish_busctl_members -a type -a busname -a object -a interface __fish_busctl introspect --list $busname $object $interface \ | string match -- "* $type *" | string replace -r '.(\S+) .*' '$1' @@ -108,7 +108,7 @@ end set -l commands list status monitor capture tree introspect call get-property set-property help complete -f -e -c busctl -complete -A -f -c busctl -n "not __fish_seen_subcommand_from $commands" -a "$commands" +complete -f -c busctl -n "not __fish_seen_subcommand_from $commands" -a "$commands" ### Arguments to commands # "status" only takes a single service as argument diff --git a/share/completions/bzr.fish b/share/completions/bzr.fish index facbf4783..bcc39d0e9 100644 --- a/share/completions/bzr.fish +++ b/share/completions/bzr.fish @@ -1,604 +1,114 @@ -# -# Command specific completions for the bzr command. -# These completions were generated from the commands -# man page by the make_completions.py script, but may -# have been hand edited since. -# +# NOTE: Fish helper functions are your best friend here! +# see https://github.com/fish-shell/fish-shell/blob/master/share/functions/__fish_seen_subcommand_from.fish +# and https://github.com/fish-shell/fish-shell/blob/master/share/functions/__fish_use_subcommand.fish -complete -c bzr -l dry-run --description 'Show what would be done, but don\'t actually do anything' -complete -c bzr -l file-ids-from --description 'ARG Lookup file ids from this tree' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l no-recurse --description 'Don\'t recursively add the contents of directories' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l dry-run --description 'Will show which files would be added, but not actually add them' -complete -c bzr -l file-ids-from --description 'Will try to use the file ids from the supplied path' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l remove --description 'Remove the alias' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l all --description 'Show annotations on all lines' -complete -c bzr -l directory --description 'ARG, -d Branch to operate on, instead of working directory' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l long --description 'Show commit date in annotations' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l revision --description 'ARG, -r See "help revisionspec" for details' -complete -c bzr -l show-ids --description 'Show internal object ids' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l directory --description 'ARG, -d Branch to operate on, instead of working directory' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l bind --description 'Bind new branch to from location' -complete -c bzr -l files-from --description 'ARG Get file contents from this tree' -complete -c bzr -l hardlink --description 'Hard-link working tree files where possible' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l no-tree --description 'Create a branch without a working-tree' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l revision --description 'ARG, -r See "help revisionspec" for details' -complete -c bzr -l stacked --description 'Create a stacked branch referring to the source branch' -complete -c bzr -l standalone --description 'Do not use a shared repository, even if available' -complete -c bzr -l switch --description 'Switch the checkout in the current directory to the new branch' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l use-existing-dir --description 'By default branch will fail if the target directory exists, but does not already have a control directory' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l recursive -s R --description 'Recursively scan for branches rather than just looking in the specified location' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l config --description 'LOCATION is the directory where the config lock is' -complete -c bzr -l force --description 'Do not ask for confirmation before breaking the lock' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l directory --description 'ARG, -d Branch to operate on, instead of working directory' -complete -c bzr -l filters --description 'Apply content filters to display the convenience form' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l name-from-revision --description 'The path name in the old tree' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l revision --description 'ARG, -r See "help revisionspec" for details' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l branch --description 'Check the branch related to the current directory' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l repo --description 'Check the repository related to the current directory' -complete -c bzr -l tree --description 'Check the working tree related to the current directory' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l files-from --description 'ARG Get file contents from this tree' -complete -c bzr -l hardlink --description 'Hard-link working tree files where possible' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l lightweight --description 'Perform a lightweight checkout' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l revision --description 'ARG, -r See "help revisionspec" for details' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l detritus --description 'Delete conflict files, merge and revert backups, and failed selftest dirs' -complete -c bzr -l directory --description 'ARG, -d Branch to operate on, instead of working directory' -complete -c bzr -l dry-run --description 'Show files to delete instead of deleting them' -complete -c bzr -l force --description 'Do not prompt before deleting' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l ignored --description 'Delete all ignored files' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l unknown --description 'Delete files unknown to bzr (default)' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l author --description 'ARG Set the author\'s name, if it\'s different from the committer' -complete -c bzr -l commit-time --description 'ARG Manually set a commit time using commit date format, e' -complete -c bzr -l exclude --description 'ARG, -x Do not consider changes made to a given path' -complete -c bzr -l file --description 'MSGFILE, -F Take commit message from this file' -complete -c bzr -l fixes --description 'ARG Mark a bug as being fixed by this revision (see "bzr help bugs")' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l local --description 'Perform a local commit in a bound branch' -complete -c bzr -l lossy --description 'When committing to a foreign version control system do not push data that can not be natively represented' -complete -c bzr -l message --description 'ARG, -m Description of the new revision' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l show-diff -s p --description 'When no message is supplied, show the diff along with the status summary in the message editor' -complete -c bzr -l strict --description 'Refuse to commit if there are unknown files in the working tree' -complete -c bzr -l unchanged --description 'Commit even if nothing has changed' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l show-diff --description 'Option' -complete -c bzr -l all --description 'Display all the defined values for the matching options' -complete -c bzr -l directory --description 'ARG, -d Branch to operate on, instead of working directory' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l remove --description 'Remove the option from the configuration file' -complete -c bzr -l scope --description 'ARG Reduce the scope to the specified configuration file' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l directory --description 'ARG, -d Branch to operate on, instead of working directory' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l text --description 'List paths of files with text conflicts' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l directory --description 'ARG, -d Branch to operate on, instead of working directory' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l show-ids --description 'Show internal object ids' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l change --description 'ARG, -c Select changes introduced by the specified revision' -complete -c bzr -l diff-options --description 'ARG Pass these options to the external diff program' -complete -c bzr -l format --description 'ARG, -F Diff format to use' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l new --description 'ARG Branch/tree to compare to' -complete -c bzr -l old --description 'ARG Branch/tree to compare from' -complete -c bzr -l prefix --description 'ARG, -p Set prefixes added to old and new filenames, as two values separated by a colon' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l revision --description 'ARG, -r See "help revisionspec" for details' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l using --description 'ARG Use this command to compare files' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l directory --description 'ARG, -d Branch to push from, rather than the one containing the working directory' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l no-rebase --description 'Do not rebase after push' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l remember --description 'Remember the specified location as a default' -complete -c bzr -l strict --description 'Refuse to push if there are uncommitted changes in the working tree, --no-strict disables the check' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l directory --description 'ARG, -d Branch to operate on, instead of working directory' -complete -c bzr -l filters --description 'Apply content filters to export the convenient form' -complete -c bzr -l format --description 'ARG Type of file to export to' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l per-file-timestamps --description 'Set modification time of files to that of the last revision in which it was changed' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l revision --description 'ARG, -r See "help revisionspec" for details' -complete -c bzr -l root --description 'ARG Name of the root directory inside the exported file' -complete -c bzr -l uncommitted --description 'Export the working tree contents rather than that of the last revision' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l long --description 'Show help on all commands' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l default-rules --description 'Display the default ignore rules that bzr uses' -complete -c bzr -l directory --description 'ARG, -d Branch to operate on, instead of working directory' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l directory --description 'ARG, -d Branch to operate on, instead of working directory' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l append-revisions-only --description 'Never change revnos or the existing log' -complete -c bzr -l create-prefix --description 'Create the path leading up to the branch if it does not already exist' -complete -c bzr -l format --description 'ARG Specify a format for this branch' -complete -c bzr -l 2a --description 'Format for the bzr 2' -complete -c bzr -l default --description 'Format for the bzr 2' -complete -c bzr -l development-colo --description 'The 2a format with experimental support for colocated branches' -complete -c bzr -l pack-0.92 --description 'Pack-based format used in 1' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l no-tree --description 'Create a branch without a working tree' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l format --description 'ARG Specify a format for this repository' -complete -c bzr -l 2a --description 'Format for the bzr 2' -complete -c bzr -l default --description 'Format for the bzr 2' -complete -c bzr -l development-colo --description 'The 2a format with experimental support for colocated branches' -complete -c bzr -l pack-0.92 --description 'Pack-based format used in 1' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l no-trees --description 'Branches in the repository will default to not having a working tree' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l authors --description 'ARG What names to list as authors - first, all or committer' -complete -c bzr -l change --description 'ARG, -c Show just the specified revision' -complete -c bzr -l exclude-common-ancestry --description 'Display only the revisions that are not part of both ancestries (require -rX' -complete -c bzr -l forward --description 'Show from oldest to newest' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l include-merged --description 'Show merged revisions like --levels 0 does' -complete -c bzr -l levels --description 'N, -n Number of levels to display - 0 for all, 1 for flat' -complete -c bzr -l limit --description 'N, -l Limit the output to the first N revisions' -complete -c bzr -l log-format --description 'ARG Use specified log format' -complete -c bzr -l gnu-changelog --description 'Format used by GNU ChangeLog files' -complete -c bzr -l line --description 'Log format with one line per revision' -complete -c bzr -l long --description 'Detailed log format' -complete -c bzr -l short --description 'Moderately short log format' -complete -c bzr -l match --description 'ARG, -m Show revisions whose properties match this expression' -complete -c bzr -l match-author --description 'ARG Show revisions whose authors match this expression' -complete -c bzr -l match-bugs --description 'ARG Show revisions whose bugs match this expression' -complete -c bzr -l match-committer --description 'ARG Show revisions whose committer matches this expression' -complete -c bzr -l match-message --description 'ARG Show revisions whose message matches this expression' -complete -c bzr -l omit-merges --description 'Do not report commits with more than one parent' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l revision --description 'ARG, -r See "help revisionspec" for details' -complete -c bzr -l show-diff -s p --description 'Show changes made in each revision as a patch' -complete -c bzr -l show-ids --description 'Show internal object ids' -complete -c bzr -l signatures --description 'Show digital signature validity' -complete -c bzr -l timezone --description 'ARG Display timezone as local, original, or utc' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Show files changed in each revision' -complete -c bzr -s l --description 'N display a maximum of N revisions -n N display N levels of revisions (0 for all, 1 for collapsed) -v display a status summary (delta) for each revision -p display a diff (patch) for each revision --show-ids display revision-ids (and file-ids), not just revnos' -complete -c bzr -o rX --description 'Display revision X -rX' -complete -c bzr -o r..Y --description 'Display up to and including revision Y -rX' -complete -c bzr -o r-1 --description 'Show just the tip -r-10' -complete -c bzr -o rsubmit:.. --description 'Show what\'s new on this branch -rancestor:path' -complete -c bzr -o rdate:yesterday.. --description 'Show changes since yesterday' -complete -c bzr -l match-message --description 'Can be used to only match a specific field' -complete -c bzr -l directory --description 'ARG, -d Branch to operate on, instead of working directory' -complete -c bzr -l from-root --description 'Print paths relative to the root of the branch' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l ignored -s i --description 'Print ignored files' -complete -c bzr -l kind --description 'ARG, -k List entries of a particular kind: file, directory, symlink' -complete -c bzr -l null -s 0 --description 'Use an ASCII NUL (\0) separator rather than a newline' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l recursive -s R --description 'Recurse into subdirectories' -complete -c bzr -l revision --description 'ARG, -r See "help revisionspec" for details' -complete -c bzr -l show-ids --description 'Show internal object ids' -complete -c bzr -l unknown -s u --description 'Print unknown files' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l versioned -s V --description 'Print versioned files' -complete -c bzr -l change --description 'ARG, -c Select changes introduced by the specified revision' -complete -c bzr -l directory --description 'ARG, -d Branch to merge into, rather than the one containing the working directory' -complete -c bzr -l force --description 'Merge even if the destination tree has uncommitted changes' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l interactive -s i --description 'Select changes interactively' -complete -c bzr -l merge-type --description 'ARG Select a particular merge algorithm' -complete -c bzr -l diff3 --description 'Merge using external diff3' -complete -c bzr -l lca --description 'LCA-newness merge' -complete -c bzr -l merge3 --description 'Native diff3-style merge' -complete -c bzr -l weave --description 'Weave-based merge' -complete -c bzr -l preview --description 'Instead of merging, show a diff of the merge' -complete -c bzr -l pull --description 'If the destination is already completely merged into the source, pull from the source rather than merging' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l remember --description 'Remember the specified location as a default' -complete -c bzr -l reprocess --description 'Reprocess to reduce spurious conflicts' -complete -c bzr -l revision --description 'ARG, -r See "help revisionspec" for details' -complete -c bzr -l show-base --description 'Show base revision text in conflicts' -complete -c bzr -l uncommitted --description 'Apply uncommitted changes from a working copy, instead of branch changes' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l directory --description 'ARG, -d Branch to operate on, instead of working directory' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l include-merged --description 'Show all revisions in addition to the mainline ones' -complete -c bzr -l log-format --description 'ARG Use specified log format' -complete -c bzr -l gnu-changelog --description 'Format used by GNU ChangeLog files' -complete -c bzr -l line --description 'Log format with one line per revision' -complete -c bzr -l long --description 'Detailed log format' -complete -c bzr -l short --description 'Moderately short log format' -complete -c bzr -l mine-only --description 'Display changes in the local branch only' -complete -c bzr -l my-revision --description 'ARG Filter on local branch revisions (inclusive)' -complete -c bzr -l other --description 'Same as --theirs-only' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l reverse --description 'Reverse the order of revisions' -complete -c bzr -l revision --description 'ARG, -r Filter on other branch revisions (inclusive)' -complete -c bzr -l show-ids --description 'Show internal object ids' -complete -c bzr -l theirs-only --description 'Display changes in the remote branch only' -complete -c bzr -l this --description 'Same as --mine-only' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l parents -s p --description 'No error if existing, make parent directories as needed' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l after --description 'Move only the bzr identifier of the file, because the file has already been moved' -complete -c bzr -l auto --description 'Automatically guess renames' -complete -c bzr -l dry-run --description 'Avoid making changes when guessing renames' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l directory --description 'ARG, -d Branch to operate on, instead of working directory' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l clean-obsolete-packs --description 'Delete obsolete packs to save disk space' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l verbose --description 'Shows the path where each plugin is located' -complete -c bzr -l directory --description 'ARG, -d Branch to pull into, rather than the one containing the working directory' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l local --description 'Perform a local pull in a bound branch' -complete -c bzr -l overwrite --description 'Ignore differences between branches and overwrite unconditionally' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l remember --description 'Remember the specified location as a default' -complete -c bzr -l revision --description 'ARG, -r See "help revisionspec" for details' -complete -c bzr -l show-base --description 'Show base revision text in conflicts' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Show logs of pulled revisions' -complete -c bzr -l create-prefix --description 'Create the path leading up to the branch if it does not already exist' -complete -c bzr -l directory --description 'ARG, -d Branch to push from, rather than the one containing the working directory' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l no-tree --description 'Don\'t populate the working tree, even for protocols that support it' -complete -c bzr -l overwrite --description 'Ignore differences between branches and overwrite unconditionally' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l remember --description 'Remember the specified location as a default' -complete -c bzr -l revision --description 'ARG, -r See "help revisionspec" for details' -complete -c bzr -l stacked --description 'Create a stacked branch that references the public location of the parent branch' -complete -c bzr -l stacked-on --description 'ARG Create a stacked branch that refers to another branch for the commit history' -complete -c bzr -l strict --description 'Refuse to push if there are uncommitted changes in the working tree, --no-strict disables the check' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l use-existing-dir --description 'By default push will fail if the target directory exists, but does not already have a control directory' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l bind-to --description 'ARG Branch to bind checkout to' -complete -c bzr -l force --description 'Perform reconfiguration even if local changes will be lost' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l repository_trees --description 'ARG Whether new branches in the repository have trees' -complete -c bzr -l with-no-trees --description 'Reconfigure repository to not create working trees on branches by default' -complete -c bzr -l with-trees --description 'Reconfigure repository to create working trees on branches by default' -complete -c bzr -l repository_type --description 'ARG Location fo the repository' -complete -c bzr -l standalone --description 'Reconfigure to be a standalone branch (i' -complete -c bzr -l use-shared --description 'Reconfigure to use a shared repository' -complete -c bzr -l stacked-on --description 'ARG Reconfigure a branch to be stacked on another branch' -complete -c bzr -l tree_type --description 'ARG The relation between branch and tree' -complete -c bzr -l branch --description 'Reconfigure to be an unbound branch with no working tree' -complete -c bzr -l checkout --description 'Reconfigure to be a bound branch with a working tree' -complete -c bzr -l lightweight-checkout --description 'Reconfigure to be a lightweight checkout (with no local history)' -complete -c bzr -l tree --description 'Reconfigure to be an unbound branch with a working tree' -complete -c bzr -l unstacked --description 'Reconfigure a branch to be unstacked' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l merge-type --description 'ARG Select a particular merge algorithm' -complete -c bzr -l diff3 --description 'Merge using external diff3' -complete -c bzr -l lca --description 'LCA-newness merge' -complete -c bzr -l merge3 --description 'Native diff3-style merge' -complete -c bzr -l weave --description 'Weave-based merge' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l reprocess --description 'Reprocess to reduce spurious conflicts' -complete -c bzr -l show-base --description 'Show base revision text in conflicts' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l file-deletion-strategy --description 'ARGThe file deletion mode to be used' -complete -c bzr -l force --description 'Delete all the specified files, even if they can not be recovered and even if they are non-empty directories' -complete -c bzr -l keep --description 'Delete from bzr but leave the working copy' -complete -c bzr -l no-backup --description 'Don\'t backup changed files' -complete -c bzr -l safe --description 'Backup changed files (default)' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l new --description 'Only remove files that have never been committed' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l directory --description 'ARG, -d Branch to operate on, instead of working directory' -complete -c bzr -l force --description 'Remove branch even if it is the active branch' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l force --description 'Remove the working tree even if it has uncommitted or shelved changes' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l action --description 'ARG How to resolve the conflict' -complete -c bzr -l done --description 'Marks the conflict as resolved' -complete -c bzr -l take-other --description 'Resolve the conflict taking the merged version into account' -complete -c bzr -l take-this --description 'Resolve the conflict preserving the version in the working tree' -complete -c bzr -l all --description 'Resolve all conflicts in this tree' -complete -c bzr -l directory --description 'ARG, -d Branch to operate on, instead of working directory' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l forget-merges --description 'Remove pending merge marker, without changing any files' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l no-backup --description 'Do not save backups of reverted files' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l revision --description 'ARG, -r See "help revisionspec" for details' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l revision --description 'ARG, -r See "help revisionspec" for details' -complete -c bzr -l tree --description 'Show revno of working tree' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l body --description 'ARG Body for the email' -complete -c bzr -l format --description 'ARG Use the specified output format' -complete -c bzr -l from --description 'ARG, -f Branch to generate the submission from, rather than the one containing the working directory' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l mail-to --description 'ARG Mail the request to this address' -complete -c bzr -l message --description 'ARG, -m Message string' -complete -c bzr -l no-bundle --description 'Do not include a bundle in the merge directive' -complete -c bzr -l no-patch --description 'Do not include a preview patch in the merge directive' -complete -c bzr -l output --description 'ARG, -o Write merge directive to this file or directory; use - for stdout' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l remember --description 'Remember submit and public branch' -complete -c bzr -l revision --description 'ARG, -r See "help revisionspec" for details' -complete -c bzr -l strict --description 'Refuse to send if there are uncommitted changes in the working tree, --no-strict disables the check' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l allow-writes --description 'By default the server is a readonly server' -complete -c bzr -l client-timeout --description 'ARG Override the default idle client timeout (5min)' -complete -c bzr -l directory --description 'ARG, -d Serve contents of this directory' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l inet --description 'Serve on stdin/out for use from inetd or sshd' -complete -c bzr -l port --description 'ARG Listen for connections on nominated port of the form [hostname:]portnumber' -complete -c bzr -l protocol --description 'ARG Protocol to serve' -complete -c bzr -l bzr --description 'The Bazaar smart server protocol over TCP' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l all --description 'Shelve all changes' -complete -c bzr -l destroy --description 'Destroy removed changes instead of shelving them' -complete -c bzr -l directory --description 'ARG, -d Branch to operate on, instead of working directory' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l list --description 'List shelved changes' -complete -c bzr -l message --description 'ARG, -m Message string' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l revision --description 'ARG, -r See "help revisionspec" for details' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l writer --description 'ARG Method to use for writing diffs' -complete -c bzr -l plain --description 'Plaintext diff output' -complete -c bzr -l dry-run --description 'Don\'t actually sign anything, just print the revisions that would be signed' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l change --description 'ARG, -c Select changes introduced by the specified revision' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l no-classify --description 'Do not mark object type using indicator' -complete -c bzr -l no-pending --description 'Don\'t show pending merges' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l revision --description 'ARG, -r See "help revisionspec" for details' -complete -c bzr -l short -s S --description 'Use short status indicators' -complete -c bzr -l show-ids --description 'Show internal object ids' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l versioned -s V --description 'Only show versioned files' -complete -c bzr -l create-branch -s b --description 'Create the target branch from this one before switching to it' -complete -c bzr -l directory --description 'ARG, -d Branch to operate on, instead of working directory' -complete -c bzr -l force --description 'Switch even if local commits will be lost' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l revision --description 'ARG, -r See "help revisionspec" for details' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l delete --description 'Delete this tag rather than placing it' -complete -c bzr -l directory --description 'ARG, -d Branch in which to place the tag' -complete -c bzr -l force --description 'Replace existing tags' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l revision --description 'ARG, -r See "help revisionspec" for details' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l delete --description 'Oldname``' -complete -c bzr -l directory --description 'ARG, -d Branch whose tags should be displayed' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l revision --description 'ARG, -r See "help revisionspec" for details' -complete -c bzr -l show-ids --description 'Show internal object ids' -complete -c bzr -l sort --description 'ARG Sort tags by different criteria' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l long --description 'Produce long-format testament' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l revision --description 'ARG, -r See "help revisionspec" for details' -complete -c bzr -l strict --description 'Produce a strict-format testament' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l directory --description 'ARG, -d Branch to operate on, instead of working directory' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l dry-run --description 'Don\'t actually make changes' -complete -c bzr -l force --description 'Say yes to all questions' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l keep-tags --description 'Keep tags that point to removed revisions' -complete -c bzr -l local --description 'Only remove the commits from the local branch when in a checkout' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l revision --description 'ARG, -r See "help revisionspec" for details' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l verbose --description 'Will print out what is being removed' -complete -c bzr -l dry-run --description 'Will go through all the motions, but not actually remove anything' -complete -c bzr -l action --description 'ARG The action to perform' -complete -c bzr -l apply --description 'Apply changes and remove from the shelf' -complete -c bzr -l delete-only --description 'Delete changes without applying them' -complete -c bzr -l dry-run --description 'Show changes, but do not apply or remove them' -complete -c bzr -l keep --description 'Apply changes but don\'t delete them' -complete -c bzr -l preview --description 'Instead of unshelving the changes, show the diff that would result from unshelving' -complete -c bzr -l directory --description 'ARG, -d Branch to operate on, instead of working directory' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l revision --description 'ARG, -r See "help revisionspec" for details' -complete -c bzr -l show-base --description 'Show base revision text in conflicts' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l clean --description 'Remove the backup' -complete -c bzr -l dry-run --description 'Show what would be done, but don\'t actually do anything' -complete -c bzr -l format --description 'ARG Upgrade to a specific format' -complete -c bzr -l 2a --description 'Format for the bzr 2' -complete -c bzr -l default --description 'Format for the bzr 2' -complete -c bzr -l development-colo --description 'The 2a format with experimental support for colocated branches' -complete -c bzr -l pack-0.92 --description 'Pack-based format used in 1' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l acceptable-keys --description 'ARG, -k Comma separated list of GPG key patterns which are acceptable for verification' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l revision --description 'ARG, -r See "help revisionspec" for details' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l short --description 'Print just the version number' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l all --description 'Include all possible information' -complete -c bzr -l check-clean --description 'Check if tree is clean' -complete -c bzr -l format --description 'ARG Select the output format' -complete -c bzr -l custom --description 'Version info in Custom template-based format' -complete -c bzr -l python --description 'Version info in Python format' -complete -c bzr -l rio --description 'Version info in RIO (simple text) format (default)' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l include-file-revisions --description 'Include the last revision for each file' -complete -c bzr -l include-history --description 'Include the revision-history' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l revision --description 'ARG, -r See "help revisionspec" for details' -complete -c bzr -l template --description 'ARG Template for the output' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l template --description 'VERSION_INFO \"Project 1' -complete -c bzr -l all --description 'Apply list or delete action to all views' -complete -c bzr -l delete --description 'Delete the view' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l name --description 'ARG Name of the view to define, list or delete' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l switch --description 'ARG Name of the view to switch to' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' -complete -c bzr -l branch --description 'Set identity for the current branch instead of globally' -complete -c bzr -l directory --description 'ARG, -d Branch to operate on, instead of working directory' -complete -c bzr -l email --description 'Display email address only' -complete -c bzr -l help -s h --description 'Show help message' -complete -c bzr -l quiet -s q --description 'Only display errors and warnings' -complete -c bzr -l usage --description 'Show usage message and options' -complete -c bzr -l verbose -s v --description 'Display more information' + +# help commands +complete -f -c bzr -n '__fish_use_subcommand' -a help --description 'Show help' +complete -f -c bzr -n '__fish_seen_subcommand_from help' -a topics --description 'List all help topics' +complete -f -c bzr -n '__fish_seen_subcommand_from help' -a commands --description 'List all commands' +complete -f -c bzr -n '__fish_seen_subcommand_from help' -a formats --description 'Help about supported formats' +complete -f -c bzr -n '__fish_seen_subcommand_from help' -a current-formats --description 'Help about current supported formats' +complete -f -c bzr -n '__fish_seen_subcommand_from help' -a revisionspec -d 'How to specify revisions in bzr' +complete -f -c bzr -n '__fish_seen_subcommand_from help' -a bugs -d 'Show bug tracker settings in bzr' +# TODO: Add help about specific commands generating the output + +# init command +complete -f -c bzr -n '__fish_use_subcommand' -a init --description 'Makes this directory a versioned branch' +complete -f -c bzr -n '__fish_seen_subcommand_from init' -l create-prefix --description 'Create the path leading up to the branch if it does not already exists' +complete -f -c bzr -n '__fish_seen_subcommand_from init' -l no-tree --description 'Create a branch without a working tree' +complete -f -c bzr -n '__fish_seen_subcommand_from init' -l append-revisions-only --description 'Never change revnos or the existing log. Append revisions to it only' +# TODO: Add init using path directory + +# branch command +complete -f -c bzr -n '__fish_use_subcommand' -a branch --description 'Make a copy of another branch' +complete -f -c bzr -n '__fish_seen_subcommand_from branch' -l use-existing-dir --description 'Proceed even if directory exits' +complete -f -c bzr -n '__fish_seen_subcommand_from branch' -l stacked --description 'Create a stacked branch referring to the source branch' +complete -f -c bzr -n '__fish_seen_subcommand_from branch' -l standalone --description 'Do not use a shared repository, even if available' +complete -f -c bzr -n '__fish_seen_subcommand_from branch' -l switch --description 'Switch the checkout in the current directory to the new branch' +complete -f -c bzr -n '__fish_seen_subcommand_from branch' -l hardlink --description 'Hard-link working tree files where possible' +complete -f -c bzr -n '__fish_seen_subcommand_from branch' -l bind --description 'Bind new branch to from location' +complete -f -c bzr -n '__fish_seen_subcommand_from branch' -l no-tree --description 'Create a branch without a working-tree' +# TODO: Add source/destination branch or directory + +# add command +complete -f -c bzr -n '__fish_use_subcommand' -a add -d 'Make files or directories versioned' +complete -f -c bzr -n '__fish_seen_subcommand_from add' -l no-recurse -s N -d 'Don\'t recursively add the contents of directories' + +# ignore command +complete -f -c bzr -n '__fish_use_subcommand' -a ignore -d 'Ignore a file or pattern' +complete -f -c bzr -n '__fish_seen_subcommand_from ignore' -l default-rules -d 'Display the default ignore rules that bzr uses' + +# mv command +complete -f -c bzr -n '__fish_use_subcommand' -a mv -d 'Move or rename a versioned file' +complete -f -c bzr -n '__fish_seen_subcommand_from mv' -l auto -d 'Automatically guess renames' +complete -f -c bzr -n '__fish_seen_subcommand_from mv' -l after -d 'Move only the bzr identifier of the file, because the file has already been moved' + +# status command +complete -f -c bzr -n '__fish_use_subcommand' -a status -d 'Summarize changes in working copy' +complete -f -c bzr -n '__fish_seen_subcommand_from status' -l short -s S -d 'Use short status indicators' +complete -f -c bzr -n '__fish_seen_subcommand_from status' -l versioned -s V -d 'Only show versioned files' +complete -f -c bzr -n '__fish_seen_subcommand_from status' -l no-pending -d 'Don\'t show pending merges' +complete -f -c bzr -n '__fish_seen_subcommand_from status' -l no-classify -d 'Do not mark object type using indicator' +complete -f -c bzr -n '__fish_seen_subcommand_from status' -l show-ids -d 'Show internal object ids' + +# diff command +complete -f -c bzr -n '__fish_use_subcommand' -a diff -d 'Show detailed diffs' +# TODO: Add file diff options + +# merge command +complete -f -c bzr -n '__fish_use_subcommand' -a merge -d 'Pull in changes from another branch' +complete -f -c bzr -n '__fish_seen_subcommand_from merge' -l pull -d 'If the destination is already completely merged into the source, pull from the source rather than merging' +complete -f -c bzr -n '__fish_seen_subcommand_from merge' -l remember -d 'Remember the specified location as a default' +complete -f -c bzr -n '__fish_seen_subcommand_from merge' -l force -d 'Merge even if the destination tree has uncommitted changes' +complete -f -c bzr -n '__fish_seen_subcommand_from merge' -l reprocess -d 'Reprocess to reduce spurious conflicts' +complete -f -c bzr -n '__fish_seen_subcommand_from merge' -l uncommited -d 'Apply uncommitted changes from a working copy, instead of branch changes' +complete -f -c bzr -n '__fish_seen_subcommand_from merge' -l show-base -d 'Show base revision text in conflicts' +complete -f -c bzr -n '__fish_seen_subcommand_from merge' -l preview -d 'Instead of merging, show a diff of the merge' +complete -f -c bzr -n '__fish_seen_subcommand_from merge' -l interactive -s i -d 'Select changes interactively' +complete -f -c bzr -n '__fish_seen_subcommand_from merge' -l directory -s d -d 'Branch to merge into, rather than the one containing the working directory' +complete -f -c bzr -n '__fish_seen_subcommand_from merge' -l change -s c -d 'Select changes introduced by the specified revision' +complete -f -c bzr -n '__fish_seen_subcommand_from merge' -l revision -s r -d 'Select changes introduced by the specified revision' + +# commit command +complete -f -c bzr -n '__fish_use_subcommand' -a commit -d 'Save some or all changes' +complete -f -c bzr -n '__fish_seen_subcommand_from commit' -l show-diff -s p -d 'When no message is supplied, show the diff along with the status summary in the message editor' +complete -f -c bzr -n '__fish_seen_subcommand_from commit' -l file -s F -d 'Take commit message from this file' +complete -f -c bzr -n '__fish_seen_subcommand_from commit' -l exclude -s x -d 'Do not consider changes made to a given path' +complete -f -c bzr -n '__fish_seen_subcommand_from commit' -l message -s m -d 'Description of the new revision' +complete -f -c bzr -n '__fish_seen_subcommand_from commit' -l author -d 'Set the author\'s name, if it\'s different from the commiter' +complete -f -c bzr -n '__fish_seen_subcommand_from commit' -l commit-time -d 'Manually set a commit time using commit date format' +complete -f -c bzr -n '__fish_seen_subcommand_from commit' -l unchanged -d 'Commit even if nothing has changed' +complete -f -c bzr -n '__fish_seen_subcommand_from commit' -l fixes -d 'Mark a bug as being fixed by this revision' +complete -f -c bzr -n '__fish_seen_subcommand_from commit' -l strict -d 'Refuse to commit if there are unknown files in the working tree' +complete -f -c bzr -n '__fish_seen_subcommand_from commit' -l lossy -d 'When committing to a foreign version control system do not push data that can not be natively represented' +complete -f -c bzr -n '__fish_seen_subcommand_from commit' -l local -d 'Perform a local commit in a bound branch. Local commits are not pushed to the master branch until a normal commit is performed' + +# send command +complete -f -c bzr -n '__fish_use_subcommand' -a send -d 'Send changes via email' +complete -f -c bzr -n '__fish_seen_subcommand_from send' -l body -d 'Body for the email' +complete -f -c bzr -n '__fish_seen_subcommand_from send' -l remember -d 'Remember submit and public branch' +complete -f -c bzr -n '__fish_seen_subcommand_from send' -l mail-to -d 'Mail the request to this address' +complete -f -c bzr -n '__fish_seen_subcommand_from send' -l format -d 'Use the specified output format' +complete -f -c bzr -n '__fish_seen_subcommand_from send' -l no-bundle -d 'Do not include a bundle in the merge directive' +complete -f -c bzr -n '__fish_seen_subcommand_from send' -l strict -d 'Refuse to send if there are uncommitted changes in the working tree, --no-strict disables the check' +complete -f -c bzr -n '__fish_seen_subcommand_from send' -l no-patch -d 'Do not include a preview patch in the merge directive' + +# log command +complete -f -c bzr -n '__fish_use_subcommand' -a log -d 'Show history of changes' + +# check command +complete -f -c bzr -n '__fish_use_subcommand' -a check -d 'Validate storage' +complete -f -c bzr -n '__fish_seen_subcommand_from check' -l tree -d 'Check the working tree related to the current directory' +complete -f -c bzr -n '__fish_seen_subcommand_from check' -l repo -d 'Check the repository related to the current directory' +complete -f -c bzr -n '__fish_seen_subcommand_from check' -l branch -d 'Check the branch related to the current directory' + +# Common long/short options +set -l $cmds init branch add ignore mv status diff merge commit send log check +complete -f -c bzr -n '__fish_seen_subcommand_from $cmds' -l usage --description 'Show usage message and options' +complete -f -c bzr -n '__fish_seen_subcommand_from $cmds' -s h -l help --description 'Show help message' +complete -f -c bzr -n '__fish_seen_subcommand_from $cmds' -s q -l quiet --description 'Only displays errors and warnings' +complete -f -c bzr -n '__fish_seen_subcommand_from $cmds' -s v -l verbose --description 'Display more information' + +# Commands with dry-run option +complete -f -c bzr -n '__fish_seen_subcommand_from add mv' -l dry-run --description 'Show what would be done' diff --git a/share/completions/cargo.fish b/share/completions/cargo.fish index 7402427d5..f0f0fe61d 100644 --- a/share/completions/cargo.fish +++ b/share/completions/cargo.fish @@ -1,7 +1,7 @@ # Tab completion for cargo (https://github.com/rust-lang/cargo). complete -e -c cargo -complete -c cargo -s h -l help +complete -c cargo -s h -l help complete -c cargo -s V -l version -d 'Print version info and exit' complete -c cargo -l list -d 'List installed commands' complete -c cargo -s v -l verbose -d 'Use verbose output' diff --git a/share/completions/castnow.fish b/share/completions/castnow.fish new file mode 100644 index 000000000..6788b1c95 --- /dev/null +++ b/share/completions/castnow.fish @@ -0,0 +1,31 @@ +# Castnow is a utility that can be used to play back media files on Chromecast devices. +# See: https://github.com/xat/castnow + +set -l __fish_castnow_keys "space\tToggle\ between\ play\ and\ pause m\tToggle\ mute t\tToggle\ subtitles up\tVolume\ up down\tVolume\ down left\tSeek\ backward right\tSeek\ forward n\tNext\ in\ playlist s\tStop\ playback quit\tQuit" + +complete -c castnow -l tomp4 -d "Convert file to mp4 during playback" +complete -c castnow -l device -d "Specify name of Chromecast device to be used" -x +complete -c castnow -l address -d "Specify IP or hostname of Chromecast device" -x +complete -c castnow -l subtitles -d "Path or URL to SRT or VTT file" -x -a "( + __fish_complete_suffix .srt + __fish_complete_suffix .vtt +)" +complete -c castnow -l subtitles-scale -d "Set subtitles font scale" -x +complete -c castnow -l subtitles-color -d "Set subtitles font RGBA color" -x +complete -c castnow -l subtitles-port -d "Specify port to be used for serving subtitles" -x +complete -c castnow -l myip -d "Set local IP" -x +complete -c castnow -l quiet -d "No output" +complete -c castnow -l type -d "Explicitly set the mime-type" -a "(__fish_print_xdg_mimetypes | string match -r '^video/.*')" -x +complete -c castnow -l bypass-srt-encoding -d "Disable automatic UTF-8 encoding of SRT subtitles" +complete -c castnow -l seek -d "Seek to specified time (format: [hh:]mm:ss)" -x +complete -c castnow -l loop -d "Loop over playlist, or file" +complete -c castnow -l shuffle -d "Play in random order" +complete -c castnow -l recursive -d "List all files in directories recursively" +complete -c castnow -l volume-step -d "Set at which the volume changes" -x +complete -c castnow -l localfile-port -d "Specify port to be used for serving local file" -x +complete -c castnow -l transcode-port -d "Specify port to be used for serving transcoded file" -x +complete -c castnow -l torrent-port -d "Specify port to be used for serving torrented file" -x +complete -c castnow -l stdin-port -d "Specify port to be used for serving file read from stdin" -x +complete -c castnow -l command -d "Execute key command(s)" -x -a "(__fish_append , $__fish_castnow_keys)" +complete -c castnow -l exit -d "Exit when playback begins or --command completes" +complete -c castnow -l help -d "Display help" diff --git a/share/completions/configure.fish b/share/completions/configure.fish index 8834842be..8ef9f044d 100644 --- a/share/completions/configure.fish +++ b/share/completions/configure.fish @@ -10,5 +10,3 @@ complete -c configure -l exec-prefix --description "Architecture-dependent insta complete -c configure -l build --description "Configure for building on BUILD" -x complete -c configure -l host --description "Cross-compile to build programs to run on HOST" -x complete -c configure -l target --description "Configure for building compilers for TARGET" -x - -complete -c configure -u diff --git a/share/completions/connmanctl.fish b/share/completions/connmanctl.fish index df97de307..197364fb4 100644 --- a/share/completions/connmanctl.fish +++ b/share/completions/connmanctl.fish @@ -23,7 +23,7 @@ complete -f -c connmanctl -n "test (count (commandline -opc)) -lt 2" -a "state" complete -f -c connmanctl -n "test (count (commandline -opc)) -lt 2" -a "technologies" -d "Display technologies" complete -f -c connmanctl -n "test (count (commandline -opc)) -lt 2" -a "clock" -d "Get System Clock Properties" complete -f -c connmanctl -n "test (count (commandline -opc)) -lt 2" -a "enable" -d "Enables given technology or offline mode" -complete -f -c connmanctl -n "test (count (commandline -opc)) -eq 2; and contains -- (commandline -opc)[2] enable" -a "(__fish_print_connman_technologies) offline" +complete -f -c connmanctl -n "test (count (commandline -opc)) -eq 2; and contains -- (commandline -opc)[2] enable" -a "(__fish_print_connman_technologies) offline" complete -f -c connmanctl -n "test (count (commandline -opc)) -lt 2" -a "disable" -d "Disables given technology or offline mode" complete -f -c connmanctl -n "test (count (commandline -opc)) -eq 2; and contains -- (commandline -opc)[2] disable" -a "(__fish_print_connman_technologies) offline" complete -f -c connmanctl -n "test (count (commandline -opc)) -lt 2" -a "tether" -d "Enable, disable tethering, set SSID and passphrase for wifi" diff --git a/share/completions/cygport.fish b/share/completions/cygport.fish index 6a88454e1..77666c765 100644 --- a/share/completions/cygport.fish +++ b/share/completions/cygport.fish @@ -5,26 +5,26 @@ complete -c cygport -s 8 -l 64 -d "Build for 64-bit Cygwin" complete -c cygport -l debug -d "Enable debugging messages" # Cygport file -complete -c cygport -n '__fish_is_first_token' -A -f -a '*.cygport' -d "Cygport file" +complete -c cygport -n '__fish_is_first_token' -f -a '*.cygport' -d "Cygport file" # Commands -complete -c cygport -n 'not __fish_is_first_token' -A -f -a 'downloadall fetchall wgetall getall' -d "Download all sources" -complete -c cygport -n 'not __fish_is_first_token' -A -f -a 'download fetch wget get' -d "Download missing sources" -complete -c cygport -n 'not __fish_is_first_token' -A -f -a 'prep unpack' -d "Prepare source directory" -complete -c cygport -n 'not __fish_is_first_token' -A -f -a 'compile build make' -d "Build software" -complete -c cygport -n 'not __fish_is_first_token' -A -f -a 'check test' -d "Run test suite" -complete -c cygport -n 'not __fish_is_first_token' -A -f -a 'inst install' -d "Install into DESTDIR and run post-installation steps" -complete -c cygport -n 'not __fish_is_first_token' -A -f -a 'postinst' -d "Run post-installation steps" -complete -c cygport -n 'not __fish_is_first_token' -A -f -a 'list' -d "List package files" -complete -c cygport -n 'not __fish_is_first_token' -A -f -a 'listdebug listdbg' -d "List debug package files" -complete -c cygport -n 'not __fish_is_first_token' -A -f -a 'dep' -d "Show dependencies" -complete -c cygport -n 'not __fish_is_first_token' -A -f -a 'info' -d "Show packaging info" -complete -c cygport -n 'not __fish_is_first_token' -A -f -a 'homepage web www' -d "Show project homepage URL" -complete -c cygport -n 'not __fish_is_first_token' -A -f -a 'package pkg' -d "Create packages" -complete -c cygport -n 'not __fish_is_first_token' -A -f -a 'diff mkdiff mkpatch' -d "Create source patches" -complete -c cygport -n 'not __fish_is_first_token' -A -f -a 'upload up' -d "Upload finished packages" -complete -c cygport -n 'not __fish_is_first_token' -A -f -a 'announce' -d "Send announcement email" -complete -c cygport -n 'not __fish_is_first_token' -A -f -a 'clean finish' -d "Delete working directory" -complete -c cygport -n 'not __fish_is_first_token' -A -f -a 'almostall all' -d "Same as prep build inst pkg" -complete -c cygport -n 'not __fish_is_first_token' -A -f -a 'help' -d "Show help" -complete -c cygport -n 'not __fish_is_first_token' -A -f -a 'version' -d "Show version" +complete -c cygport -n 'not __fish_is_first_token' -f -a 'downloadall fetchall wgetall getall' -d "Download all sources" +complete -c cygport -n 'not __fish_is_first_token' -f -a 'download fetch wget get' -d "Download missing sources" +complete -c cygport -n 'not __fish_is_first_token' -f -a 'prep unpack' -d "Prepare source directory" +complete -c cygport -n 'not __fish_is_first_token' -f -a 'compile build make' -d "Build software" +complete -c cygport -n 'not __fish_is_first_token' -f -a 'check test' -d "Run test suite" +complete -c cygport -n 'not __fish_is_first_token' -f -a 'inst install' -d "Install into DESTDIR and run post-installation steps" +complete -c cygport -n 'not __fish_is_first_token' -f -a 'postinst' -d "Run post-installation steps" +complete -c cygport -n 'not __fish_is_first_token' -f -a 'list' -d "List package files" +complete -c cygport -n 'not __fish_is_first_token' -f -a 'listdebug listdbg' -d "List debug package files" +complete -c cygport -n 'not __fish_is_first_token' -f -a 'dep' -d "Show dependencies" +complete -c cygport -n 'not __fish_is_first_token' -f -a 'info' -d "Show packaging info" +complete -c cygport -n 'not __fish_is_first_token' -f -a 'homepage web www' -d "Show project homepage URL" +complete -c cygport -n 'not __fish_is_first_token' -f -a 'package pkg' -d "Create packages" +complete -c cygport -n 'not __fish_is_first_token' -f -a 'diff mkdiff mkpatch' -d "Create source patches" +complete -c cygport -n 'not __fish_is_first_token' -f -a 'upload up' -d "Upload finished packages" +complete -c cygport -n 'not __fish_is_first_token' -f -a 'announce' -d "Send announcement email" +complete -c cygport -n 'not __fish_is_first_token' -f -a 'clean finish' -d "Delete working directory" +complete -c cygport -n 'not __fish_is_first_token' -f -a 'almostall all' -d "Same as prep build inst pkg" +complete -c cygport -n 'not __fish_is_first_token' -f -a 'help' -d "Show help" +complete -c cygport -n 'not __fish_is_first_token' -f -a 'version' -d "Show version" diff --git a/share/completions/date.fish b/share/completions/date.fish index b7725f199..c361c661c 100644 --- a/share/completions/date.fish +++ b/share/completions/date.fish @@ -19,4 +19,4 @@ else # OS X complete -c date -s u -d 'Display or set the date int UTC time' complete -c date -s v -d 'Adjust the time component backward(-)/forward(+) according to VAL' -x end - + diff --git a/share/completions/dconf.fish b/share/completions/dconf.fish new file mode 100644 index 000000000..b24866d4e --- /dev/null +++ b/share/completions/dconf.fish @@ -0,0 +1,44 @@ +# Fish completions for gnome's "dconf" configuration tool + +function __fish_dconf_keys + set -l dir + set -l key + # We parse the `dump` output instead of `list` + # because it allows us to complete non-incrementally + # i.e. to get the keys directly, without going through + # `dconf list /`, `dconf list /org/` and so on. + dconf dump / ^/dev/null | while read -l line + if string match -q "[*]" -- $line + # New directory - just save it for the keys + set dir /(string trim -c "[]" -- $line) + else if test -n "$line" + # New key - output with the dir prepended. + echo $dir/(string replace -r '=.*' '' -- $line) + end + end +end + +### Commands +set -l commands read list write reset compile update watch dump load help + +complete -f -e -c dconf +complete -f -c dconf -n "not __fish_seen_subcommand_from $commands" -a 'read' -d 'Read the value of a key' +complete -f -c dconf -n "not __fish_seen_subcommand_from $commands" -a 'list' -d 'List the sub-keys and sub-directories of a directory' +complete -f -c dconf -n "not __fish_seen_subcommand_from $commands" -a 'write' -d 'Write a new value to a key' +complete -f -c dconf -n "not __fish_seen_subcommand_from $commands" -a 'reset' -d 'Delete a key or an entire directory' +complete -f -c dconf -n "not __fish_seen_subcommand_from $commands" -a 'compile' -d 'Compile a binary database from keyfiles' +complete -f -c dconf -n "not __fish_seen_subcommand_from $commands" -a 'update' -d 'Update the system dconf databases' +complete -f -c dconf -n "not __fish_seen_subcommand_from $commands" -a 'watch' -d 'Watch a key or directory for changes' +complete -f -c dconf -n "not __fish_seen_subcommand_from $commands" -a 'dump' -d 'Dump an entire subpath to stdout' +complete -f -c dconf -n "not __fish_seen_subcommand_from $commands" -a 'load' -d 'Populate a subpath from stdin' +complete -f -c dconf -n "not __fish_seen_subcommand_from $commands" -a 'help' -d 'Display help and exit' + + +### Arguments to commands +# Technically, reset/watch take a "PATH" (which is a dir or a key) +# while read and write take a KEY, but for now this is close enough. +complete -f -c dconf -n "__fish_seen_subcommand_from read write reset watch" -a "(__fish_dconf_keys)" +# List/dump/load take a dir, which is something that ends in a "/" +complete -f -c dconf -n "__fish_seen_subcommand_from list dump load" -a "(__fish_dconf_keys | string replace -r '/[^/]*\$' '/')" + +complete -f -c dconf -n "__fish_seen_subcommand_from help" -a "$commands" diff --git a/share/completions/dpkg-reconfigure.fish b/share/completions/dpkg-reconfigure.fish index 144fe734f..bd7624d57 100644 --- a/share/completions/dpkg-reconfigure.fish +++ b/share/completions/dpkg-reconfigure.fish @@ -8,7 +8,7 @@ complete -x -f -c dpkg-reconfigure -s h -l help --description 'Display help' # General options complete -f -c dpkg-reconfigure -s f -l frontend -r -a "dialog readline noninteractive gnome kde editor web" --description 'Set configuration frontend' complete -f -c dpkg-reconfigure -s p -l priority -r -a "low medium high critical" --description 'Set priority threshold' -complete -f -c dpkg-reconfigure -l default-priority --description 'Use default priority threshold' +complete -f -c dpkg-reconfigure -l default-priority --description "Use current default ("(echo get debconf/priority | debconf-communicate | string match -r '\w+$')") priority threshold" complete -f -c dpkg-reconfigure -s u -l unseen-only --description 'Show only unseen question' complete -f -c dpkg-reconfigure -l force --description 'Reconfigure also inconsistent packages' complete -f -c dpkg-reconfigure -l no-reload --description 'Prevent reloading templates' diff --git a/share/completions/dropbox.fish b/share/completions/dropbox.fish index 02dfb90ad..ecb0bcc50 100644 --- a/share/completions/dropbox.fish +++ b/share/completions/dropbox.fish @@ -28,9 +28,9 @@ complete -c dropbox -n "__fish_seen_subcommand_from help" -xa "$subcommands" complete -c dropbox -n "__fish_seen_subcommand_from start" -s i -l install -d "Auto install dropboxd if not available on the system" complete -c dropbox -n "__fish_seen_subcommand_from filestatus stat" -s l -l list -d "Prints out information in a format similar to ls. works best when your console supports color :)" complete -c dropbox -n "__fish_seen_subcommand_from filestatus stat ls" -s a -l all -d "Do not ignore entries starting with ." -complete -c dropbox -n "__fish_seen_subcommand_from autostart lansync" -xa '(echo -e "y\tEnable\nn\tDisable")' +complete -c dropbox -n "__fish_seen_subcommand_from autostart lansync" -xa '(echo -e "y\tEnable\nn\tDisable")' -set -l needs_excl_arg "__fish_seen_subcommand_from exclude; and not __fish_seen_subcommand_from list add remove" +set -l needs_excl_arg "__fish_seen_subcommand_from exclude; and not __fish_seen_subcommand_from list add remove" complete -c dropbox -n $needs_excl_arg -xa list -d "Prints a list of directories currently excluded from syncing" complete -c dropbox -n $needs_excl_arg -xa add -d "Adds one or more directories to the exclusion list" complete -c dropbox -n $needs_excl_arg -xa remove -d "Removes one or more directories from the exclusion list" diff --git a/share/completions/echo.fish b/share/completions/echo.fish index 28ffa03e3..bfb962fd3 100644 --- a/share/completions/echo.fish +++ b/share/completions/echo.fish @@ -3,4 +3,3 @@ complete -c echo -s s --description "Do not separate arguments with spaces" complete -c echo -s E --description "Disable backslash escapes" complete -c echo -s e --description "Enable backslash escapes" complete -c echo -s h -l help --description "Display help and exit" -complete -c echo -u diff --git a/share/completions/emerge.fish b/share/completions/emerge.fish index e234be15f..589e41359 100644 --- a/share/completions/emerge.fish +++ b/share/completions/emerge.fish @@ -4,7 +4,7 @@ function __fish_emerge_print_installed_pkgs --description 'Prints completions for installed packages on the system from /var/db/pkg' if test -d /var/db/pkg - find /var/db/pkg/ -type d | cut -d'/' -f5-6 | sort | uniq | \ + find /var/db/pkg/ -type d | cut -d'/' -f5-6 | sort -u | \ sed 's/-[0-9]\{1,\}\..*$//' | sed -e '/^ *$/d' return end @@ -13,7 +13,7 @@ end function __fish_emerge_print_all_pkgs --description 'Prints completions for all available packages on the system from /usr/portage' if test -d /usr/portage find /usr/portage/ -maxdepth 2 -type d | cut -d'/' -f4-5 | \ - sed 's/^\(distfiles\|profiles\|eclass\).*$//' | sort | uniq | \ + sed 's/^\(distfiles\|profiles\|eclass\).*$//' | sort -u | \ sed 's/-[0-9]\{1,\}\..*$//' | sed -e '/^ *$/d' return end diff --git a/share/completions/env.fish b/share/completions/env.fish index c6359da0a..e00601717 100644 --- a/share/completions/env.fish +++ b/share/completions/env.fish @@ -7,6 +7,3 @@ complete -c env -s i -l ignore-environment --description "Start with an empty en complete -c env -s u -l unset --description "Remove variable from the environment" -x -a "(set -n)" complete -c env -l help --description "Display help and exit" complete -c env -l version --description "Display version and exit" - -# Since env runs subcommands, it can accept any switches -complete -c env -u diff --git a/share/completions/equery.fish b/share/completions/equery.fish index 01d9cc157..3ff8ca620 100644 --- a/share/completions/equery.fish +++ b/share/completions/equery.fish @@ -4,21 +4,21 @@ function __fish_equery_print_installed_pkgs --description 'Prints completions for installed packages on the system from /var/db/pkg' if test -d /var/db/pkg - find /var/db/pkg/ -type d | cut -d'/' -f5-6 | sort | uniq | sed 's/-[0-9]\{1,\}\..*$//' + find /var/db/pkg/ -type d | cut -d'/' -f5-6 | sort -u | sed 's/-[0-9]\{1,\}\..*$//' return end end function __fish_equery_print_all_pkgs --description 'Prints completions for all available packages on the system from /usr/portage' if test -d /usr/portage - find /usr/portage/ -maxdepth 2 -type d | cut -d'/' -f4-5 | sed 's/^\(distfiles\|profiles\|eclass\).*$//' | sort | uniq | sed 's/-[0-9]\{1,\}\..*$//' + find /usr/portage/ -maxdepth 2 -type d | cut -d'/' -f4-5 | sed 's/^\(distfiles\|profiles\|eclass\).*$//' | sort -u | sed 's/-[0-9]\{1,\}\..*$//' return end end function __fish_equery_print_all_categories --description 'Prints completions for all available categories on the system from /usr/portage' if test -d /usr/portage - find /usr/portage/ -maxdepth 1 -type d | cut -d'/' -f4 | sed 's/^\(distfiles\|profiles\|eclass\).*$//' | sort | uniq | sed 's/-[0-9]\{1,\}\..*$//' + find /usr/portage/ -maxdepth 1 -type d | cut -d'/' -f4 | sed 's/^\(distfiles\|profiles\|eclass\).*$//' | sort -u | sed 's/-[0-9]\{1,\}\..*$//' return end end diff --git a/share/completions/feh.fish b/share/completions/feh.fish new file mode 100644 index 000000000..362f32275 --- /dev/null +++ b/share/completions/feh.fish @@ -0,0 +1,89 @@ +complete -c feh -l action -s A -x -d "Specify a shell command as action to perform on the image" + +for i in (seq 1 9) + complete -c feh -l action$i -x -d "Extra action triggered with number key "$i +end + +complete -c feh -l auto-zoom -s Z -d "Zoom pictures to screen size" +complete -c feh -l borderless -s x -d "Create borderless window" +complete -c feh -l cache-thumbnails -s P -d "Enable thumbnail caching" +complete -c feh -l caption-path -s K -r -d "Path to directory containing image caption" +complete -c feh -l customlist -s L -x -d "Print image info according to given format" +complete -c feh -l cycle-once -d "Exit feh after one loop through the slideshow" +complete -c feh -l draw-actions -s G -d "Draw the defined actions" +complete -c feh -l draw-exif -d "Display some EXIF information" +complete -c feh -l draw-filename -s d -d "Draw filename" +complete -c feh -l draw-tinted -d "Show overlay texts on semi-transparent background" +complete -c feh -l filelist -s f -r +complete -c feh -l font -s e -x -r -d "Set global font" +complete -c feh -l fontpath -s C -r -d "Add given path as directory to search fonts" +complete -c feh -l force-aliasing -d "Disable antialiasing for zooming, bg settings, etc." +complete -c feh -l fullindex -s I +complete -c feh -l fullscreen -s F -d "Make window fullscreen" +complete -c feh -l geometry -s g -x -d "Limit window size. Format: [w x h] [+ x + y]" +complete -c feh -l hide-pointer -s Y -d "Hide pointer" +complete -c feh -l image-bg -s B -x -a "checks white black" -d "Use style as background for transparent image parts" +complete -c feh -l index -s i -d "Enable index mode" +complete -c feh -l index-info -x -d "Show image information based on given format" +complete -c feh -l info -x -d "Execute given command line and display its output" +complete -c feh -l keep-http -s k -d "Keep files fetched using HTTP" +complete -c feh -l insecure -d "Disable strict hostname and peer checking with HTTPS" +complete -c feh -l keep-zoom-vp -d "When switching images, keep zoom and viewport settings" +complete -c feh -l list -s l -d "Don't display images. Display an ls style listing" +complete -c feh -l loadable -s U -d "Just print out image names if imlib2 can read them" +complete -c feh -l magick-timeout -x -d "Stop trying to convert unloadable files after given timeout" +complete -c feh -l max-dimension -x -d "Only show images which are smaller then given size" +complete -c feh -l menu-font -s M -x -d "Use given font as menu font" +complete -c feh -l min-dimension -x -d "Only show image which are larger then given size" +complete -c feh -l montage -s m -d "Enable montage mode" +complete -c feh -l multiwindow -s w -d "Disable slideshow mode" +complete -c feh -l no-jump-on-resort -d "Don't jump to first image after resorting filelist" +complete -c feh -l no-menus -s N -d "Don't load or show any menus" +complete -c feh -l no-screen-clip -d "Don't limit window to screen size" +complete -c feh -l no-xinerama -d "Disable Xinerama support" +complete -c feh -l output-dir -s j -r -d "Save files to given directory" +complete -c feh -l preload -s p -d "Preload images" +complete -c feh -l quiet -s q -d "Don't report non-fatal errors" +complete -c feh -l randomize -s z -d "Randomize file list before displaying" +complete -c feh -l recursive -s r -d "Recursivly expand any directory" +complete -c feh -l no-recursive -d "Don't recursively expand any directory (default)" +complete -c feh -l reload -s R -x -d "Reload filelist after given time in second" +complete -c feh -l reverse -s n -d "Reverse sort order" +complete -c feh -l scale-down -s '.' -d "Scale image to fit window geometry" +complete -c feh -l scroll-step -x -d "Scroll given number of pixels when scrolling keys are pressed" +complete -c feh -l slideshow-delay -s D -x -d "Set delay in second between automatically changing slides" +complete -c feh -l sort -s S -x -a "name\tSort\ by\ name filename\tSort\ by\ filename dirname\tSort\ by\ directory\ name mtime\tSort\ by\ most\ recently\ modified width\tSort\ by\ width height\tSort\ by\ height pixels\tSort\ by\ number\ of\ pixels size\tSort\ by\ size format\tSort\ by\ format" -d "Sort file list with given parameter" +complete -c feh -l start-at -s l -x -d "Start the filelist at given filename" +complete -c feh -l theme -s T -x -d "Load options from given config file" +complete -c feh -l thumbnails -s t +complete -c feh -l thumb-title -s '~' -x -d "Set given title for window opended from thumbnail mode" +complete -c feh -l title -s '^' -x -d "Set window title" +complete -c feh -l unloadable -s u -d "Just print names of images that can't be loaded by imlib2" +complete -c feh -l verbose -s V -d "Verbose mode" +complete -c feh -l version -s v -d "Print version and exit" +complete -c feh -l xinerama-index -x +complete -c feh -l zoom -x -a "max fill" -d "Zoom images by given percent when in fullscreen" + +# Montage Mode Options +complete -c feh -l alpha -s a -x -d "Set thumbnails' transparency to given level (0-255)" +complete -c feh -l bg -s b -r -a "trans" -d "Use given file as background for your montage" +complete -c feh -l ignore-aspect -s X -d "Don't retain thumbnails' aspect ratios" +complete -c feh -l limit-height -s W -x -d "Limit montage's height" +complete -c feh -l limit-width -s W -x -d "Limit montage's width" +complete -c feh -l output -s o -r -d "Save created montage to given file" +complete -c feh -l output-only -s O -r -d "Just save the created montage to given file" +complete -c feh -l stretch -s s -d "If image smaller then given thumbnail size, it will be enlarged" +complete -c feh -l thumb-height -s E -x -d "Set thumbnail height" +complete -c feh -l thumb-width -s y -x -d "Set thumbnail width" +complete -c feh -l thumb-redraw -s J -x -d "Redraw thumbnail window every n images" + +# Index mode options +complete -c feh -l title-font -s '@' -x -d "Set font to print title on index" + +# Background setting +complete -c feh -l bg-center -d "Center file on background" +complete -c feh -l bg-fill -d "Fit file into background by zooming until image fits" +complete -c feh -l bg-max -d "Fit file into backround by zooming with black borders on one side" +complete -c feh -l bg-scale -d "Fit file into background without repeating it, cutting off stuff or using borders" +complete -c feh -l bg-tile -d "Tile image if too small for screen" +complete -c feh -l no-fehbg -d "Do not write a ~/.fehbg file" diff --git a/share/completions/figlet.fish b/share/completions/figlet.fish index ab71861f3..70870c7b0 100644 --- a/share/completions/figlet.fish +++ b/share/completions/figlet.fish @@ -26,7 +26,7 @@ complete -c figlet -s W -d "Makes FIGlet all FIGcharacters at full width" complete -c figlet -s o -d "Cause `overlapped`" complete -c figlet -s m -d "Specify layout mode between 1 and 63" complete -c figlet -s v -d "Print version and copyright" -complete -c figlet -s I -d "Print information given infocode" -x -a "0\tVersion\ and\ copyright 1\tVersion\ \(integer\) 2\tDefault\ font\ directory 3\tFont 4\tOutput\ width 5\tSupported\ font\ format" +complete -c figlet -s I -d "Print information given infocode" -x -a "0\tVersion\ and\ copyright 1\tVersion\ \(integer\) 2\tDefault\ font\ directory 3\tFont 4\tOutput\ width 5\tSupported\ font\ format" complete -c figlet -s L -d "Print left-to-right" complete -c figlet -s R -d "Print right-to-left" complete -c figlet -s X -d "Print with default text direction" diff --git a/share/completions/fish_indent.fish b/share/completions/fish_indent.fish index c9ae10922..fa17f081e 100644 --- a/share/completions/fish_indent.fish +++ b/share/completions/fish_indent.fish @@ -3,3 +3,7 @@ complete -c fish_indent -s v -l version --description 'Display version and exit' complete -c fish_indent -s i -l no-indent --description 'Do not indent output, only reformat into one job per line' complete -c fish_indent -l ansi --description 'Colorize the output using ANSI escape sequences' complete -c fish_indent -l html --description 'Output in HTML format' +complete -c fish_indent -s w -l write --description 'Write to file' +complete -c fish_indent -s d -l debug-level -x --description 'Enable debug at specified verbosity level' +complete -c fish_indent -s D -l debug-stack-frames -x --description 'Specify how many stack frames to display in debug messages' +complete -c fish_indent -l dump-parse-tree --description 'Dump information about parsed statements to stderr' diff --git a/share/completions/flatpak.fish b/share/completions/flatpak.fish new file mode 100644 index 000000000..5860c6bc3 --- /dev/null +++ b/share/completions/flatpak.fish @@ -0,0 +1,39 @@ +# Completions for flatpak, an "Application deployment framework for desktop apps" +# (http://flatpak.org) +set -l commands install update uninstall list info run override make-current enter document-{export,unexport,info,list} \ +remote-{add,modify,delete,list,ls} build build-{init,finish,export,bundle,import-bundle,sign,update-repo} + +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a install -d 'Install an application or runtime from a remote' +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a update -d 'Update an installed application or runtime' +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a uninstall -d 'Uninstall an installed application or runtime' +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a list -d 'List installed apps and/or runtimes' +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a info -d 'Show info for installed app or runtime' +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a run -d 'Run an application' +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a override -d 'Override permissions for an application' +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a make-current -d 'Specify default version to run' +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a enter -d 'Enter the namespace of a running application' +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a document-export -d 'Grant an application access to a specific file' +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a document-unexport -d 'Revoke access to a specific file' +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a document-info -d 'Show information about a specific file' +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a document-list -d 'List exported files' +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a remote-add -d 'Add a new remote repository (by URL)' +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a remote-modify -d 'Modify properties of a configured remote' +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a remote-delete -d 'Delete a configured remote' +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a remote-list -d 'List all configured remotes' +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a remote-ls -d 'List contents of a configured remote' +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a build-init -d 'Initialize a directory for building' +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a build -d 'Run a build command inside the build dir' +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a build-finish -d 'Finish a build dir for export' +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a build-export -d 'Export a build dir to a repository' +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a build-bundle -d 'Create a bundle file from a build directory' +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a build-import-bundle -d 'Import a bundle file' +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a build-sign -d 'Sign an application or runtime' +complete -f -c flatpak -n "not __fish_seen_subcommand_from $commands" -a build-update-repo -d 'Update the summary file in a repository' + +complete -f -c flatpak -n "__fish_seen_subcommand_from run" -a "(flatpak list --app | string trim)" +complete -f -c flatpak -n "__fish_seen_subcommand_from info uninstall" -a "(flatpak list | string trim)" +complete -f -c flatpak -n "__fish_seen_subcommand_from remote-ls remote-modify remote-delete" -a "(flatpak remote-list | string trim)" + +# Note that "remote-ls" opens an internet connection, so we don't want to complete "install" +# Plenty of the other stuff is too free-form to complete (e.g. remote-add). +complete -f -c flatpak -s h -l help diff --git a/share/completions/fusermount.fish b/share/completions/fusermount.fish index 4d9d6a7d7..19246e9d5 100644 --- a/share/completions/fusermount.fish +++ b/share/completions/fusermount.fish @@ -3,13 +3,7 @@ # # Find mount points, borrowed from umount.fish # -complete -c fusermount --description "Mount point" -x -a ' -( - cat /etc/mtab | __fish_sgrep "^sshfs" | cut -d " " -f 1-2|tr " " \n|sed -e "s/[0-9\.]*:\//\//"| __fish_sgrep "^/" - cat /etc/mtab | __fish_sgrep "^fuseiso" | cut -d " " -f 1-2|tr " " \n|sed -e "s/[0-9\.]*:\//\//"| __fish_sgrep "^/" -) -' - +complete -c fusermount --description "Mount point" -x -a '(__fish_print_mounted)' complete -c fusermount -s h --description "Display help and exit" complete -c fusermount -s v --description "Display version and exit" complete -c fusermount -s o -x --description "Mount options" diff --git a/share/completions/git.fish b/share/completions/git.fish index d49ccfd64..f15996e35 100644 --- a/share/completions/git.fish +++ b/share/completions/git.fish @@ -430,10 +430,206 @@ complete -f -c git -n '__fish_git_needs_command' -a init -d 'Create an empty git # TODO options ### log +complete -c git -n '__fish_git_needs_command' -a shortlog -d 'Show commit shortlog' complete -c git -n '__fish_git_needs_command' -a log -d 'Show commit logs' complete -c git -n '__fish_git_using_command log' -a '(__fish_git_refs) (__fish_git_ranges)' -d 'Branch' -complete -c git -n '__fish_git_needs_command' -a shortlog -d 'Show commit shortlog' -# TODO options + +complete -c git -n '__fish_git_using_command log' -l follow -d 'Continue listing file history beyond renames' +complete -c git -n '__fish_git_using_command log' -l no-decorate -d 'Don\'t print ref names' +complete -f -c git -n '__fish_git_using_command log' -l decorate -a 'short\tHide\ prefixes full\tShow\ full\ ref\ names auto\tHide\ prefixes\ if\ printed\ to\ terminal no\tDon\\\'t\ display\ ref' -d 'Print out ref names' +complete -c git -n '__fish_git_using_command log' -l source -d 'Print ref name by which each commit was reached' +complete -c git -n '__fish_git_using_command log' -l use-mailmap +complete -c git -n '__fish_git_using_command log' -l full-diff +complete -c git -n '__fish_git_using_command log' -l log-size +complete -x -c git -n '__fish_git_using_command log' -s L +complete -x -c git -n '__fish_git_using_command log' -s n -l max-count -d 'Limit the number of commits before starting to show the commit output' +complete -x -c git -n '__fish_git_using_command log' -l skip -d 'Skip given number of commits' +complete -x -c git -n '__fish_git_using_command log' -l since -d 'Show commits more recent than specified date' +complete -x -c git -n '__fish_git_using_command log' -l after -d 'Show commits more recent than specified date' +complete -x -c git -n '__fish_git_using_command log' -l until -d 'Show commits older than specified date' +complete -x -c git -n '__fish_git_using_command log' -l before -d 'Show commits older than specified date' +complete -x -c git -n '__fish_git_using_command log' -l author -d 'Limit commits from given author' +complete -x -c git -n '__fish_git_using_command log' -l committer -d 'Limit commits from given committer' +complete -x -c git -n '__fish_git_using_command log' -l grep-reflog -d 'Limit commits to ones with reflog entries matching given pattern' +complete -x -c git -n '__fish_git_using_command log' -l grep -d 'Limit commits with message that match given pattern' +complete -c git -n '__fish_git_using_command log' -l all-match -d 'Limit commits to ones that match all given --grep' +complete -c git -n '__fish_git_using_command log' -l invert-grep -d 'Limit commits to ones with message that don\'t match --grep' +complete -c git -n '__fish_git_using_command log' -l regexp-ignore-case -s i -d 'Case insensitive match' +complete -c git -n '__fish_git_using_command log' -l basic-regexp -d 'Patterns are basic regular expressions (default)' +complete -c git -n '__fish_git_using_command log' -l extended-regexp -s E -d 'Patterns are extended regular expressions' +complete -c git -n '__fish_git_using_command log' -l fixed-strings -s F -d 'Patterns are fixed strings' +complete -c git -n '__fish_git_using_command log' -l perl-regexp -d 'Patterns are Perl-compatible regular expressions' +complete -c git -n '__fish_git_using_command log' -l remove-empty -d 'Stop when given path disappears from tree' +complete -c git -n '__fish_git_using_command log' -l merges -d 'Print only merge commits' +complete -c git -n '__fish_git_using_command log' -l no-merges -d 'Don\'t print commits with more than one parent' +complete -x -c git -n '__fish_git_using_command log' -l min-parents -d 'Show only commit with at least the given number of parents' +complete -x -c git -n '__fish_git_using_command log' -l max-parents -d 'Show only commit with at most the given number of parents' +complete -c git -n '__fish_git_using_command log' -l no-min-parents -d 'Show only commit without a mimimum number of parents' +complete -c git -n '__fish_git_using_command log' -l no-max-parents -d 'Show only commit without a maximum number of parents' +complete -c git -n '__fish_git_using_command log' -l first-parent -d 'Follow only the first parent commit upon seeing a merge commit' +complete -c git -n '__fish_git_using_command log' -l not -d 'Reverse meaning of ^ prefix' +complete -c git -n '__fish_git_using_command log' -l all -d 'Pretend as if all refs in refs/ are listed on the command line as ' +complete -f -c git -n '__fish_git_using_command log' -l branches -d 'Pretend as if all refs are in refs/heads are listed on the command line as ' +complete -f -c git -n '__fish_git_using_command log' -l tags -d 'Pretend as if all refs are in ref/tags are listed on the command line as ' +complete -f -c git -n '__fish_git_using_command log' -l remotes -d 'Pretend as if all refs in refs/remotes are listed on the command line as ' +complete -x -c git -n '__fish_git_using_command log' -l glob -d 'Pretend as if all refs matching shell glob are listed on the command line as ' +complete -x -c git -n '__fish_git_using_command log' -l exclude -d 'Do not include refs matching given glob pattern' +complete -c git -n '__fish_git_using_command log' -l reflog -d 'Pretend as if all objcets mentioned by reflogs are listed on the command line as ' +complete -c git -n '__fish_git_using_command log' -l ingnore-missing -d 'Ignore invalid object names' +complete -c git -n '__fish_git_using_command log' -l bisect +complete -c git -n '__fish_git_using_command log' -l stdin -d 'Read commits from stdin' +complete -c git -n '__fish_git_using_command log' -l cherry-mark -d 'Mark equivalent commits with = and inequivalent with +' +complete -c git -n '__fish_git_using_command log' -l cherry-pick -d 'Omit equivalent commits' +complete -c git -n '__fish_git_using_command log' -l left-only +complete -c git -n '__fish_git_using_command log' -l rigth-only +complete -c git -n '__fish_git_using_command log' -l cherry +complete -c git -n '__fish_git_using_command log' -l walk-reflogs -s g +complete -c git -n '__fish_git_using_command log' -l merge +complete -c git -n '__fish_git_using_command log' -l boundary +complete -c git -n '__fish_git_using_command log' -l simplify-by-decoration +complete -c git -n '__fish_git_using_command log' -l full-history +complete -c git -n '__fish_git_using_command log' -l dense +complete -c git -n '__fish_git_using_command log' -l sparse +complete -c git -n '__fish_git_using_command log' -l simplify-merges +complete -c git -n '__fish_git_using_command log' -l ancestry-path +complete -c git -n '__fish_git_using_command log' -l date-order +complete -c git -n '__fish_git_using_command log' -l author-date-order +complete -c git -n '__fish_git_using_command log' -l topo-order +complete -c git -n '__fish_git_using_command log' -l reverse +complete -f -c git -n '__fish_git_using_command log' -l no-walk -a "sorted unsorted" +complete -c git -n '__fish_git_using_command log' -l do-walk +complete -c git -n '__fish_git_using_command log' -l format +complete -c git -n '__fish_git_using_command log' -l abbrev-commit +complete -c git -n '__fish_git_using_command log' -l no-abbrev-commit +complete -c git -n '__fish_git_using_command log' -l oneline +complete -x -c git -n '__fish_git_using_command log' -l encoding -a '(__fish_print_encodings)' +complete -f -c git -n '__fish_git_using_command log' -l expand-tabs +complete -c git -n '__fish_git_using_command log' -l no-expand-tabs +complete -f -c git -n '__fish_git_using_command log' -l notes +complete -c git -n '__fish_git_using_command log' -l no-notes +complete -f -c git -n '__fish_git_using_command log' -l show-notes +complete -c git -n '__fish_git_using_command log' -l standard-notes +complete -c git -n '__fish_git_using_command log' -l no-standard-notes +complete -c git -n '__fish_git_using_command log' -l show-signature +complete -c git -n '__fish_git_using_command log' -l relative-date +complete -x -c git -n '__fish_git_using_command log' -l date -a ' + relative + local + iso + iso-local + iso8601 + iso8601-local + iso-strict + iso-strict-local + iso8601-strict + iso8601-strict-local + rfc-local + rfc2822-local + short + short-local + raw + unix + format: + default + default-local +' +complete -c git -n '__fish_git_using_command log' -l parents +complete -c git -n '__fish_git_using_command log' -l children +complete -c git -n '__fish_git_using_command log' -l left-right +complete -c git -n '__fish_git_using_command log' -l graph +complete -f -c git -n '__fish_git_using_command log' -l show-linear-break +complete -c git -n '__fish_git_using_command log' -s c +complete -c git -n '__fish_git_using_command log' -l cc +complete -c git -n '__fish_git_using_command log' -s m +complete -c git -n '__fish_git_using_command log' -s r +complete -c git -n '__fish_git_using_command log' -s t +complete -c git -n '__fish_git_using_command log' -l patch -s p +complete -c git -n '__fish_git_using_command log' -s u +complete -c git -n '__fish_git_using_command log' -l no-patch -s s +complete -x -c git -n '__fish_git_using_command log' -l unified -s U +complete -c git -n '__fish_git_using_command log' -l raw +complete -c git -n '__fish_git_using_command log' -l patch-with-raw +complete -c git -n '__fish_git_using_command log' -l indent-heuristic +complete -c git -n '__fish_git_using_command log' -l no-indent-heuristic +complete -c git -n '__fish_git_using_command log' -l compaction-heuristic +complete -c git -n '__fish_git_using_command log' -l no-compaction-heuristic +complete -c git -n '__fish_git_using_command log' -l minimal +complete -c git -n '__fish_git_using_command log' -l patience +complete -c git -n '__fish_git_using_command log' -l histogram +complete -x -c git -n '__fish_git_using_command log' -l diff-algorithm -a ' + default\tBasic\ greedy\ diff\ algorithm + myers\tBasic\ greedy\ diff\ algorithm + minimal\tMake\ smallest\ diff\ possible + patience\tPatience\ diff\ algorithm + histogram\tPatience\ algorithm\ with\ low-occurrence\ common\ elements +' +complete -f -x -c git -n '__fish_git_using_command log' -l stat +complete -c git -n '__fish_git_using_command log' -l numstat +complete -c git -n '__fish_git_using_command log' -l shortstat +complete -f -c git -n '__fish_git_using_command log' -l dirstat -a '(__fish_append , changes lines files cumulative)' +complete -c git -n '__fish_git_using_command log' -l summary +complete -c git -n '__fish_git_using_command log' -l patch-with-stat +complete -c git -n '__fish_git_using_command log' -s z +complete -c git -n '__fish_git_using_command log' -l name-only +complete -c git -n '__fish_git_using_command log' -l name-status +complete -f -c git -n '__fish_git_using_command log' -l submodule -a 'short diff log' +complete -f -c git -n '__fish_git_using_command log' -l color -a 'always never auto' +complete -c git -n '__fish_git_using_command log' -l no-color +complete -f -c git -n '__fish_git_using_command log' -l word-diff -a ' + color + plain + porcelain + none +' +complete -f -c git -n '__fish_git_using_command log' -l color-words +complete -c git -n '__fish_git_using_command log' -l no-renames +complete -c git -n '__fish_git_using_command log' -l check +complete -f -c git -n '__fish_git_using_command log' -l ws-error-highlight -a '(__fish_append , old new context)' +complete -c git -n '__fish_git_using_command log' -l full-index +complete -c git -n '__fish_git_using_command log' -l binary +complete -f -c git -n '__fish_git_using_command log' -l abbrev +complete -f -c git -n '__fish_git_using_command log' -l break-rewrittes -s B +complete -f -c git -n '__fish_git_using_command log' -l find-renames -s M +complete -f -c git -n '__fish_git_using_command log' -l find-copies -s C +complete -c git -n '__fish_git_using_command log' -l find-copies-harder +complete -c git -n '__fish_git_using_command log' -l irreversible-delete -s D +complete -f -c git -n '__fish_git_using_command log' -s l + +function __fish__git_append_letters_nosep + set -l token (commandline -tc) + printf "%s\n" $token$argv +end + +complete -x -c git -n '__fish_git_using_command log' -l diff-filter -a '(__fish__git_append_letters_nosep a\tExclude\ added c\tExclude\ copied d\tExclude\ deleted m\tExclude\ modified r\tExclude\ renamed t\tExclude\ type\ changed u\tExclude\ unmerged x\tExclude\ unknown b\tExclude\ broken A\tAdded C\tCopied D\tDeleted M\tModified R\tRenamed T\tType\ Changed U\tUnmerged X\tUnknown B\tBroken)' + +complete -x -c git -n '__fish_git_using_command log' -s S +complete -x -c git -n '__fish_git_using_command log' -s G +complete -c git -n '__fish_git_using_command log' -l pickaxe-all +complete -f -c git -n '__fish_git_using_command log' -s O +complete -c git -n '__fish_git_using_command log' -s R +complete -c git -n '__fish_git_using_command log' -l relative +complete -c git -n '__fish_git_using_command log' -l text -s a +complete -c git -n '__fish_git_using_command log' -l ignore-space-at-eol +complete -c git -n '__fish_git_using_command log' -l ignore-space-change -s b +complete -c git -n '__fish_git_using_command log' -l ignore-all-space -s w +complete -c git -n '__fish_git_using_command log' -l ignore-blank-lines +complete -x -c git -n '__fish_git_using_command log' -l inter-hunk-context +complete -c git -n '__fish_git_using_command log' -l function-context -s W +complete -c git -n '__fish_git_using_command log' -l ext-diff +complete -c git -n '__fish_git_using_command log' -l no-ext-diff +complete -c git -n '__fish_git_using_command log' -l textconv +complete -c git -n '__fish_git_using_command log' -l no-textconv +complete -f -c git -n '__fish_git_using_command log' -l ignore-submodules -a ' + none + untracked + dirty + all +' +complete -x -c git -n '__fish_git_using_command log' -l src-prefix +complete -x -c git -n '__fish_git_using_command log' -l dst-prefix +complete -c git -n '__fish_git_using_command log' -l no-prefix +complete -x -c git -n '__fish_git_using_command log' -l line-prefix +complete -c git -n '__fish_git_using_command log' -l ita-invisible-in-index ### merge complete -f -c git -n '__fish_git_needs_command' -a merge -d 'Join two or more development histories together' @@ -527,7 +723,7 @@ complete -f -c git -n '__fish_git_using_command push' -l tags -d 'Push all refs complete -f -c git -n '__fish_git_using_command push' -s n -l dry-run -d 'Do everything except actually send the updates' complete -f -c git -n '__fish_git_using_command push' -l porcelain -d 'Produce machine-readable output' complete -f -c git -n '__fish_git_using_command push' -s f -l force -d 'Force update of remote refs' -complete -f -c git -n '__fish_git_using_command push' -s u -l set-upstream-to -d 'Add upstream (tracking) reference' +complete -f -c git -n '__fish_git_using_command push' -s u -l set-upstream -d 'Add upstream (tracking) reference' complete -f -c git -n '__fish_git_using_command push' -s q -l quiet -d 'Be quiet' complete -f -c git -n '__fish_git_using_command push' -s v -l verbose -d 'Be verbose' complete -f -c git -n '__fish_git_using_command push' -l progress -d 'Force progress status' diff --git a/share/completions/go.fish b/share/completions/go.fish index 130c05550..7e6da7bdc 100644 --- a/share/completions/go.fish +++ b/share/completions/go.fish @@ -1,3 +1,6 @@ +# go is a tool for managing Go source code. +# See: https://golang.org + function __fish__go_buildflags_completions -d 'Complete go build commands' --argument-names cmd complete -c go -n "__fish_seen_subcommand_from $cmd" -s a -d 'force rebuild' complete -c go -n "__fish_seen_subcommand_from $cmd" -s n -d 'print the commands but do not run them' @@ -7,12 +10,12 @@ function __fish__go_buildflags_completions -d 'Complete go build commands' --arg complete -c go -n "__fish_seen_subcommand_from $cmd" -o work -d 'print and preserve work directory' complete -c go -n "__fish_seen_subcommand_from $cmd" -s x -d 'print the commands' complete -c go -n "__fish_seen_subcommand_from $cmd" -o ccflags -r -d 'c compiler flags' - complete -c go -n "__fish_seen_subcommand_from $cmd" -o compiler -r -d 'name of compiler to use, as in runtime.Compiler (gccgo or gc)' + complete -c go -n "__fish_seen_subcommand_from $cmd" -o compiler -x -d 'name of compiler to use, as in runtime' -a 'gccgo gc' complete -c go -n "__fish_seen_subcommand_from $cmd" -o gccgoflags -r -d 'gccgo compiler/linker flags' complete -c go -n "__fish_seen_subcommand_from $cmd" -o gcflags -r -d 'go compiler flags' complete -c go -n "__fish_seen_subcommand_from $cmd" -o installsuffix -r -d 'suffix for installation directory' complete -c go -n "__fish_seen_subcommand_from $cmd" -o ldflags -r -d 'linker flags' - complete -c go -n "__fish_seen_subcommand_from $cmd" -o tags -r -d 'build tags ' + complete -c go -n "__fish_seen_subcommand_from $cmd" -o tags -r -d 'build tags' end function __fish_complete_go_files -d 'Complete go' --argument-names cmd @@ -52,7 +55,7 @@ complete -c go -n '__fish_seen_subcommand_from fmt' -s x -d "prints commands as # get complete -c go -n '__fish_use_subcommand' -a get -d 'download and install packages and dependencies' -complete -c go -n '__fish_seen_subcommand_from get' -s d -d "stop after downloading the packages; don\'t install" +complete -c go -n '__fish_seen_subcommand_from get' -s d -d "stop after downloading the packages; don't install" complete -c go -n '__fish_seen_subcommand_from get' -o fix -d "run fix tool on packages before resolving dependencies or building" complete -c go -n '__fish_seen_subcommand_from get' -s u -d "update remote packages" __fish__go_buildflags_completions get @@ -80,7 +83,7 @@ __fish_complete_go_files run # test complete -c go -n '__fish_use_subcommand' -a test -d 'test packages' complete -c go -n '__fish_seen_subcommand_from test' -s c -r -d "compile the test binary to pkg.test but do not run it" -complete -c go -n '__fish_seen_subcommand_from test' -s i -d "install dependent packages, but don\'t run tests" +complete -c go -n '__fish_seen_subcommand_from test' -s i -d "install dependent packages, but don't run tests" __fish__go_buildflags_completions test __fish_complete_go_files test @@ -97,4 +100,3 @@ complete -c go -f -n '__fish_seen_subcommand_from version' complete -c go -n '__fish_use_subcommand' -a vet -d 'vet packages' complete -c go -n '__fish_seen_subcommand_from vet' -s n -d "print the command that would be executed" complete -c go -n '__fish_seen_subcommand_from vet' -s x -d "prints commands as they are executed" - diff --git a/share/completions/gpg.fish b/share/completions/gpg.fish index 9c236e654..dbccca0b1 100644 --- a/share/completions/gpg.fish +++ b/share/completions/gpg.fish @@ -48,8 +48,18 @@ function __fish_print_gpg_algo -d "Complete using all algorithms of the type spe # will take effect again. set -lx LC_ALL C - # XXX this misses certain ciphers in gpg --version - redo this entirely and use fish's annoying group printing as a feature finally! - gpg --version | __fish_sgrep "$argv:"| __fish_sgrep -v "Home:"|cut -d : -f 2 |tr , \n|tr -d " " + # sed script explained: + # in the line that matches "$argv:" + # define label 'loop' + # if the line ends with a ',' + # add next line to buffer + # transliterate '\n' with ' ' + # goto loop + # remove everything until the first ':' of the line + # remove all blanks + # transliterate ',' with '\n' (OSX apparently doesn't like '\n' on RHS of the s-command) + # print result + gpg --version | sed -ne "/$argv:/"'{:loop; /,$/{N; y!\n! !; b loop}; s!^[^:]*:!!; s![ ]*!!g; y!,!\n!; p}' end diff --git a/share/completions/grep.fish b/share/completions/grep.fish index 07172a91c..126c6a650 100644 --- a/share/completions/grep.fish +++ b/share/completions/grep.fish @@ -3,9 +3,9 @@ complete -c grep -s a -l text --description "Process binary file as text" complete -c grep -s B -l before-context --description "Print NUM lines of leading context" complete -c grep -s C -l context --description "Print NUM lines of context" complete -c grep -s b -l byte-offset --description "Print byte offset of matches" -complete -c grep -l binary-files --description "Assume data type for binary files" -x -a "binary text" -complete -c grep -l colour -x -a "never always auto" -complete -c grep -l color -x -a "never always auto" +complete -c grep -l binary-files --description "Assume data type for binary files" -x -a "binary\tBinary\ format text\tText\ format" +complete -c grep -l colour -x --description "Colour output" -a "never always auto" +complete -c grep -l color -x --description "Color output" -a "never always auto" complete -c grep -s c -l count --description "Only print number of matches" complete -c grep -s D -l devices -x -a "read skip" --description "Action for devices" complete -c grep -s d -l directories -x -a "read skip recurse" --description "Action for directories" @@ -44,6 +44,6 @@ complete -c grep -s V -l version --description "Display version and exit" complete -c grep -s v -l invert-match --description "Invert the sense of matching" complete -c grep -s w -l word-regexp --description "Only whole matching words" complete -c grep -s x -l line-regexp --description "Only whole matching lines" -complete -c grep -s y --description "Obsolete synonym for -i" -complete -c grep -s z -l null-data --description 'treat input as a set of lines each terminated by a zero byte' +complete -c grep -s y --description "Ignore case (deprecated: use -i instead)" +complete -c grep -s z -l null-data --description "Treat input as a set of zero-terminated lines" complete -c grep -s Z -l null --description "Output a zero byte after filename" diff --git a/share/completions/help.fish b/share/completions/help.fish index f0c1fa0a5..85a8f750c 100644 --- a/share/completions/help.fish +++ b/share/completions/help.fish @@ -1,9 +1,5 @@ -# -# Completions for the help command -# - if test -d "$__fish_datadir/man/man1/" - complete -c help -x -a '(__fish_print_commands)' --description "Help for this command" + complete -c help -x -a '(__fish_print_commands)' --description 'Help for this command' end complete -c help -x -a syntax --description 'Introduction to the fish syntax' @@ -11,22 +7,22 @@ complete -c help -x -a todo --description 'Incomplete aspects of fish' complete -c help -x -a bugs --description 'Known fish bugs' complete -c help -x -a history --description 'Help on how to reuse previously entered commands' -complete -c help -x -a completion --description "Help on how tab-completion works" -complete -c help -x -a job-control --description "Help on how job control works" -complete -c help -x -a difference --description "Summary on how fish differs from other shells" +complete -c help -x -a completion --description 'Help on how tab-completion works' +complete -c help -x -a job-control --description 'Help on how job control works' +complete -c help -x -a difference --description 'Summary on how fish differs from other shells' -complete -c help -x -a prompt --description "Help on how to set the prompt" -complete -c help -x -a title --description "Help on how to set the titlebar message" -complete -c help -x -a killring --description "Help on how to copy and paste" -complete -c help -x -a editor --description "Help on editor shortcuts" -complete -c help -x -a variables --description "Help on environment variables" -complete -c help -x -a color --description "Help on setting syntax highlighting colors" +complete -c help -x -a prompt --description 'Help on how to set the prompt' +complete -c help -x -a title --description 'Help on how to set the titlebar message' +complete -c help -x -a killring --description 'Help on how to copy and paste' +complete -c help -x -a editor --description 'Help on editor shortcuts' +complete -c help -x -a variables --description 'Help on environment variables' +complete -c help -x -a color --description 'Help on setting syntax highlighting colors' -complete -c help -x -a globbing --description "Help on parameter expansion (Globbing)" -complete -c help -x -a expand --description "Help on parameter expansion (Globbing)" -complete -c help -x -a expand-variable --description "Help on variable expansion \$VARNAME" -complete -c help -x -a expand-home --description "Help on home directory expansion ~USER" -complete -c help -x -a expand-brace --description "Help on brace expansion {a,b,c}" -complete -c help -x -a expand-wildcard --description "Help on wildcard expansion *.*" -complete -c help -x -a expand-command-substitution --description "Help on command substitution (SUBCOMMAND)" -complete -c help -x -a expand-process --description "Help on process expansion %JOB" +complete -c help -x -a globbing --description 'Help on parameter expansion (Globbing)' +complete -c help -x -a expand --description 'Help on parameter expansion (Globbing)' +complete -c help -x -a expand-variable --description 'Help on variable expansion $VARNAME' +complete -c help -x -a expand-home --description 'Help on home directory expansion ~USER' +complete -c help -x -a expand-brace --description 'Help on brace expansion {a,b,c}' +complete -c help -x -a expand-wildcard --description 'Help on wildcard expansion *.*' +complete -c help -x -a expand-command-substitution --description 'Help on command substitution (SUBCOMMAND)' +complete -c help -x -a expand-process --description 'Help on process expansion %JOB' diff --git a/share/completions/htop.fish b/share/completions/htop.fish index c4894a9de..b8cdace88 100644 --- a/share/completions/htop.fish +++ b/share/completions/htop.fish @@ -1,5 +1,11 @@ -# Completions for top -complete -c htop -s d --description "Update interval" -x -complete -c htop -s u --description "Monitor effective UID" -x -a "(__fish_complete_users)" -complete -c htop -l sort-key -d 'Sort column' -xa "(htop --sort-key '')" +# htop is an interactive process viewer. +# See: http://hisham.hm/htop +complete -c htop -l delay -s d -d 'Update interval' -x +complete -c htop -l no-color -s C -d 'Start htop in monochrome mode' +complete -c htop -l no-colour -d 'Start htop in monochrome mode' +complete -c htop -l help -s h -d 'Show help and exit' +complete -c htop -l pid -s p -d 'Show only given PIDs' -x -a '(__fish_append , (__fish_complete_pids))' +complete -c htop -l user -s u -d 'Monitor given user' -x -a '(__fish_complete_users)' +complete -c htop -l sort-key -d 'Sort column' -xa '(htop --sort-key help)' +complete -c htop -l version -s v -d 'Show version and exit' diff --git a/share/completions/i3-msg.fish b/share/completions/i3-msg.fish new file mode 100644 index 000000000..d635392a9 --- /dev/null +++ b/share/completions/i3-msg.fish @@ -0,0 +1,16 @@ +# i3-msg is a tool to send messages to the i3 window manager. +# See: https://i3wm.org + +complete -c i3-msg -l quiet -s q -d 'Only send ipc message and suppress output' +complete -c i3-msg -l version -s v -d 'Display version number and exit' +complete -c i3-msg -l help -s h -d 'Display help and exit' +complete -c i3-msg -l socket -s s -d 'Set socket' +complete -c i3-msg -s t -x -d 'Specify ipc message type' -a ' + command\t"Payload is a command" + get_workspaces\t"Get current workspace" + get_outputs\t"Get current outputs" + get_tree\t"Get layout tree" + get_marks\t"Get list of marks" + get_bar_config\t"Get list of configured binding modes" + get_version\t"Get i3 version" +' diff --git a/share/completions/ip.fish b/share/completions/ip.fish index b7ded602e..de4599912 100644 --- a/share/completions/ip.fish +++ b/share/completions/ip.fish @@ -320,7 +320,7 @@ function __fish_complete_ip end end end - + complete -f -c ip complete -f -c ip -a '(__fish_complete_ip)' complete -f -c ip -n "not __fish_seen_subcommand_from $ip_all_commands" -a "$ip_commands" diff --git a/share/completions/journalctl.fish b/share/completions/journalctl.fish index 8bbd0136d..f582f4e54 100644 --- a/share/completions/journalctl.fish +++ b/share/completions/journalctl.fish @@ -25,7 +25,7 @@ end complete -c journalctl -n "not __fish_journalctl_is_field" -a '(__fish_journalctl_fields)' -d "Journal field" -f complete -c journalctl -n "not __fish_journalctl_is_field" -a '(command journalctl -F _EXE ^/dev/null)' -d "Executable" complete -c journalctl -n "not __fish_journalctl_is_field" -a '+' -d "OR" -complete -c journalctl -n "__fish_journalctl_is_field" -a '(__fish_journalctl_field_values)' -f -r -A +complete -c journalctl -n "__fish_journalctl_is_field" -a '(__fish_journalctl_field_values)' -f -r complete -c journalctl -f -s h -l help -d 'Prints a short help text and exits' complete -c journalctl -f -l version -d 'Prints a short version string and exits' diff --git a/share/completions/killall.fish b/share/completions/killall.fish index 154a63eed..6f9d4e4d1 100644 --- a/share/completions/killall.fish +++ b/share/completions/killall.fish @@ -42,9 +42,9 @@ if test (uname) != 'SunOS' complete -c killall -s s -d 'Simulate, but do not send any signals' complete -c killall -s d -d 'Print detailed info. Doesn\'t send signals' complete -c killall -s u -x -d 'Only processes for USER' - # Completions for users + # Completions for users __make_users_completions - complete -c killall -s t -d 'Limit to processes running on specified TTY' + complete -c killall -s t -d 'Limit to processes running on specified TTY' complete -c killall -s t -xa "(ps a -o tty | sed 1d | uniq)" complete -c killall -s c -x -d 'Limit to processes matching specified PROCNAME' complete -c killall -s z -d 'Do not skip zombies' diff --git a/share/completions/launchctl.fish b/share/completions/launchctl.fish new file mode 100644 index 000000000..5636e0d38 --- /dev/null +++ b/share/completions/launchctl.fish @@ -0,0 +1,45 @@ +complete --command launchctl -n '__fish_use_subcommand' -xa 'bootstrap\t"'(_ "Bootstraps a domain or a service into a domain")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'bootout\t"'(_ "Tears down a domain or removes a service from a domain")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'enable\t"'(_ "Enables an existing service")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'disable\t"'(_ "Disables an existing service")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'uncache\t"'(_ "Removes the specified service name from the service cache")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'kickstart\t"'(_ "Forces an existing service to start")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'attach\t"'(_ "Attach the system's debugger to a service")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'debug\t"'(_ "Configures the next invocation of a service for debugging")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'kill\t"'(_ "Sends a signal to the service instance")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'blame\t"'(_ "Prints the reason a service is running")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'print\t"'(_ "Prints a description of a domain or service")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'print-cache\t"'(_ "Prints information about the service cache")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'print-disabled\t"'(_ "Prints which services are disabled")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'plist\t"'(_ "Prints a property list embedded in a binary (targets the Info.plist by default)")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'procinfo\t"'(_ "Prints port information about a process")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'hostinfo\t"'(_ "Prints port information about the host")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'resolveport\t"'(_ "Resolves a port name from a process to an endpoint in launchd")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'limit\t"'(_ "Reads or modifies launchd's resource limits")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'runstats\t"'(_ "Prints performance statistics for a service")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'examine\t"'(_ "Runs the specified analysis tool against launchd in a non-reentrant manner")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'config\t"'(_ "Modifies persistent configuration parameters for launchd domains")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'dumpstate\t"'(_ "Dumps launchd state to stdout")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'dumpjpcategory\t"'(_ "Dumps the jetsam properties category for all services")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'reboot\t"'(_ "Initiates a system reboot of the specified type")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'bootshell\t"'(_ "Brings the system up from single-user mode with a console shell")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'load\t"'(_ "Bootstraps a service or directory of services")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'unload\t"'(_ "Unloads a service or directory of services")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'remove\t"'(_ "Unloads the specified service name")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'list\t"'(_ "Lists information about services")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'start\t"'(_ "Starts the specified service")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'stop\t"'(_ "Stops the specified service if it is running")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'setenv\t"'(_ "Sets the specified environment variables for all services within the domain")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'unsetenv\t"'(_ "Unsets the specified environment variables for all services within the domain")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'getenv\t"'(_ "Gets the value of an environment variable from within launchd")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'bsexec\t"'(_ "Execute a program in another process' bootstrap context")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'asuser\t"'(_ "Execute a program in the bootstrap context of a given user")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'submit\t"'(_ "Submit a basic job from the command line")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'managerpid\t"'(_ "Prints the PID of the launchd controlling the session")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'manageruid\t"'(_ "Prints the UID of the current launchd session")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'managername\t"'(_ "Prints the name of the current launchd session")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'error\t"'(_ "Prints a description of an error")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'variant\t"'(_ "Prints the launchd variant")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'version\t"'(_ "Prints the launchd version")'"' +complete --command launchctl -n '__fish_use_subcommand' -xa 'help\t"'(_ "Prints the usage for a given subcommand")'"' + diff --git a/share/completions/light.fish b/share/completions/light.fish new file mode 100644 index 000000000..5b33abba8 --- /dev/null +++ b/share/completions/light.fish @@ -0,0 +1,24 @@ +# Light is a program to control backlight controllers under GNU/Linux. +# See: https://github.com/haikarainen/light + +function __fish_print_light_controllers + command light -L +end + +complete -c light -s h -d 'Print help and exit' +complete -c light -s V -d 'Print version info and exit' +complete -c light -s G -d 'Get value (default)' +complete -c light -s S -x -d 'Set value' +complete -c light -s A -x -d 'Add value' +complete -c light -s U -x -d 'Subtract value' +complete -c light -s L -d 'List controllers' +complete -c light -s I -d 'Restore brightness' +complete -c light -s O -d 'Save brightness' +complete -c light -s b -d 'Brightness (default)' +complete -c light -s m -d 'Maximum brightness' +complete -c light -s c -d 'Minimum cap' +complete -c light -s a -d 'Selects controller automatically (default)' +complete -c light -s s -a '(__fish_print_light_controllers)' -x -d 'Specify controller to use' +complete -c light -s p -d 'Interpret & output values in percent' +complete -c light -s r -d 'Interpret & output values in raw mode' +complete -c light -s v -x -d 'Sets the verbosity level' -a '0\tRead\ values 1\tRead\ values\ \&\ errors 2\tRead\ values,\ erros\ \&\ warnings 3\tRead\ values,\ errors,\ warnings\ \&\ notices' diff --git a/share/completions/lxc.fish b/share/completions/lxc.fish new file mode 100644 index 000000000..ebfe9aa6a --- /dev/null +++ b/share/completions/lxc.fish @@ -0,0 +1,51 @@ +function __fish_lxc_no_subcommand -d 'Test if lxc has yet to be given the command' + for i in (commandline --tokenize --cut-at-cursor --current-process) + if contains -- $i config copy delete exec file help image launch list move network profile publish remote restore restart snapshot start stop + return 1 + end + end + return 0 +end + +function __fish_lxc_list_containers + lxc list -c n | string match -r '\| [a-zA-Z_-]+' | string replace -r '\| ' '' +end + +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments config --description 'Manage configuration.' +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments copy --description 'Copy containers within or in between lxd instances.' +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments delete --description 'Delete containers or snapshots.' +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments exec --description 'Execute the specified command in a container.' +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments file --description 'Manage files on a container.' +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments finger --description 'Check if the LXD instance is up.' +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments help --description 'Print help.' +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments image --description 'Manipulate container images.' +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments info --description 'List information on LXD servers and containers.' +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments init --description 'Initialize a container from a particular image.' +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments launch --description 'Launch a container from a particular image.' +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments list --description 'Lists the available resources.' +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments manpage --description 'Prints all the subcommands help.' +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments monitor --description 'Monitor activity on the LXD server.' +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments move --description 'Move containers within or in between lxd instances.' +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments network --description 'Manage networks.' +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments pause --description 'Changes state of one or more containers to pause.' +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments profile --description 'Manage configuration profiles.' +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments publish --description 'Publish containers as images.' +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments remote --description 'Manage remote LXD servers.' +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments restart --description 'Changes state of one or more containers to restart.' +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments restore --description 'Set the current state of a container back to a snapshot.' +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments snapshot --description 'Create a read-only snapshot of a container.' +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments start --description 'Changes state of one or more containers to start.' +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments stop --description 'Changes state of one or more containers to stop.' +complete --condition '__fish_lxc_no_subcommand' --command lxc --no-files --arguments version --description 'Prints the version number of this client tool.' + +# config +complete --condition '__fish_seen_subcommand_from config' --command lxc --no-files --arguments "device get set unset show edit trust" + +# exec +complete --condition '__fish_seen_subcommand_from exec' --command lxc --no-files --arguments "(__fish_lxc_list_containers)" + +# start +complete --condition '__fish_seen_subcommand_from start' --command lxc --no-files --arguments "(__fish_lxc_list_containers)" + +# stop +complete --condition '__fish_seen_subcommand_from stop' --command lxc --no-files --arguments "(__fish_lxc_list_containers)" diff --git a/share/completions/machinectl.fish b/share/completions/machinectl.fish index 1b8396083..277988c7b 100644 --- a/share/completions/machinectl.fish +++ b/share/completions/machinectl.fish @@ -50,7 +50,7 @@ complete -f -c machinectl -n "__fish_seen_subcommand_from list-images" -s a -l a complete -f -c machinectl -n "not __fish_seen_subcommand_from $commands" -a "status" -d "Show information about machine" complete -f -c machinectl -n "__fish_seen_subcommand_from status" -s l -l full -d "Do not ellipsize process tree entries" complete -x -c machinectl -n "__fish_seen_subcommand_from status" -s n -l lines -d "How many journal lines to show" -complete -x -A -c machinectl -n "__fish_seen_subcommand_from status" -s o -l output -d "Formatting of journal output" -a \ +complete -x -c machinectl -n "__fish_seen_subcommand_from status" -s o -l output -d "Formatting of journal output" -a \ 'short short-iso short-precise short-monotonic verbose export json json-pretty json-sse cat' complete -f -c machinectl -n "not __fish_seen_subcommand_from $commands" -a "show" -d "Show properties of machines" @@ -66,7 +66,7 @@ complete -f -c machinectl -n "not __fish_seen_subcommand_from $commands" -a "reb complete -f -c machinectl -n "not __fish_seen_subcommand_from $commands" -a "terminate" -d "Terminate machine (without shutting down)" complete -f -c machinectl -n "not __fish_seen_subcommand_from $commands" -a "kill" -d "Send signal to process in a machine" -complete -x -A -c machinectl -n "__fish_seen_subcommand_from kill" -l kill-who -d "Choose who to send the signal to" -a 'leader all' +complete -x -c machinectl -n "__fish_seen_subcommand_from kill" -l kill-who -d "Choose who to send the signal to" -a 'leader all' __fish_make_completion_signals complete -x -c machinectl -n "__fish_seen_subcommand_from kill" -s s -l signal -d "Signal to send" -a "$__kill_signals" @@ -100,8 +100,8 @@ complete -f -c machinectl -n "not __fish_seen_subcommand_from $commands" -a "exp complete -f -c machinectl -n "__fish_seen_subcommand_from export-tar export-raw" -l format -d "Specify compression format" -a 'uncompressed xz gzip bzip2' complete -f -c machinectl -n "not __fish_seen_subcommand_from $commands" -a "list-transfers" -d "Show running downloads, imports and exports" complete -f -c machinectl -n "not __fish_seen_subcommand_from $commands" -a "cancel-transfers" -d "Abort running downloads, imports or exports" -complete -x -A -c machinectl -n "__fish_seen_subcommand_from pull-{tar,raw}" -l verify -a 'no checksum signature' -d "Verify image with specified method" -complete -x -A -c machinectl -n "__fish_seen_subcommand_from pull-dkr" -l verify -a 'no' -d "Verify image (not available for dkr)" +complete -x -c machinectl -n "__fish_seen_subcommand_from pull-{tar,raw}" -l verify -a 'no checksum signature' -d "Verify image with specified method" +complete -x -c machinectl -n "__fish_seen_subcommand_from pull-dkr" -l verify -a 'no' -d "Verify image (not available for dkr)" complete -x -c machinectl -n "__fish_seen_subcommand_from pull-dkr" -l dkr-index-url -d "Specify index server" complete -f -c machinectl -n "__fish_seen_subcommand_from pull-{tar,raw,dkr}" -l force -d "Overwrite existing machine image" diff --git a/share/completions/make.fish b/share/completions/make.fish index dbebb409e..d62ee8cd7 100644 --- a/share/completions/make.fish +++ b/share/completions/make.fish @@ -1,13 +1,21 @@ # Completions for make +function __fish_complete_make_targets + set directory (string replace -r '^make .*(-C ?|--directory[= ]?)([^ ]*) .*$' '$2' -- $argv) + if test $status -eq 0 -a -d $directory + __fish_print_make_targets $directory + else + __fish_print_make_targets + end +end # This completion reenables file completion on # assignments, so e.g. 'make foo FILES=' will receive standard # filename completion. complete -c make -n 'commandline -ct | string match "*=*"' -complete -x -c make -a "(__fish_print_make_targets)" --description "Target" +complete -x -c make -a "(__fish_complete_make_targets (commandline -c))" --description "Target" complete -r -c make -s f --description "Use file as makefile" -r -complete -x -c make -s C -x -a "(__fish_complete_directories (commandline -ct))" --description "Change directory" +complete -x -c make -s C -l directory -x -a "(__fish_complete_directories (commandline -ct))" --description "Change directory" complete -c make -s d --description "Debug mode" complete -c make -s e --description "Environment before makefile" complete -c make -s i --description "Ignore errors" diff --git a/share/completions/mkdir.fish b/share/completions/mkdir.fish index f27a89b8b..3f18ee5e9 100644 --- a/share/completions/mkdir.fish +++ b/share/completions/mkdir.fish @@ -2,7 +2,7 @@ # Checks if we are using GNU tools if mkdir --version > /dev/null ^ /dev/null complete -c mkdir -l version --description 'Output version' - complete -c mkdir -s m -l mode --description 'Set file mode (as in chmod)' -x + complete -c mkdir -s m -l mode --description 'Set file mode (as in chmod)' -x complete -c mkdir -s p -l parents --description 'Make parent directories as needed' complete -c mkdir -s v -l verbose --description 'Print a message for each created directory' complete -c mkdir -l help --description 'Display help' diff --git a/share/completions/mkinitcpio.fish b/share/completions/mkinitcpio.fish index 7d3443bd1..664eb14fb 100644 --- a/share/completions/mkinitcpio.fish +++ b/share/completions/mkinitcpio.fish @@ -3,7 +3,7 @@ function __fish_mkinitcpio_complete_hooks mkinitcpio --listhooks | tail -n +2 | sed -e "s/^[¹²³].*//" -e "s/\t\+/\n/g" | sed -e "s/^\([^[:space:]]\+\)[¹²³]\$/\1\t(deprecated)/g" end - + complete -c mkinitcpio -s A -l addhooks -d 'Add the additional hooks to the image' -a "(__fish_mkinitcpio_complete_hooks)" -f complete -c mkinitcpio -s c -l config -d 'Use config file to generate the ramdisk' complete -c mkinitcpio -s d -l generatedir -d 'Set directory as the location where the initramfs is built' diff --git a/share/completions/mkvextract.fish b/share/completions/mkvextract.fish new file mode 100644 index 000000000..c2d761fc8 --- /dev/null +++ b/share/completions/mkvextract.fish @@ -0,0 +1,82 @@ +# Sample output of 'mkvmerge -i file.mkv' +# +# File 'file.mkv': container: Matroska +# Track ID 0: video (MPEG-4p10/AVC/h.264) +# Track ID 1: audio (AAC) +# Track ID 2: subtitles (SubStationAlpha) +# Attachment ID 1: type 'application/x-truetype-font', size 53532 bytes, file name 'some_font.ttf' +# Chapters: 7 entires + +function __fish_mkvextract_find_matroska_in_args + set -l cmd (commandline -opc) + if not set -q cmd[3] + return 1 + end + for c in $cmd[3..-1] + set -l skip_next 1 + test $skip_next -eq 0; and set skip_next 1; and continue + switch $c + # General options with an argument we need to skip + case "--ui-language" "--command-line-charset" "--output-charset" "-r" "--redirect-output" "-c" "--blockadd" "--simple-language" + set skip_next 0 + continue + # these behave like commands and everything after them is ignored + case "-h" "--help" "-V" "--version" + return 1 + case "*" + if test -f "$c" + echo $c + return 0 + end + continue + end + end + return 1 +end + +function __fish_mkvextract_print_attachments + if set -l matroska (__fish_mkvextract_find_matroska_in_args) + if set -l info (mkvmerge -i $matroska) + string match 'Attachment ID*' -- $info | string replace -r '.*?(\d+).*? type \'(.*?)\'.*?file name \'(.*?)\'' '$1:\t$3 ($2)' + end + end +end + +function __fish_mkvextract_print_tracks + if set -l matroska (__fish_mkvextract_find_matroska_in_args) + if set -l info (mkvmerge -i $matroska) + string match 'Track ID*' -- $info | string replace -r '.*?(\d+): (.*)' '$1:\t$2' + end + end +end + +# simple options +complete -f -c mkvextract -s V -l "version" -d "Show version information" +complete -f -c mkvextract -s h -l "help" -d "Show help" +# commands +complete -f -c mkvextract -n "test (count (commandline -opc)) -lt 2" -a "tracks" -d "Extract tracks to external files" +complete -f -c mkvextract -n "test (count (commandline -opc)) -lt 2" -a "tags" -d "Extract tags as XML" +complete -f -c mkvextract -n "test (count (commandline -opc)) -lt 2" -a "attachments" -d "Extract attachments" +complete -f -c mkvextract -n "test (count (commandline -opc)) -lt 2" -a "chapters" -d "Extract chapters as XML" +complete -f -c mkvextract -n "test (count (commandline -opc)) -lt 2" -a "cuesheet" -d "Extract chapters and tags as CUE sheet" +complete -f -c mkvextract -n "test (count (commandline -opc)) -lt 2" -a "timecodes_v2" -d "Extract timecodes of a track as timecode v2 file" +complete -f -c mkvextract -n "test (count (commandline -opc)) -lt 2" -a "cues" -d "Extract cue information as text file" +# dynamic tracks and attachments completions +complete -f -c mkvextract -n "__fish_seen_subcommand_from tracks timecodes_v2 cues" -a "(__fish_mkvextract_print_tracks)" +complete -f -c mkvextract -n "__fish_seen_subcommand_from attachments" -a "(__fish_mkvextract_print_attachments)" +# options common to all commands +complete -f -c mkvextract -n "test (count (commandline -opc)) -ge 2" -s f -l "parse-fully" -d "Parse the whole file instead of relying on the index" +complete -f -c mkvextract -n "test (count (commandline -opc)) -ge 2" -s v -l "verbose" -d "Increase verbosity" +complete -f -c mkvextract -n "test (count (commandline -opc)) -ge 2" -s q -l "quiet" -d "Suppress status output" +complete -f -c mkvextract -n "test (count (commandline -opc)) -ge 2" -r -l "ui-language" -d "Force the translations for 'code' to be used" +complete -f -c mkvextract -n "test (count (commandline -opc)) -ge 2" -r -l "command-line-charset" -d "Charset for strings on the command line" +complete -f -c mkvextract -n "test (count (commandline -opc)) -ge 2" -r -l "output-charset" -d "Outputs messages in specified charset" +complete -f -c mkvextract -n "test (count (commandline -opc)) -ge 2" -r -s r -l "redirect-output" -d "Redirect all messages into a file" +# command-specific options +complete -f -c mkvextract -n "__fish_seen_subcommand_from tracks" -r -s c -d "Convert text subtitles to a charset" +complete -f -c mkvextract -n "__fish_seen_subcommand_from tracks" -l "cuesheet" -d "Also try to extract the CUE sheet" +complete -f -c mkvextract -n "__fish_seen_subcommand_from tracks" -r -l "blockadd" -d "Keep only the BlockAdditions up to the specified level" +complete -f -c mkvextract -n "__fish_seen_subcommand_from tracks" -l "raw" -d "Extract the data to a raw file" +complete -f -c mkvextract -n "__fish_seen_subcommand_from tracks" -l "fullraw" -d "Extract the data to a raw file including the CodecPrivate as header" +complete -f -c mkvextract -n "__fish_seen_subcommand_from chapters" -s s -l "simple" -d "Exports the chapter information in a simple format" +complete -f -c mkvextract -n "__fish_seen_subcommand_from chapters" -r -l "simple-language" -d "Uses the chapter names of the specified language" diff --git a/share/completions/mosh.fish b/share/completions/mosh.fish index 064c7023b..150dcd5f7 100644 --- a/share/completions/mosh.fish +++ b/share/completions/mosh.fish @@ -21,6 +21,3 @@ complete -c mosh -f -l predict --description 'Controls use of speculative local complete -c mosh -s a --description 'Synonym for --predict=always' complete -c mosh -s n --description 'Synonym for --predict=never' complete -c mosh -s p -l port --description 'Use a particular server-side UDP port or port range' - -# Since mosh runs subcommands, it can accept any switches -complete -c mosh -u diff --git a/share/completions/mplayer.fish b/share/completions/mplayer.fish index eb72628fb..b3a48635a 100644 --- a/share/completions/mplayer.fish +++ b/share/completions/mplayer.fish @@ -82,6 +82,4 @@ complete -c mplayer -o vfm -x --description "Video output" -a " complete -c mplayer -l help --description "Display help and exit" complete -c mplayer -l version --description "Display version and exit" -complete -c mplayer -u - set -e mplayer_lang diff --git a/share/completions/mvn.fish b/share/completions/mvn.fish index 4fcc0646c..1e99a40bc 100644 --- a/share/completions/mvn.fish +++ b/share/completions/mvn.fish @@ -443,7 +443,7 @@ complete -c mvn -a "jaxb2:schemagen" -d "Mojo that creates XML schema(s) from co complete -c mvn -a "jaxb2:testSchemagen" -d "Mojo that creates XML schema(s) from test-scope Java testSources or binaries by invoking the JAXB SchemaGenerator. This implementation is tailored to use the JAXB Reference Implementation from project Kenai. Note that the TestSchemaGenerationMojo was completely re-implemented for the 2.x versions. Its configuration semantics and parameter set is not backwards compatible with the 1.x plugin versions. If you are upgrading from version 1.x of the plugin, read the documentation carefully. " complete -c mvn -a "jaxb2:testXjc" -d "Mojo that creates test-scope Java source or binaries from XML schema(s) by invoking the JAXB XJC binding compiler. This implementation is tailored to use the JAXB Reference Implementation from project Kenai. Note that the TestXjcMojo was completely re-implemented for the 2.x versions. Its configuration semantics and parameter set is not necessarily backwards compatible with the 1.x plugin versions. If you are upgrading from version 1.x of the plugin, read the documentation carefully. " complete -c mvn -a "jaxb2:xjc" -d "Mojo that creates compile-scope Java source or binaries from XML schema(s) by invoking the JAXB XJC binding compiler. This implementation is tailored to use the JAXB Reference Implementation from project Kenai. Note that the XjcMojo was completely re-implemented for the 2.x versions. Its configuration semantics and parameter set is not necessarily backwards compatible with the 1.x plugin versions. If you are upgrading from version 1.x of the plugin, read the documentation carefully. " -complete -c mvn -a "jpox:enhance" -d "" +complete -c mvn -a "jpox:enhance" complete -c mvn -a "jpox:schema-create" -d "Generates the Schema from the JDO mappings and the enhanced class files." complete -c mvn -a "jpox:schema-dbinfo" -d "Provides detailed information about the database - limits and datatypes support. Currently this seems to be printing out the information for each of available database datatypes twice. " complete -c mvn -a "jpox:schema-delete" -d "Deletes all database tables required for a set of JDO MetaData files (and enhanced classes) from the database schema." @@ -457,8 +457,8 @@ complete -c mvn -a "js-import:generate-html" -d "Main goal implementation of the complete -c mvn -a "js-import:test-import-js" -d "Test goal implementation of the import mojo." complete -c mvn -a "js-import:import-js" -d "Main goal implementation of the import mojo." complete -c mvn -a "js-import:help" -d "Display help information on js-import-maven-plugin. Call mvn js-import:help -Ddetail=true -Dgoal= to display parameter details." -complete -c mvn -a "jspc:compile" -d "" -complete -c mvn -a "jspc:testCompile" -d "" +complete -c mvn -a "jspc:compile" +complete -c mvn -a "jspc:testCompile" complete -c mvn -a "openjpa:test-enhance" -d "Processes Application model classes and enhances them by running Open JPA Enhancer tool." complete -c mvn -a "openjpa:help" -d "Display help information on openjpa-maven-plugin. Call mvn openjpa:help -Ddetail=true -Dgoal= to display parameter details." complete -c mvn -a "openjpa:enhance" -d "Processes Application model classes and enhances them by running Open JPA Enhancer tool. This basically only acts as a container for the xdoclet stuff since all the required functionality is already in the AbstratOpenJpaEnhancerMojo." @@ -516,9 +516,9 @@ complete -c mvn -a "jdepend:help" -d "Display help information on jdepend-maven- complete -c mvn -a "jdepend:generate" -d "Run JDepend and generate a site report. Goal which generate the JDepend metrics." complete -c mvn -a "codenarc:codenarc" -d "Create a CodeNarc Report." complete -c mvn -a "codenarc:help" -d "Display help information on codenarc-maven-plugin. Call mvn codenarc:help -Ddetail=true -Dgoal= to display parameter details." -complete -c mvn -a "findbugs:check" -d "" -complete -c mvn -a "findbugs:findbugs" -d "" -complete -c mvn -a "findbugs:gui" -d "" +complete -c mvn -a "findbugs:check" +complete -c mvn -a "findbugs:findbugs" +complete -c mvn -a "findbugs:gui" -d "Open the findbugs GUI to browse the report" complete -c mvn -a "findbugs:help" -d "Display help information on findbugs-maven-plugin. Call mvn findbugs:help -Ddetail=true -Dgoal= to display parameter details." complete -c mvn -a "fitnesse:remotecall" -d "This goal uses the fitnesse.runner.TestRunner class for getting result of a remote FitNesse web page execution. It's possible to define several pages and/or servers." complete -c mvn -a "fitnesse:help" -d "Display help information on fitnesse-maven-plugin. Call mvn fitnesse:help -Ddetail=true -Dgoal= to display parameter details." @@ -730,7 +730,7 @@ complete -c mvn -a "appengine:backends_stop" -d "Stop the specified backend." complete -c mvn -a "android:aar" -d "Creates an Android Archive (aar) file. " complete -c mvn -a "android:apk" -d "Creates the apk file. By default signs it with debug keystore. Change that by setting configuration parameter false." complete -c mvn -a "android:apklib" -d "Creates the apklib file. apklib files do not generate deployable artifacts." -complete -c mvn -a "android:clean" -d "" +complete -c mvn -a "android:clean" complete -c mvn -a "android:connect" -d "Connect external IP addresses to the ADB server." complete -c mvn -a "android:deploy" -d "Deploys the apk(s) of the current project(s) to all attached devices and emulators. Automatically skips other projects in a multi-module build that do not use packaging apk without terminating. Deploymnet is automatically performed when running mvn integration-test (or mvn install) on a project with instrumentation tests." complete -c mvn -a "android:deploy-apk" -d "Deploys a specified Android application apk to attached devices and emulators. By default it will deploy to all, but a subset or single one can be configured with the device and devices parameters.This goal can be used in non-android projects and as standalone execution on the command line. " @@ -752,10 +752,10 @@ complete -c mvn -a "android:manifest-merger" -d "Manifest Merger V2 AndroidManif complete -c mvn -a "android:manifest-update" -d "Updates various version attributes present in the AndroidManifest.xml file." complete -c mvn -a "android:monkey" -d "Can execute tests using UI/Application Exerciser Monkey. Implements parsing parameters from pom or command line arguments and sets useful defaults as well. This goal will invoke Android Monkey exerciser. If the application crashes during the exercise, this goal can fail the build. A typical usage of this goal can be found at Quality tools for Android project." complete -c mvn -a "android:monkeyrunner" -d "Can execute monkey runner programs. Implements parsing parameters from pom or command line arguments and sets useful defaults as well. This goal will invoke monkey runner scripts. If the application crashes during the exercise, this goal can fail the build. A typical usage of this goal can be found at Quality tools for Android project." -complete -c mvn -a "android:ndk-build" -d "" +complete -c mvn -a "android:ndk-build" complete -c mvn -a "android:proguard" -d "Processes both application and dependency classes using the ProGuard byte code obfuscator, minimzer, and optimizer. For more information, see https://proguard.sourceforge.net." -complete -c mvn -a "android:publish-apk" -d "" -complete -c mvn -a "android:publish-listing" -d "" +complete -c mvn -a "android:publish-apk" +complete -c mvn -a "android:publish-listing" complete -c mvn -a "android:pull" -d "Copy file or directory from all the attached (or specified) devices/emulators." complete -c mvn -a "android:push" -d "Copy file to all the attached (or specified) devices/emulators." complete -c mvn -a "android:redeploy" -d "Undeploys and the deploys (= redeploys) the apk(s) of the current project(s) to all attached devices and emulators. Automatically skips other projects in a multi-module build that do not use packaging apk without terminating. " @@ -786,14 +786,14 @@ complete -c mvn -a "liquibase:diff" -d "Generates a diff between the specified d complete -c mvn -a "liquibase:update" -d "Applies the DatabaseChangeLogs to the database. Useful as part of the build process." complete -c mvn -a "liquibase:generateChangeLog" -d "Generates SQL that marks all unapplied changes as applied." complete -c mvn -a "liquibase:migrateSQL" -d "Creates an SQL migration script using the provided DatabaseChangeLog(s) comparing what already exists in the database to what is defined in the DataBaseChangeLog(s)." -complete -c mvn -a "jgitflow:feature-deploy" -d "" -complete -c mvn -a "jgitflow:release-finish" -d "" -complete -c mvn -a "jgitflow:hotfix-start" -d "" -complete -c mvn -a "jgitflow:hotfix-finish" -d "" -complete -c mvn -a "jgitflow:feature-finish" -d "" -complete -c mvn -a "jgitflow:build-number" -d "" -complete -c mvn -a "jgitflow:release-start" -d "" -complete -c mvn -a "jgitflow:feature-start" -d "" +complete -c mvn -a "jgitflow:feature-deploy" +complete -c mvn -a "jgitflow:release-finish" -d "Finishes a release" +complete -c mvn -a "jgitflow:hotfix-start" -d "Starts a hotfix" +complete -c mvn -a "jgitflow:hotfix-finish" -d "Finishes a hotfix" +complete -c mvn -a "jgitflow:feature-finish" -d "Finishes a feature branch" +complete -c mvn -a "jgitflow:build-number" -d "Updates the pom versions in the current branch by adding a build number label" +complete -c mvn -a "jgitflow:release-start" -d "Starts a release" +complete -c mvn -a "jgitflow:feature-start" -d "Starts a feature branch" complete -c mvn -a "spring-boot:help" -d "Display help information on spring-boot-maven-plugin. Call mvn spring-boot:help -Ddetail=true -Dgoal= to display parameter details." complete -c mvn -a "spring-boot:repackage" -d "Repackages existing JAR and WAR archives so that they can be executed from the command line using java -jar. With layout=NONE can also be used simply to package a JAR with nested dependencies (and no main class, so not executable)." complete -c mvn -a "spring-boot:run" -d "Run an executable archive application." diff --git a/share/completions/netctl-auto.fish b/share/completions/netctl-auto.fish index 1b010b6f6..1b208d317 100644 --- a/share/completions/netctl-auto.fish +++ b/share/completions/netctl-auto.fish @@ -1,4 +1,4 @@ -set -l cmds list current start stop switch-to enable disable enable-all disable-all +set -l cmds list start stop switch-to enable disable enable-all disable-all is-active is-enabled # Helper function that prints network profiles managed by netctl-auto. # If no argument is given, it prints all profiles. @@ -52,7 +52,6 @@ end complete -c netctl-auto -n "not __fish_seen_subcommand_from $cmds" -l help -d "Show help" complete -c netctl-auto -n "not __fish_seen_subcommand_from $cmds" -l version -d "Show version" complete -c netctl-auto -n "not __fish_seen_subcommand_from $cmds" -a list -f -d "List all available profiles for automatic selection" -complete -c netctl-auto -n "not __fish_seen_subcommand_from $cmds" -a current -d "Report currently active profiles" complete -c netctl-auto -n "not __fish_seen_subcommand_from $cmds" -a start -f -d "Start automatic profile selection on interface" complete -c netctl-auto -n "not __fish_seen_subcommand_from $cmds" -a stop -f -d "Stop automatic profile selection on interface" complete -c netctl-auto -n "not __fish_seen_subcommand_from $cmds" -a switch-to -f -d "Switch to the given network profile" @@ -60,9 +59,11 @@ complete -c netctl-auto -n "not __fish_seen_subcommand_from $cmds" -a enable -f complete -c netctl-auto -n "not __fish_seen_subcommand_from $cmds" -a disable -f -d "Disable network profile for automatic selection" complete -c netctl-auto -n "not __fish_seen_subcommand_from $cmds" -a enable-all -f -d "Enable all profiles for automatic selection" complete -c netctl-auto -n "not __fish_seen_subcommand_from $cmds" -a disable-all -f -d "Disable all profiles for automatic selection" +complete -c netctl-auto -n "not __fish_seen_subcommand_from $cmds" -a is-active -f -d "Check whether specified profile is active" +complete -c netctl-auto -n "not __fish_seen_subcommand_from $cmds" -a is-enabled -f -d "Check whether specified profile is enabled" complete -c netctl-auto -n "__fish_seen_subcommand_from switch-to" -f -a "(__fish_print_netctl-auto_profile other disabled)" -d "Profile" complete -c netctl-auto -n "__fish_seen_subcommand_from enable" -f -a "(__fish_print_netctl-auto_profile disabled)" -d "Profile" complete -c netctl-auto -n "__fish_seen_subcommand_from disable" -f -a "(__fish_print_netctl-auto_profile active other)" -d "Profile" complete -c netctl-auto -n "__fish_seen_subcommand_from start stop" -f -a "(__fish_print_interfaces)" - +complete -c netctl-auto -n "__fish_seen_subcommand_from is-enabled is-active" -x -a "(__fish_print_netctl-auto_profile active disabled other)" diff --git a/share/completions/nmcli.fish b/share/completions/nmcli.fish index 459371db9..f1481d8bb 100644 --- a/share/completions/nmcli.fish +++ b/share/completions/nmcli.fish @@ -1,31 +1,81 @@ -complete -c nmcli -s t -l terse -d 'Output is terse' -complete -c nmcli -s p -l pretty -d 'Output is pretty' -complete -c nmcli -s m -l mode -xa 'tabular multiline' -d 'Switch between tabular and multiline mode' -complete -c nmcli -s f -l fields -xa 'all common' -d 'Specify the output fields' -complete -c nmcli -s e -l escape -xa 'yes no' -d 'Whether to escape ":" and "\\" characters' -complete -c nmcli -s v -l version -d 'Show nmcli version' -complete -c nmcli -s h -l help -d 'Print help information' -complete -c nmcli -d 'Command-line tool to control NetworkManager' -x +set -l nmcli_commands general networking radio connection device agent monitor help +set -l nmcli_general status hostname permissions logging help +set -l nmcli_networking on off connectivity help +set -l nmcli_radio all wifi wwan help +set -l nmcli_connection show up down add modify clone edit delete monitor reload load import export help +set -l nmcli_device status show set connect reapply modify disconnect delete monitor wifi lldp help +set -l nmcli_agent secret polkit all help -complete -c nmcli -xa nm -n '__fish_use_subcommand' -d 'Inquiry and change the state of NM' -x -complete -c nmcli -n '__fish_seen_subcommand_from nm; and not __fish_seen_subcommand_from status enable sleep wifi wwan' -xa 'status enable sleep wifi wwan' -complete -c nmcli -n '__fish_seen_subcommand_from nm; and __fish_seen_subcommand_from enable sleep' -xa 'true false' -complete -c nmcli -n '__fish_seen_subcommand_from nm; and __fish_seen_subcommand_from wifi wwan' -xa 'on off' +complete -c nmcli -s t -l terse -d 'Output is terse' -n "not __fish_seen_subcommand_from $nmcli_commands" +complete -c nmcli -s p -l pretty -d 'Output is pretty' -n "not __fish_seen_subcommand_from $nmcli_commands" +complete -c nmcli -s m -l mode -d 'Switch between tabular and multiline mode' -xa 'tabular multiline' -n "not __fish_seen_subcommand_from $nmcli_commands" +complete -c nmcli -s c -l color -d 'Whether to use colors in output' -xa 'auto yes no' -n "not __fish_seen_subcommand_from $nmcli_commands" +complete -c nmcli -s f -l fields -d 'Specify the output fields' -xa 'all common' -n "not __fish_seen_subcommand_from $nmcli_commands" +complete -c nmcli -s e -l escape -d 'Whether to escape ":" and "\\" characters' -xa 'yes no' -n "not __fish_seen_subcommand_from $nmcli_commands" +complete -c nmcli -s a -l ask -d 'Ask for missing parameters' -n "not __fish_seen_subcommand_from $nmcli_commands" +complete -c nmcli -s s -l show-secrets -d 'Allow displaying passwords' -n "not __fish_seen_subcommand_from $nmcli_commands" +complete -c nmcli -s w -l wait -d 'Set timeout (seconds) waiting for finishing operations' -x -n "not __fish_seen_subcommand_from $nmcli_commands" +complete -c nmcli -s v -l version -d 'Show nmcli version' -x -n "not __fish_seen_subcommand_from $nmcli_commands" +complete -c nmcli -s h -l help -d 'Print help information' -x +complete -c nmcli -d 'Command-line tool to control NetworkManager' -complete -c nmcli -xa con -n '__fish_use_subcommand' -d "Get information about NM's connections" -x -complete -c nmcli -n '__fish_seen_subcommand_from con; and not __fish_seen_subcommand_from list status up down delete' -xa 'list status up down delete' -complete -c nmcli -n '__fish_seen_subcommand_from con; and __fish_seen_subcommand_from list up down delete' -xa 'id uuid' -complete -c nmcli -n 'contains_seq con up -- (commandline -op)' -xa 'iface ap' -complete -c nmcli -n 'contains_seq con up iface -- (commandline -op)' -xa '(__fish_print_interfaces)' -complete -c nmcli -n 'contains_seq con up -- (commandline -op)' -l nowait -d 'Exit immediately' -complete -c nmcli -n 'contains_seq con up -- (commandline -op)' -l timeout -d 'How long to wait for operation completion' -x +complete -c nmcli -n "not __fish_seen_subcommand_from $nmcli_commands" -xa "$nmcli_commands" -complete -c nmcli -xa dev -n '__fish_use_subcommand' -d 'Get information about devices' -x -complete -c nmcli -n '__fish_seen_subcommand_from dev; and not __fish_seen_subcommand_from status list disconnect wifi' -xa 'status list disconnect wifi' -complete -c nmcli -n 'contains_seq dev disconnect -- (commandline -op)' -l nowait -d 'Exit immediately' -complete -c nmcli -n 'contains_seq dev list -- (commandline -op)' -xa 'iface' -complete -c nmcli -n '__fish_seen_subcommand_from dev; and __fish_seen_subcommand_from iface' -xa '(__fish_print_interfaces)' -complete -c nmcli -n 'contains_seq dev wifi -- (commandline -op)' -xa 'list iface' -complete -c nmcli -n 'contains_seq dev wifi list -- (commandline -op)' -xa 'essid bssid' +complete -c nmcli -n "__fish_seen_subcommand_from general; and not __fish_seen_subcommand_from $nmcli_general" -xa 'status' -d 'Show overall status of NetworkManager' +complete -c nmcli -n "__fish_seen_subcommand_from general; and not __fish_seen_subcommand_from $nmcli_general" -xa 'hostname' -d 'Get or change persistent system hostname' +complete -c nmcli -n "__fish_seen_subcommand_from general; and not __fish_seen_subcommand_from $nmcli_general" -xa 'permissions' -d 'Show caller permissions for authenticated operations' +complete -c nmcli -n "__fish_seen_subcommand_from general; and not __fish_seen_subcommand_from $nmcli_general" -xa 'logging' -d 'Get or change NetworkManager logging level and domains' +complete -c nmcli -n "__fish_seen_subcommand_from general; and not __fish_seen_subcommand_from $nmcli_general" -xa 'help' +complete -c nmcli -n "contains_seq general logging -- (commandline -op)" -xa 'level domains help' +complete -c nmcli -n "__fish_seen_subcommand_from networking; and not __fish_seen_subcommand_from $nmcli_networking" -xa 'on' -d 'Switch networking on' +complete -c nmcli -n "__fish_seen_subcommand_from networking; and not __fish_seen_subcommand_from $nmcli_networking" -xa 'off' -d 'Switch networking off' +complete -c nmcli -n "__fish_seen_subcommand_from networking; and not __fish_seen_subcommand_from $nmcli_networking" -xa 'connectivity' -d 'Get network connectivity state' +complete -c nmcli -n "__fish_seen_subcommand_from networking; and not __fish_seen_subcommand_from $nmcli_networking" -xa 'help' +complete -c nmcli -n "contains_seq networking connectivity -- (commandline -op)" -xa 'check' -d 'Re-check the connectivity' +complete -c nmcli -n "__fish_seen_subcommand_from radio; and not __fish_seen_subcommand_from $nmcli_radio" -xa 'all' -d 'Get status of all radio switches; turn them on/off' +complete -c nmcli -n "contains_seq radio all -- (commandline -op)" -xa 'on off help' +complete -c nmcli -n "__fish_seen_subcommand_from radio; and not __fish_seen_subcommand_from $nmcli_radio" -xa 'wifi' -d 'Get status of Wi-Fi radio switch; turn it on/off' +complete -c nmcli -n "contains_seq radio wifi -- (commandline -op)" -xa 'on off help' +complete -c nmcli -n "__fish_seen_subcommand_from radio; and not __fish_seen_subcommand_from $nmcli_radio" -xa 'wwan' -d 'Get status of mobile broadband radio switch; turn it on/off' +complete -c nmcli -n "contains_seq radio wwan -- (commandline -op)" -xa 'on off help' + +complete -c nmcli -n "__fish_seen_subcommand_from connection; and not __fish_seen_subcommand_from $nmcli_connection" -xa "$nmcli_connection" +# Connection subcommands are self-explanatory, I'm just highlighting a difference between edit and modify +complete -c nmcli -n "__fish_seen_subcommand_from connection; and not __fish_seen_subcommand_from $nmcli_connection" -xa "modify" -d "Modify one or more properties" +complete -c nmcli -n "__fish_seen_subcommand_from connection; and not __fish_seen_subcommand_from $nmcli_connection" -xa "edit" -d "Interactive edit" +complete -c nmcli -n "contains_seq connection show -- (commandline -op)" -l active -d 'List only active profiles' +complete -c nmcli -n "contains_seq connection show -- (commandline -op)" -l order -d 'Custom connection ordering' +complete -c nmcli -n "contains_seq connection show -- (commandline -op)" -xa 'id uuid path apath help' +complete -c nmcli -n "contains_seq connection up -- (commandline -op)" -xa 'id uuid path ifname help' +complete -c nmcli -n "contains_seq connection up -- (commandline -op)" -xa 'ap' -d 'Specify AP to connect to (only for Wi-Fi)' +complete -c nmcli -n "contains_seq connection up -- (commandline -op)" -xa 'nsp' -d 'Specify NSP to connect to (only for WiMAX)' +complete -c nmcli -n "contains_seq connection up -- (commandline -op)" -xa 'passwd-file' -d 'password file to activate the connection' +complete -c nmcli -n "contains_seq connection down -- (commandline -op)" -xa 'id uuid path apath help' +complete -c nmcli -n "contains_seq connection add -- (commandline -op)" -xa 'type ifname con-name autoconnect save master slave-type help' +complete -c nmcli -n "contains_seq connection modify -- (commandline -op)" -l temporary +complete -c nmcli -n "contains_seq connection modify -- (commandline -op)" -xa 'id uuid path help' +complete -c nmcli -n "contains_seq connection clone -- (commandline -op)" -l temporary +complete -c nmcli -n "contains_seq connection clone -- (commandline -op)" -xa 'id uuid path help' +complete -c nmcli -n "contains_seq connection edit -- (commandline -op)" -xa 'id uuid path type help' +complete -c nmcli -n "contains_seq connection edit type -- (commandline -op)" -xa 'con-name' +complete -c nmcli -n "contains_seq connection delete -- (commandline -op)" -xa 'id uuid path help' +complete -c nmcli -n "contains_seq connection monitor -- (commandline -op)" -xa 'id uuid path help' +complete -c nmcli -n "contains_seq connection import -- (commandline -op)" -l temporary +complete -c nmcli -n "contains_seq connection import -- (commandline -op)" -xa 'type file help' +complete -c nmcli -n "contains_seq connection export -- (commandline -op)" -xa 'id uuid path help' + +set -l wifi_commands list connect hotspot rescan help +complete -c nmcli -n "__fish_seen_subcommand_from device; and not __fish_seen_subcommand_from $nmcli_device" -xa "$nmcli_device" +complete -c nmcli -n "contains_seq device set -- (commandline -op)" -xa 'ifname autoconnect managed' +complete -c nmcli -n "contains_seq device wifi -- (commandline -op); and not __fish_seen_subcommand_from $wifi_commands" -xa "$wifi_commands" +complete -c nmcli -n "contains_seq device wifi list -- (commandline -op)" -xa 'ifname bssid' +complete -c nmcli -n "contains_seq device wifi connect -- (commandline -op)" -xa 'password wep-key-type ifname bssid name private hidden' +complete -c nmcli -n "contains_seq device wifi hotspot -- (commandline -op)" -xa 'ifname con-name ssid band channel password' +complete -c nmcli -n "contains_seq device wifi rescan -- (commandline -op)" -xa 'ifname ssid' +complete -c nmcli -n "contains_seq device lldp -- (commandline -op)" -xa 'list' + +complete -c nmcli -n "__fish_seen_subcommand_from agent; and not __fish_seen_subcommand_from $nmcli_agent" -xa "secret" -d "Register nmcli as NM secret agent" +complete -c nmcli -n "__fish_seen_subcommand_from agent; and not __fish_seen_subcommand_from $nmcli_agent" -xa "polkit" -d "Register nmcli as a polkit agent for user session" +complete -c nmcli -n "__fish_seen_subcommand_from agent; and not __fish_seen_subcommand_from $nmcli_agent" -xa "all" -d "Run nmcli as secret and polkit agent" diff --git a/share/completions/objdump.fish b/share/completions/objdump.fish new file mode 100644 index 000000000..23e13233d --- /dev/null +++ b/share/completions/objdump.fish @@ -0,0 +1,49 @@ +complete -c objdump -l archive-headers -s a -d "Display archive header information" +complete -c objdump -l file-headers -s f -d "Display contents of the overall file header" +complete -c objdump -l private-headers -s p -d "Display object format specific file header contents" +complete -c objdump -l private -s P -d "Display object format specific contents" -x +complete -c objdump -l header -s h -d "Display contents of section headers" +complete -c objdump -l section-header -s h -d "Display content of section headers" +complete -c objdump -l all-headers -s x -d "Display the contents of all headers" +complete -c objdump -l disassemble -s d -d "Display assembler contents of executable sections" +complete -c objdump -l disassemble-all -s D -d "Display assembler contents of all sections" +complete -c objdump -l source -s S -d "Intermix source code with disassembly" +complete -c objdump -l full-contents -s s -d "Display full contents of all sections requested" +complete -c objdump -l debugging -s g -d "Display debug information in object file" +complete -c objdump -l debugging-tags -s e -d "Display debug information using ctags style" +complete -c objdump -l stabs -s G -d "Display (in raw form) any STABS info in file" +complete -c objdump -l dwarf -x -d "Display DWARF info in file" -a "rawline decodedline info abbrev pubnames aranges macro frames frames-interp str loc Ranges pubtypes gdb_index trace_info trace_abbrev trace_aranges addr cu_index" +complete -c objdump -l syms -s t -d "Display contents of symbol table(s)" +complete -c objdump -l dynamic-syms -s T -d "Display contents of dynamic symbol table" +complete -c objdump -l reloc -s r -d "Display relocation entries in file" +complete -c objdump -l dynamic-reloc -s R -d "Display dynamic relocation entries in file" +complete -c objdump -l version -s v -d "Display version number" +complete -c objdump -l info -s i -d "List object formats and architectures supported" +complete -c objdump -l help -s H -d "Display help" +complete -c objdump -l target -s b -d "Specify target object format" -x -a "elf64-x86-64 elf32-i386 elf32-iamcu elf32-x86-64 a.out-i386-linux pei-i386 pei-x86-64 elf64-l1om elf64-k1om elf64-little elf64-big elf32-little elf32-big plugin srec symbolsrec verilog tekhex binary ihex" +complete -c objdump -l architecture -s m -d "Specify target architecture" -x -a "i386 i386:x86-64 i386:x64-32 i8086 i386:intel i386:x86-64:intel i386:x64-32:intel i386:nacl i386:x86-64:nacl i386:x64-32:nacl iamcu iamcu:intel l1om l1om:intel k1om k1om:intel plugin" +complete -c objdump -l section -s j -d "Only display information for given section" -x +complete -c objdump -l disassembler-options -s M -d "Pass given options on to disassembler" -x +complete -c objdump -l endian -x -d "Set format endianness when disassembling" -a "big little" +complete -c objdump -o EB -d "Assume big endian format when disassembling" +complete -c objdump -o EL -d "Assume little endian format when disassembling" +complete -c objdump -l file-start-context -d "Include context from start of file (with -S)" +complete -c objdump -l include -s I -f -d "Add given directory to search list from source files" -x +complete -c objdump -l line-numbers -s l -d "Include line numbers and filenames in output" +complete -c objdump -l file-offsets -s F -d "Include file offsets when displaying information" +complete -c objdump -l demangle -s C -d "Decode mangled/processed symbol names" -x -a "auto gnu lucid arm hp edg gnu-v3 java gnat" +complete -c objdump -l wide -s w -d "Format output for more than 80 columns" +complete -c objdump -l disassemble-zeroes -s z -d "Do not skip blocks of zeroes when disassembling" +complete -c objdump -l start-address -d "Only process data whose address is >= given address" -x +complete -c objdump -l stop-address -d "Only process data whose address is <= given address" -x +complete -c objdump -l prefix-addresses -d "Print complete address alongside disassembly" +complete -c objdump -l show-raw-insn -d "Display hex alongside symbolic disassembly" +complete -c objdump -l no-show-raw-insn -d "Don't display hex alongside symbolic disassembly" +complete -c objdump -l insn-width -x -d "Display specified number of bytes on single line for -d" +complete -c objdump -l adjust-vma -x -d "Add offset to all displayed section address" +complete -c objdump -l special-syms -d "Include special symbols in symbol dumps" +complete -c objdump -l prefix -x -d "Add given prefix to absolute paths for -S" +complete -c objdump -l prefix-strip -x -d "Strip initial directory names for -S" +complete -c objdump -l dwarf-depth -x -d "Do not display DIEs at given depth or greater" +complete -c objdump -l dwarf-start -x -d "Display DIEs starting with given number" +complete -c objdump -l dwarf-check -d "Make additional dwarf internal consistency checks" diff --git a/share/completions/pactl.fish b/share/completions/pactl.fish index 6a0a38348..ae6dec43b 100644 --- a/share/completions/pactl.fish +++ b/share/completions/pactl.fish @@ -23,7 +23,7 @@ function __fish_pa_print_type pactl list short $argv # Pa allows both a numerical index and a name pactl list short $argv | string replace -r '(\w+)\t.*' '$1' -end +end function __fish_pa_list_ports # Yes, this is localized diff --git a/share/completions/perl.fish b/share/completions/perl.fish index 284dc4ef1..83203585a 100644 --- a/share/completions/perl.fish +++ b/share/completions/perl.fish @@ -2,7 +2,7 @@ begin set -l unicode 'commandline | __fish_sgrep -qe "-[a-zA-Z]*C[a-zA-Z]*\$"' set -l noopt 'commandline | not __fish_sgrep -qe "-[a-zA-Z]*C[a-zA-Z]*\$"' set -l modules "(find (perl -lE'print for @INC') -name '*.pm' -printf '%P\n' ^/dev/null \ - | awk '{ gsub(\"/\", \"::\") } /[^-.]/' RS='\\\\\\\\.pm'\n | sort | uniq)" + | sed -e 's,/,::,g; s,\.pm$,,' | sort -u)" complete -c perl -s 0 -n $noopt --description 'Specify record separator' complete -c perl -s a -n $noopt --description 'Turn on autosplit mode' complete -c perl -s c -n $noopt --description 'Check syntax' diff --git a/share/completions/pv.fish b/share/completions/pv.fish new file mode 100644 index 000000000..6f91e45ac --- /dev/null +++ b/share/completions/pv.fish @@ -0,0 +1,37 @@ +# pv - Pipe Viewer - is a terminal-based tool for monitoring the progress of +# data through a pipeline. +# See: http://www.ivarch.com/programs/pv.shtml + +complete -c pv -l progress -s p -d 'Turn progress bar on' +complete -c pv -l timer -s t -d 'Show timer' +complete -c pv -l eta -s e -d 'Show estimated time left' +complete -c pv -l fineta -s I -d 'Show estimated time of arrival' +complete -c pv -l rate -s r -d 'Show rate counter' +complete -c pv -l average-rate -s a -d 'Show average rate' +complete -c pv -l bytes -s b -d 'Show total byte counter' +complete -c pv -l buffer-percent -s T -d 'Show transfer buffer percentage' +complete -c pv -l last-written -s A -d 'Show the last NUM bytes written' +complete -c pv -l format -s F -x -d 'Set output format' +complete -c pv -l numeric -s n -d 'Numeric output' +complete -c pv -l quiet -s q -d 'No output' +complete -c pv -l wait -s W -d 'Wait for first byte before showing progress' +complete -x -c pv -l delay-start -s D -d 'Wait given time (in secs) before showing progress' +complete -x -c pv -l size -s s -d 'Set total number of bytes to be transfered' +complete -c pv -l line-mode -s l -d 'Count lines instead of bytes' +complete -c pv -l null -s 0 -d 'Count null-terminated lines' +complete -x -c pv -l interval -s i -d 'Wait given time (in secs) between updates' +complete -x -c pv -l width -s w -d 'Set terminal width' +complete -x -c pv -l height -s H -d 'Set terminal height' +complete -x -c pv -l name -l N -d 'Prefix output with given name' +complete -c pv -l force -s f -d 'Force output' +complete -c pv -l cursor -s c -d 'Use cursor positioning escape sequence instead of \r' +complete -x -c pv -l rate-limit -s L -d 'Limit transfer rate' +complete -x -c pv -l buffer-size -s B -d 'Use transfer buffer size (in bytes)' +complete -c pv -l no-splice -s C -d 'Don\'t use slice' +complete -c pv -l skip-errors -s E -d 'Ignore read errors' +complete -c pv -l stop-at-size -s S -d 'Stop transfer after given number of bytes' +complete -x -c pv -l watchfd -s d -d 'Watch file given description from given process (PID:FD)' +complete -x -c pv -l remote -s R -d 'Change a running pv\'s options' -a '(__fish_complete_pids | string match \*\tpv\*)' +complete -x -c pv -l pidfile -s P -d 'Save pv PID in given file' +complete -c pv -l help -s h -d 'Show help and exit' +complete -c pv -l version -s V -d 'Show version and exit' diff --git a/share/completions/pygmentize.fish b/share/completions/pygmentize.fish index aefa7bc65..4f4cb6042 100644 --- a/share/completions/pygmentize.fish +++ b/share/completions/pygmentize.fish @@ -1,8 +1,12 @@ function __fish_print_pygmentize - set -l lines (pygmentize -L $argv[1] | string match -r '^(?:\* | ).*(?:)$' | string replace -r '\* (.*):$' '$1' | string replace -r '^(.*).$' '$1' | string trim) + set -l lines (pygmentize -L $argv[1] | string match -r '^(?:\* | ).*(?:)$' | string replace -r '\* (.*):$' '$1' | string replace -r '^(.*)\.$' '$1' | string trim) while set -q lines[2] - printf '%s\t%s\n' $lines[1] $lines[2] + set -l names (string split ", " $lines[1]) + for name in $names + printf '%s\t%s\n' $name $lines[2] + end + set -e lines[1] set -e lines[1] end diff --git a/share/completions/rustc.fish b/share/completions/rustc.fish index 8dadcaf67..090be9db8 100644 --- a/share/completions/rustc.fish +++ b/share/completions/rustc.fish @@ -2,7 +2,7 @@ # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 complete -e -c rustc -complete -c rustc -s h -l help +complete -c rustc -s h -l help complete -c rustc -x -l cfg complete -c rustc -r -s L -a 'dylib= static= framework=' diff --git a/share/completions/sass-convert.fish b/share/completions/sass-convert.fish index db9942434..6f45e7154 100644 --- a/share/completions/sass-convert.fish +++ b/share/completions/sass-convert.fish @@ -9,11 +9,11 @@ # -F, --from FORMAT The format to convert from. Can be css, scss, sass. # By default, this is inferred from the input filename. # If there is none, defaults to css. -complete -c sass-convert -s F -l from -x -a "css scss sass" -A -d "The format to convert from. Can be css, scss, sass. By default, this is inferred from the input filename. If there is none, defaults to css." +complete -c sass-convert -s F -l from -x -a "css scss sass" -d "The format to convert from. Can be css, scss, sass. By default, this is inferred from the input filename. If there is none, defaults to css." # -T, --to FORMAT The format to convert to. Can be scss or sass. # By default, this is inferred from the output filename. # If there is none, defaults to sass. -complete -c sass-convert -s T -l to -x -a "scss sass" -A -d "The format to convert to. Can be scss or sass. By default, this is inferred from the output filename. If there is none, defaults to sass." +complete -c sass-convert -s T -l to -x -a "scss sass" -d "The format to convert to. Can be scss or sass. By default, this is inferred from the output filename. If there is none, defaults to sass." # -i, --in-place Convert a file to its own syntax. # This can be used to update some deprecated syntax. complete -c sass-convert -s i -l in-place -d "Convert a file to its own syntax. This can be used to update some deprecated syntax." diff --git a/share/completions/sass.fish b/share/completions/sass.fish index 551ee3683..95a2c1441 100644 --- a/share/completions/sass.fish +++ b/share/completions/sass.fish @@ -11,7 +11,7 @@ complete -c sass -s r -l require -x -d "Require a Ruby library before running Sa # --compass Make Compass imports available and load project configuration. complete -c sass -l compass -d "Make Compass imports available and load project configuration." # -t, --style NAME Output style. Can be nested (default), compact, compressed, or expanded. -complete -c sass -s t -l style -x -A -a "nested compact compressed expanded" -d "Output style. Can be nested (default), compact, compressed, or expanded." +complete -c sass -s t -l style -x -a "nested compact compressed expanded" -d "Output style. Can be nested (default), compact, compressed, or expanded." # -?, -h, --help Show this help message. complete -c sass -s '?' -s h -l help -f -d "Show help message." # -v, --version Print the Sass version. @@ -44,7 +44,7 @@ complete -c sass -l scss -d "Use the CSS-superset SCSS syntax." # file: always absolute file URIs # inline: include the source text in the sourcemap # none: no sourcemaps -complete -c sass -l sourcemap -x -A -a "auto\t'(default) relative paths where possible, file URIs elsewhere' +complete -c sass -l sourcemap -x -a "auto\t'(default) relative paths where possible, file URIs elsewhere' sfile\t'always absolute file URIs' inline\t'include the source text in the sourcemap' none\t'no sourcemaps'" -d "How to link generated output to the source files." diff --git a/share/completions/scss.fish b/share/completions/scss.fish index 4fb3e3293..f0d8f9ed9 100644 --- a/share/completions/scss.fish +++ b/share/completions/scss.fish @@ -11,7 +11,7 @@ complete -c scss -s r -l require -r -d "Require a Ruby library before running Sa # --compass Make Compass imports available and load project configuration. complete -c scss -l compass -d "Make Compass imports available and load project configuration." # -t, --style NAME Output style. Can be nested (default), compact, compressed, or expanded. -complete -c scss -s t -l style -x -a "nested compact compressed expanded" -A -d "Output style. Can be nested (default), compact, compressed, or expanded." +complete -c scss -s t -l style -x -a "nested compact compressed expanded" -d "Output style. Can be nested (default), compact, compressed, or expanded." # -?, -h, --help Show this help message. complete -c scss -s '?' -s h -l help -f -d "Show help message." # -v, --version Print the Sass version. @@ -44,7 +44,7 @@ complete -c scss -l sass -d "Use the indented Sass syntax." # file: always absolute file URIs # inline: include the source text in the sourcemap # none: no sourcemaps -complete -c scss -l sourcemap -x -A -d "How to link generated output to the source files." -a \ +complete -c scss -l sourcemap -x -d "How to link generated output to the source files." -a \ "auto\t'(default) relative paths where possible, file URIs elsewhere' file\t'always absolute file URIs' inline\t'include the source text in the sourcemap' diff --git a/share/completions/set.fish b/share/completions/set.fish index cadbec0f1..4184d297d 100644 --- a/share/completions/set.fish +++ b/share/completions/set.fish @@ -78,5 +78,3 @@ complete -c set -n '__fish_set_is_color' -s o -l bold --description 'Make font b complete -c set -n '__fish_is_first_token' -x -a '$__fish_locale_vars' -d 'Locale variable' complete -c set -n '__fish_set_is_locale' -x -a '(locale -a)' -d (_ Locale) complete -c set -s L -l long -d 'Do not truncate long lines' - -complete -c set -u diff --git a/share/completions/set_color.fish b/share/completions/set_color.fish index 55ea4b1e7..752d07d0c 100644 --- a/share/completions/set_color.fish +++ b/share/completions/set_color.fish @@ -1,6 +1,9 @@ complete -c set_color -x --description "Color" -a '(set_color --print-colors)' complete -c set_color -s b -l background -x -a '(set_color --print-colors)' --description "Change background color" complete -c set_color -s o -l bold --description 'Make font bold' +complete -c set_color -s i -l italics --description 'Italicise' +complete -c set_color -s d -l dim --description 'Dim text' +complete -c set_color -s r -l reverse --description 'Reverse color text' complete -c set_color -s u -l underline --description 'Underline text' complete -c set_color -s h -l help --description 'Display help and exit' complete -c set_color -s c -l print-colors --description 'Print a list of all accepted color names' diff --git a/share/completions/setsid.fish b/share/completions/setsid.fish new file mode 100644 index 000000000..a380787f4 --- /dev/null +++ b/share/completions/setsid.fish @@ -0,0 +1,9 @@ +# setsid is a tool to run a program in a new session. +# It is part of the util-linux package. +# See: https://www.kernel.org/pub/linux/utils/util-linux + +complete -c setsid -x -d 'Command to run' -a '(__fish_complete_subcommand)' +complete -c setsid -n '__fish_no_arguments' -l ctty -s c -d 'Set controlling terminal to current one' +complete -c setsid -n '__fish_no_arguments' -l wait -s w -d 'Wait until program ends and return its exit value' +complete -c setsid -n '__fish_no_arguments' -l version -s V -d 'Display version and exit' +complete -c setsid -n '__fish_no_arguments' -l help -s h -d 'Display help and exit' diff --git a/share/completions/setxkbmap.fish b/share/completions/setxkbmap.fish index 71aab63e8..6a557fb70 100644 --- a/share/completions/setxkbmap.fish +++ b/share/completions/setxkbmap.fish @@ -2,23 +2,23 @@ set -l filter '"s/\S+\s\S+\s(.+)\((.+)\)/\1\t\2/;"' complete -c setxkbmap -o '?' -o help -d 'Print this message' -complete -c setxkbmap -o compat -d 'Specifies compatibility map component name' -xa "(cat /usr/share/X11/xkb/compat.dir | sed -r $filter)" +complete -c setxkbmap -o compat -d 'Specifies compatibility map component name' -xa "(sed -r $filter /usr/share/X11/xkb/compat.dir)" complete -c setxkbmap -o config -d 'Specifies configuration file to use' -r complete -c setxkbmap -o device -d 'Specifies the device ID to use' -x complete -c setxkbmap -o display -d 'Specifies display to use' -x -complete -c setxkbmap -o geometry -d 'Specifies geometry component name' -xa "(cat /usr/share/X11/xkb/geometry.dir | sed -r $filter)" +complete -c setxkbmap -o geometry -d 'Specifies geometry component name' -xa "(sed -r $filter /usr/share/X11/xkb/geometry.dir)" complete -c setxkbmap -o I -d 'Add to list of directories to be used' -xa '(__fish_complete_directories)' -complete -c setxkbmap -o keycodes -d 'Specifies keycodes component name' -xa "(cat /usr/share/X11/xkb/keycodes.dir | sed -r $filter)" -complete -c setxkbmap -o keymap -d 'Specifies name of keymap to load' -xa "(cat /usr/share/X11/xkb/keymap.dir | sed -r $filter)" +complete -c setxkbmap -o keycodes -d 'Specifies keycodes component name' -xa "(sed -r $filter /usr/share/X11/xkb/keycodes.dir)" +complete -c setxkbmap -o keymap -d 'Specifies name of keymap to load' -xa "(sed -r $filter /usr/share/X11/xkb/keymap.dir)" complete -c setxkbmap -o layout -d 'Specifies layout used to choose component names' -xa "(__fish_complete_setxkbmap layout)" complete -c setxkbmap -o model -d 'Specifies model used to choose component names' -xa "(__fish_complete_setxkbmap model)" complete -c setxkbmap -o option -d 'Adds an option used to choose component names' -xa "(__fish_complete_list , '__fish_complete_setxkbmap option')" complete -c setxkbmap -o print -d 'Print a complete xkb_keymap description and exit' complete -c setxkbmap -o query -d 'Print the current layout settings and exit' complete -c setxkbmap -o rules -d 'Name of rules file to use' -x -complete -c setxkbmap -o symbols -d 'Specifies symbols component name' -xa "(cat /usr/share/X11/xkb/symbols.dir | sed -r $filter)" +complete -c setxkbmap -o symbols -d 'Specifies symbols component name' -xa "(sed -r $filter /usr/share/X11/xkb/symbols.dir)" complete -c setxkbmap -o synch -d 'Synchronize request w/X server' -complete -c setxkbmap -o types -d 'Specifies types component name' -xa "(cat /usr/share/X11/xkb/types.dir | sed -r $filter)" +complete -c setxkbmap -o types -d 'Specifies types component name' -xa "(sed -r $filter /usr/share/X11/xkb/types.dir)" complete -c setxkbmap -o v -o verbose -d 'Sets verbosity (1..10). Higher values yield more messages' -xa '(seq 1 10)' complete -c setxkbmap -o variant -d 'Specifies layout variant used to choose component names' -xa "(__fish_complete_setxkbmap variant)" diff --git a/share/completions/ssh.fish b/share/completions/ssh.fish index 6131c2545..691302982 100644 --- a/share/completions/ssh.fish +++ b/share/completions/ssh.fish @@ -23,7 +23,8 @@ complete -c ssh -s a --description "Disables forwarding of the authentication ag complete -c ssh -s A --description "Enables forwarding of the authentication agent" complete -x -c ssh -s b --description "Interface to transmit from" -a " ( - cat /proc/net/arp ^/dev/null| string match -r -v '^IP'|cut -d ' ' -f 1 ^/dev/null + # TODO /proc/net/arp is not POSIX compliant + cut -d ' ' -f 1 /proc/net/arp ^/dev/null | string match -r -v '^IP' ) " @@ -46,6 +47,3 @@ complete -c ssh -s X --description "Enable X11 forwarding" complete -c ssh -s L --description "Locally forwarded ports" complete -c ssh -s R --description "Remotely forwarded ports" complete -c ssh -s D --description "Dynamic port forwarding" - -# Since ssh runs subcommands, it can accept any switches -complete -c ssh -u diff --git a/share/completions/stack.fish b/share/completions/stack.fish index 70b0ca270..b67fac8d0 100644 --- a/share/completions/stack.fish +++ b/share/completions/stack.fish @@ -1,6 +1,6 @@ complete -c stack -f -# Completion for 'stack' haskell build tool (http://docs.haskellstack.org/en/stable/index.html) +# Completion for 'stack' haskell build tool (http://haskellstack.org) # (Handmade) generated from version 1.0.0 # diff --git a/share/completions/sudo.fish b/share/completions/sudo.fish index afe1380f8..6d5260a78 100644 --- a/share/completions/sudo.fish +++ b/share/completions/sudo.fish @@ -24,5 +24,3 @@ complete -c sudo -s u -a "(__fish_complete_users)" -x -d "Run command as user" complete -c sudo -s v -n "__fish_no_arguments" -d "Validate the credentials, extending timeout" complete -c sudo -d "Command to run" -x -a "(__fish_complete_subcommand_root -u -g)" -# Since sudo runs subcommands, it can accept any switches -complete -c sudo -u diff --git a/share/completions/sysctl.fish b/share/completions/sysctl.fish index 758d19a1b..3fc7c91c5 100644 --- a/share/completions/sysctl.fish +++ b/share/completions/sysctl.fish @@ -3,7 +3,7 @@ if type -q -f sysctl if sysctl -h >/dev/null ^/dev/null # Print sysctl keys and values, separated by a tab function __fish_sysctl_values - sysctl -a ^/dev/null | string replace -a " = " "\t" + sysctl -a ^/dev/null | string replace -a " = " \t end complete -c sysctl -a '(__fish_sysctl_values)' -f @@ -32,7 +32,7 @@ if type -q -f sysctl else # OSX sysctl function __fish_sysctl_values - sysctl -a ^/dev/null | string replace -a ":" "\t" + sysctl -a ^/dev/null | string replace -a ":" \t end complete -c sysctl -a '(__fish_sysctl_values)' -f diff --git a/share/completions/systemd-nspawn.fish b/share/completions/systemd-nspawn.fish index f8002a700..773d39b78 100644 --- a/share/completions/systemd-nspawn.fish +++ b/share/completions/systemd-nspawn.fish @@ -21,7 +21,7 @@ complete -c systemd-nspawn -s L -l selinux-apifs-context -d 'Sets the SELinux se complete -c systemd-nspawn -l capability -d 'Grant additional capabilities to the container' complete -c systemd-nspawn -l drop-capability -d 'Drop capabilities from the container' complete -c systemd-nspawn -l kill-signal -d "Signal to send to the container's PID1 when nspawn receives SIGTERM" -complete -c systemd-nspawn -l link-journal -d 'Set container journal visibility' -a 'no host try-host guest try-guest auto' -r -A +complete -c systemd-nspawn -l link-journal -d 'Set container journal visibility' -a 'no host try-host guest try-guest auto' -r complete -c systemd-nspawn -s j -d 'Equivalent to --link-journal=try-guest' complete -c systemd-nspawn -l read-only -d 'Mount the root file system read-only for the container' complete -c systemd-nspawn -l bind -l bind-ro -d 'Bind mount a file or directory from the host in the container' -r diff --git a/share/completions/tar.fish b/share/completions/tar.fish index 369b172ba..3a5e4dfd0 100644 --- a/share/completions/tar.fish +++ b/share/completions/tar.fish @@ -63,4 +63,4 @@ complete -c tar -l uncompress --description "Filter through compress" complete -c tar -s z -l gzip --description "Filter through gzip" complete -c tar -l gunzip --description "Filter through gzip" complete -c tar -l use-compress-program -r --description "Filter through specified program" - +complete -c tar -s J -l xz --description "Filter through xz" diff --git a/share/completions/test.fish b/share/completions/test.fish index 90de3e2f2..64ba62851 100644 --- a/share/completions/test.fish +++ b/share/completions/test.fish @@ -1,9 +1,9 @@ complete -c test -l help --description "Display help and exit" -complete -c test -l version --description "Display version and exit" +#complete -c test -l version --description "Display version and exit" complete -c test -a ! --description "Negate expression" -complete -c test -s a --description "Logical and" -complete -c test -s o --description "Logical or" +complete -c test -s a --description "Logical AND" +complete -c test -s o --description "Logical OR" complete -c test -s n --description "String length is non-zero" complete -c test -s z --description "String length is zero" complete -c test -a = --description "Strings are equal" @@ -14,23 +14,24 @@ complete -c test -o gt --description "Left integer larger than right integer" complete -c test -o le --description "Left integer less than or equal to right integer" complete -c test -o lt --description "Left integer less than right integer" complete -c test -o ne --description "Left integer not equal to right integer" -complete -c test -o ef --description "Left file equal to right file" -complete -c test -o nt --description "Left file newer than right file" -complete -c test -o ot --description "Left file older than right file" +# builtin test does not do these +#complete -c test -o ef --description "Left file equal to right file" +#complete -c test -o nt --description "Left file newer than right file" +#complete -c test -o ot --description "Left file older than right file" complete -c test -s b --description "File is block device" complete -c test -s c --description "File is character device" complete -c test -s d --description "File is directory" complete -c test -s e --description "File exists" complete -c test -s f --description "File is regular" complete -c test -s g --description "File is set-group-ID" -complete -c test -s G --description "File owned by effective group ID" -complete -c test -s L --description "File is symlink" -complete -c test -s O --description "File owned by effective user ID" -complete -c test -s p --description "File is named pipe" +complete -c test -s G --description "File owned by our effective group ID" +complete -c test -s L --description "File is a symlink" +complete -c test -s O --description "File owned by our effective user ID" +complete -c test -s p --description "File is a named pipe" complete -c test -s r --description "File is readable" complete -c test -s s --description "File size is non-zero" -complete -c test -s S --description "File is socket" -complete -c test -s t --description "FD is terminal" +complete -c test -s S --description "File is a socket" +complete -c test -s t --description "FD is a terminal" complete -c test -s u --description "File set-user-ID bit is set" complete -c test -s w --description "File is writable" complete -c test -s x --description "File is executable" diff --git a/share/completions/time.fish b/share/completions/time.fish index f072f0b0c..bb496322b 100644 --- a/share/completions/time.fish +++ b/share/completions/time.fish @@ -8,6 +8,3 @@ complete -c time -s a -l append -n "__fish_no_arguments" --description "(Used to complete -c time -s v -l verbose -n "__fish_no_arguments" --description "Verbose mode" complete -c time -l help -n "__fish_no_arguments" --description "Display help and exit" complete -c time -s V -l version -n "__fish_no_arguments" --description "Display version and exit" - -# Since time runs subcommands, it can accept any switches -complete -c time -u diff --git a/share/completions/timedatectl.fish b/share/completions/timedatectl.fish index ba67e9934..eff6cee61 100644 --- a/share/completions/timedatectl.fish +++ b/share/completions/timedatectl.fish @@ -1,4 +1,4 @@ -set -l commands status set-time{,zone} list-timezones set-local-rtc set-ntp +set -l commands status set-time{,zone} list-timezones set-local-rtc set-ntp complete -c timedatectl -f complete -c timedatectl -n "not __fish_seen_subcommand_from $commands" -a "status" diff --git a/share/completions/umount.fish b/share/completions/umount.fish index 85929fb82..7b164a071 100644 --- a/share/completions/umount.fish +++ b/share/completions/umount.fish @@ -16,7 +16,7 @@ complete -c umount -s d --description "In case the unmounted device was a loop d complete -c umount -s i --description "Don't call the /sbin/umount. helper even if it exists" complete -c umount -s a --description "Unmount all of the file systems described in /etc/mtab" complete -c umount -s t --description "Actions should only be taken on file systems of the specified type" -xa "(__fish_print_filesystems)" -complete -c umount -s O --description "Actions should only be taken on file systems with the specified options in /etc/fstab" -xa '(cat /etc/mtab | cut -d " " -f 4)\t"Mount option"' +complete -c umount -s O --description "Actions should only be taken on file systems with the specified options in /etc/fstab" -xa '(cut -d " " -f 4 /etc/mtab)\t"Mount option"' complete -c umount -s f --description "Force unmount (in case of an unreachable NFS system)" complete -c umount -s l --description "Detach the filesystem from the filesystem hierarchy now, and cleanup all references to the filesystem as soon as it is not busy" diff --git a/share/completions/useradd.fish b/share/completions/useradd.fish index 37c9a7290..0719d6196 100644 --- a/share/completions/useradd.fish +++ b/share/completions/useradd.fish @@ -7,7 +7,7 @@ complete -c useradd -s c -l comment --description 'A comment about this user' -r complete -c useradd -s d -l home --description 'Home directory for the new user' -x -a '(__fish_complete_directories)' -complete -c useradd -s G -l groups --description 'Supplementary groups' -xa '(__fish_append , (cat /etc/group|cut -d : -f 1))' +complete -c useradd -s G -l groups --description 'Supplementary groups' -xa '(__fish_append , (cut -d : -f 1 /etc/group))' complete -c useradd -s h -l help --description 'Display help message and exit' complete -c useradd -s m -l create-home --description 'The user\'s home directory will be created if it does not exist' complete -c useradd -s n --description 'A group having the same name as the user being added to the system will be created by default (when -g is not specified)' diff --git a/share/completions/usermod.fish b/share/completions/usermod.fish new file mode 100644 index 000000000..c28d01d7a --- /dev/null +++ b/share/completions/usermod.fish @@ -0,0 +1,22 @@ +complete -c usermod -a "(__fish_complete_users)" -f +complete -c usermod -s a -l append -d 'Append groups (use with -G)' -f -a "(__fish_complete_groups)" +complete -c usermod -s c -l comment -d "Change user's password file comment" -f +complete -c usermod -s d -l home -d "Change user's login directory" +complete -c usermod -s e -l expiredate -d "Date on which the user account will be disabled" -f +complete -c usermod -s f -l inactive -d "Number of days after a password expires until the account is locked" -f +complete -c usermod -s g -l gid -d "Group name or number of the user's new initial login group" -f +complete -c usermod -s G -l groups -d "List of groups which the user is also a member of" -f -a "(__fish_complete_groups)" +complete -c usermod -s l -l login -d "Change user's name" -f +complete -c usermod -s L -l lock -d "Lock user's password" -f +complete -c usermod -s m -l move-home -d "Move the content of the user's home directory to the new location" -f +complete -c usermod -s o -l non-unique -d "Allow non-unique UID" -f +complete -c usermod -s p -l password -d "The encrypted password, as returned by crypt(3)" -f +complete -c usermod -s R -l root -d "Apply changes in this directory" -f +complete -c usermod -s s -l shell -d "The name of the user's new login shell" -f +complete -c usermod -s u -l uid -d "The new numerical value of the user's ID" -f +complete -c usermod -s U -l unlock -d "Unlock a users password" -f +complete -c usermod -s v -l add-sub-uids -d "Add a range of subordinate uids to the user's account" -f +complete -c usermod -s V -l del-sub-uids -d "Remove a range of subordinate uids from the user's account" -f +complete -c usermod -s w -l add-sub-gids -d "Add a range of subordinate gids to the user's account" -f +complete -c usermod -s W -l del-sub-gids -d "Remove a range of subordinate gids from the user's account" -f +complete -c usermod -s Z -l selinux-user -d "The new SELinux user for the user's login" -f diff --git a/share/completions/vim-addons.fish b/share/completions/vim-addons.fish index 67d5f48c7..0b5736305 100644 --- a/share/completions/vim-addons.fish +++ b/share/completions/vim-addons.fish @@ -3,7 +3,7 @@ # ========================= # # Adrien Grellier -# +# function __fish_vim-addons_subcommand --description 'Test if vim-addons has yet to be given the subcommand' for i in (commandline -opc) diff --git a/share/completions/xinput.fish b/share/completions/xinput.fish new file mode 100644 index 000000000..eadf40ae2 --- /dev/null +++ b/share/completions/xinput.fish @@ -0,0 +1,11 @@ +# xinput, a tool for managing X11 input devices +set -l cmds version list get-feedbacks set-pointer set-mode set-ptr-feedback set-integer-feedback set-button-map query-state list-props set-int-prop set-float-prop set-prop watch-props delete-prop test test-xi2 create-master remove-master reattach float set-cp map-to-output enable disable + +function __fish_xinput_devices + # Yeah, this includes a "↳" char + # There's either this or printing only name or id, not both + xinput list --short | string replace -r '^[\W↳]*([\w/ ]+)\s+id=([0-9]+).*$' '$2\t$1' +end + +complete -c xinput -f -n "not __fish_seen_subcommand_from $cmds" -a "$cmds" +complete -c xinput -f -n "__fish_seen_subcommand_from list get-feedbacks set-pointer set-mode set-ptr-feedback set-integer-feedback set-button-map query-state list-props set-int-prop set-float-prop set-prop watch-props" -a "(__fish_xinput_devices)" diff --git a/share/completions/xprop.fish b/share/completions/xprop.fish index da56ea609..25bc299c3 100644 --- a/share/completions/xprop.fish +++ b/share/completions/xprop.fish @@ -1,3 +1,7 @@ +function __fish_xprop_list_properties + # TODO search commandline for a target window ("-root" or "-name foo") + xprop -root | cut -d'(' -f 1 +end complete -c xprop -o help --description "Display help and exit" complete -c xprop -o grammar --description "Display grammar and exit" @@ -10,23 +14,9 @@ complete -c xprop -o len -x --description "Maximum display length" complete -c xprop -o notype --description "Do not show property type" complete -c xprop -o fs -r --description "Set format file" complete -c xprop -o frame --description "Select a window by clicking on its frame" -complete -c xprop -o remove --description "Remove property" -x -a " -( - xprop -root -notype|cut -d ' ' -f 1|cut -d \t -f 1 -) -" - -complete -c xprop -o set --description "Set property" -x -a " -( - xprop -root -notype|cut -d ' ' -f 1|cut -d \t -f 1 -) -" - +complete -c xprop -o remove --description "Remove property" -x -a "( __fish_xprop_list_properties)" +complete -c xprop -o set --description "Set property" -x -a " (__fish_xprop_list_properties)" complete -c xprop -o spy --description "Examine property updates forever" complete -c xprop -o f --description "Set format" -complete -c xprop -d Property -x -a " -( - xprop -root -notype|cut -d ' ' -f 1|cut -d \t -f 1 -) -" +complete -c xprop -d Property -x -a "( __fish_xprop_list_properties)" diff --git a/share/completions/yast2.fish b/share/completions/yast2.fish index ba22a6da8..4b1c80125 100644 --- a/share/completions/yast2.fish +++ b/share/completions/yast2.fish @@ -1,6 +1,6 @@ -complete -f -c yast2 -a '(yast2 -l)' -d 'Module' +complete -f -c yast2 -a '(yast2 -l)' -d 'Module' -complete -f -c yast2 -s h -l help -d 'Show help' +complete -f -c yast2 -s h -l help -d 'Show help' complete -f -c yast2 -s l -l list -d 'List all available modules' complete -f -c yast2 -l qt -d 'Use the QT graphical user interface' complete -f -c yast2 -l gtk -d 'Use the GTK graphical user interface' diff --git a/share/config.fish b/share/config.fish index fcedae39a..cb153bbe3 100644 --- a/share/config.fish +++ b/share/config.fish @@ -10,51 +10,52 @@ set -g IFS \n\ \t # Create the default command_not_found handler # function __fish_default_command_not_found_handler - echo "fish: Unknown command '$argv'" >&2 + echo "fish: Unknown command '$argv'" >&2 end set -g version $FISH_VERSION if status --is-interactive - # The user has seemingly explicitly launched an old fish with too-new scripts installed. - if not contains -- "string" (builtin -n) - set -g __is_launched_without_string 1 - # XXX nostring - fix old fish binaries with no `string' builtin. - # When executed on fish 2.2.0, the `else' block after this would - # force on 24-bit mode due to changes to in test behavior. - # These "XXX nostring" hacks were added for 2.3.1 - set_color --bold - echo "You appear to be trying to launch an old fish binary with newer scripts " - echo "installed into" (set_color --underline)"$__fish_datadir" - set_color normal - echo -e "\nThis is an unsupported configuration.\n" - set_color yellow - echo "You may need to uninstall and reinstall fish!" - set_color normal - # Remove this code when we've made it safer to upgrade fish. - else - # Enable truecolor/24-bit support for select terminals - # Ignore Neovim (in 0.1.4 at least), Screen and emacs' ansi-term as they swallow the sequences, rendering the text white. - if not set -q NVIM_LISTEN_ADDRESS - and not set -q STY - and not string match -q -- 'eterm*' $TERM - and begin - set -q KONSOLE_PROFILE_NAME # KDE's konsole - or string match -q -- "*:*" $ITERM_SESSION_ID # Supporting versions of iTerm2 will include a colon here - or string match -q -- "st-*" $TERM # suckless' st - or test "$VTE_VERSION" -ge 3600 # Should be all gtk3-vte-based terms after version 3.6.0.0 - or test "$COLORTERM" = truecolor -o "$COLORTERM" = 24bit # slang expects this - end - # Only set it if it isn't to allow override by setting to 0 - set -q fish_term24bit; or set -g fish_term24bit 1 - end - end + # The user has seemingly explicitly launched an old fish with too-new scripts installed. + if not contains -- "string" (builtin -n) + set -g __is_launched_without_string 1 + # XXX nostring - fix old fish binaries with no `string' builtin. + # When executed on fish 2.2.0, the `else' block after this would + # force on 24-bit mode due to changes to in test behavior. + # These "XXX nostring" hacks were added for 2.3.1 + set_color --bold + echo "You appear to be trying to launch an old fish binary with newer scripts " + echo "installed into" (set_color --underline)"$__fish_datadir" + set_color normal + echo -e "\nThis is an unsupported configuration.\n" + set_color yellow + echo "You may need to uninstall and reinstall fish!" + set_color normal + # Remove this code when we've made it safer to upgrade fish. + else + # Enable truecolor/24-bit support for select terminals + # Ignore Neovim (in 0.1.4 at least), Screen and emacs' ansi-term as they swallow the sequences, rendering the text white. + if not set -q NVIM_LISTEN_ADDRESS + and not set -q STY + and not string match -q -- 'eterm*' $TERM + and begin + set -q KONSOLE_PROFILE_NAME # KDE's konsole + or string match -q -- "*:*" $ITERM_SESSION_ID # Supporting versions of iTerm2 will include a colon here + or string match -q -- "st-*" $TERM # suckless' st + or test -n "$VTE_VERSION" -a "$VTE_VERSION" -ge 3600 # Should be all gtk3-vte-based terms after version 3.6.0.0 + or test "$COLORTERM" = truecolor -o "$COLORTERM" = 24bit # slang expects this + end + # Only set it if it isn't to allow override by setting to 0 + set -q fish_term24bit + or set -g fish_term24bit 1 + end + end else - # Hook up the default as the principal command_not_found handler - # in case we are not interactive - function __fish_command_not_found_handler --on-event fish_command_not_found - __fish_default_command_not_found_handler $argv - end + # Hook up the default as the principal command_not_found handler + # in case we are not interactive + function __fish_command_not_found_handler --on-event fish_command_not_found + __fish_default_command_not_found_handler $argv + end end # @@ -65,13 +66,13 @@ end set -l configdir ~/.config if set -q XDG_CONFIG_HOME - set configdir $XDG_CONFIG_HOME + set configdir $XDG_CONFIG_HOME end set -l userdatadir ~/.local/share if set -q XDG_DATA_HOME - set userdatadir $XDG_DATA_HOME + set userdatadir $XDG_DATA_HOME end # __fish_datadir, __fish_sysconfdir, __fish_help_dir, __fish_bin_dir @@ -90,19 +91,19 @@ end # default functions/completions are included in the respective path. if not set -q fish_function_path - set fish_function_path $configdir/fish/functions $__fish_sysconfdir/functions $__extra_functionsdir $__fish_datadir/functions + set fish_function_path $configdir/fish/functions $__fish_sysconfdir/functions $__extra_functionsdir $__fish_datadir/functions end if not contains -- $__fish_datadir/functions $fish_function_path - set fish_function_path $fish_function_path $__fish_datadir/functions + set fish_function_path $fish_function_path $__fish_datadir/functions end if not set -q fish_complete_path - set fish_complete_path $configdir/fish/completions $__fish_sysconfdir/completions $__extra_completionsdir $__fish_datadir/completions $userdatadir/fish/generated_completions + set fish_complete_path $configdir/fish/completions $__fish_sysconfdir/completions $__extra_completionsdir $__fish_datadir/completions $userdatadir/fish/generated_completions end if not contains -- $__fish_datadir/completions $fish_complete_path - set fish_complete_path $fish_complete_path $__fish_datadir/completions + set fish_complete_path $fish_complete_path $__fish_datadir/completions end # @@ -114,53 +115,82 @@ end # if test -d /usr/xpg4/bin - if not contains -- /usr/xpg4/bin $PATH - set PATH /usr/xpg4/bin $PATH - end + if not contains -- /usr/xpg4/bin $PATH + set PATH /usr/xpg4/bin $PATH + end end # OS X-ism: Load the path files out of /etc/paths and /etc/paths.d/* set -g __fish_tmp_path $PATH function __fish_load_path_helper_paths - # We want to rearrange the path to reflect this order. Delete that path component if it exists and then prepend it. - # Since we are prepending but want to preserve the order of the input file, we reverse the array, append, and then reverse it again - set __fish_tmp_path $__fish_tmp_path[-1..1] - while read -l new_path_comp - if test -d $new_path_comp - set -l where (contains -i -- $new_path_comp $__fish_tmp_path) - and set -e __fish_tmp_path[$where] - set __fish_tmp_path $new_path_comp $__fish_tmp_path - end - end - set __fish_tmp_path $__fish_tmp_path[-1..1] + # We want to rearrange the path to reflect this order. Delete that path component if it exists and then prepend it. + # Since we are prepending but want to preserve the order of the input file, we reverse the array, append, and then reverse it again + set __fish_tmp_path $__fish_tmp_path[-1..1] + while read -l new_path_comp + if test -d $new_path_comp + set -l where (contains -i -- $new_path_comp $__fish_tmp_path) + and set -e __fish_tmp_path[$where] + set __fish_tmp_path $new_path_comp $__fish_tmp_path + end + end + set __fish_tmp_path $__fish_tmp_path[-1..1] +end +test -r /etc/paths +and __fish_load_path_helper_paths &0 >/dev/null - end - echo "source: '.' command is deprecated, and doesn't work with STDIN anymore. Did you mean 'source' or './'?" >&2 - return 1 - else - source $argv - end + if begin + test (count $argv) -eq 0 + # Uses tty directly, as isatty depends on "." + and tty 0>&0 >/dev/null + end + echo "source: '.' command is deprecated, and doesn't work with STDIN anymore. Did you mean 'source' or './'?" >&2 + return 1 + else + source $argv + end end # Set the locale if it isn't explicitly set. Allowing the lack of locale env vars to imply the @@ -204,23 +234,25 @@ __fish_set_locale # Implement precedence (User > Admin > Extra (e.g. vendors) > Fish) by basically doing "basename" set -l sourcelist for file in $configdir/fish/conf.d/*.fish $__fish_sysconfdir/conf.d/*.fish $__extra_confdir/*.fish - set -l basename (string replace -r '^.*/' '' -- $file) - contains -- $basename $sourcelist; and continue - set sourcelist $sourcelist $basename - # Also skip non-files or unreadable files - # This allows one to use e.g. symlinks to /dev/null to "mask" something (like in systemd) - [ -f $file -a -r $file ]; and source $file + set -l basename (string replace -r '^.*/' '' -- $file) + contains -- $basename $sourcelist + and continue + set sourcelist $sourcelist $basename + # Also skip non-files or unreadable files + # This allows one to use e.g. symlinks to /dev/null to "mask" something (like in systemd) + [ -f $file -a -r $file ] + and source $file end # Upgrade pre-existing abbreviations from the old "key=value" to the new "key value" syntax # This needs to be in share/config.fish because __fish_config_interactive is called after 2sourcing config.fish, which might contain abbr calls if not set -q __fish_init_2_3_0 - set -l fab - for abb in $fish_user_abbreviations - set fab $fab (string replace -r '^([^ =]+)=(.*)$' '$1 $2' -- $abb) - end - set fish_user_abbreviations $fab - set -U __fish_init_2_3_0 + set -l fab + for abb in $fish_user_abbreviations + set fab $fab (string replace -r '^([^ =]+)=(.*)$' '$1 $2' -- $abb) + end + set fish_user_abbreviations $fab + set -U __fish_init_2_3_0 end # @@ -230,15 +262,15 @@ end if status --is-login - # - # Put linux consoles in unicode mode. - # + # + # Put linux consoles in unicode mode. + # - if test "$TERM" = linux - if string match -qir '\.UTF' -- $LANG - if command -s unicode_start >/dev/null - unicode_start - end - end - end + if test "$TERM" = linux + if string match -qir '\.UTF' -- $LANG + if command -s unicode_start >/dev/null + unicode_start + end + end + end end diff --git a/share/functions/N_.fish b/share/functions/N_.fish index 74c39b4af..9b05f12ff 100644 --- a/share/functions/N_.fish +++ b/share/functions/N_.fish @@ -1,6 +1,6 @@ function N_ --description "No-op" - printf "%s" $argv + printf "%s" $argv end diff --git a/share/functions/__fish_append.fish b/share/functions/__fish_append.fish index 43caa26c0..d1b6ece1e 100644 --- a/share/functions/__fish_append.fish +++ b/share/functions/__fish_append.fish @@ -1,7 +1,7 @@ function __fish_append -d "Internal completion function for appending string to the commandline" --argument separator - set -e argv[1] - set str (commandline -tc| sed -ne "s/\(.*$separator\)[^$separator]*/\1/p"|sed -e "s/--.*=//") - printf "%s\n" "$str"$argv "$str"(printf "%s\n" $argv|sed -e "s/\(\t\|\$\)/,\1/") + set -e argv[1] + set str (commandline -tc| sed -ne "s/\(.*$separator\)[^$separator]*/\1/p"|sed -e "s/--.*=//") + printf "%s\n" "$str"$argv "$str"(printf "%s\n" $argv|sed -e "s/\(\t\|\$\)/,\1/") end diff --git a/share/functions/__fish_bind_test1.fish b/share/functions/__fish_bind_test1.fish index 7659f5f45..fa5fe4de1 100644 --- a/share/functions/__fish_bind_test1.fish +++ b/share/functions/__fish_bind_test1.fish @@ -5,21 +5,21 @@ function __fish_bind_test1 for i in (commandline -poc) switch $i case -k --k --ke --key - set use_keys yes + set use_keys yes case "-*" case "*" - set args $args $i + set args $args $i end end switch $use_keys case yes - switch (count $args) - case 1 - return 0 - end + switch (count $args) + case 1 + return 0 + end end return 1 end diff --git a/share/functions/__fish_bind_test2.fish b/share/functions/__fish_bind_test2.fish index 4c7f684ac..fded8b262 100644 --- a/share/functions/__fish_bind_test2.fish +++ b/share/functions/__fish_bind_test2.fish @@ -1,20 +1,20 @@ function __fish_bind_test2 -set -l args -for i in (commandline -poc) - switch $i - case "-*" + set -l args + for i in (commandline -poc) + switch $i + case "-*" - case "*" - set args $args $i - end -end + case "*" + set args $args $i + end + end - switch (count $args) - case 2 - return 0 - end + switch (count $args) + case 2 + return 0 + end - return 1 + return 1 end diff --git a/share/functions/__fish_cancel_commandline.fish b/share/functions/__fish_cancel_commandline.fish index 614f2adf4..bc093ea66 100644 --- a/share/functions/__fish_cancel_commandline.fish +++ b/share/functions/__fish_cancel_commandline.fish @@ -9,8 +9,8 @@ function __fish_cancel_commandline # # Set reverse fg/bg color mode, output ^C, restore normal mode, clear to EOL (to erase any # autosuggestion). - if command -v tput >/dev/null - echo -ns (tput smso; or tput so) "^C" (tput rmso; or tput se) (tput el; or tput ce) + if command -sq tput + echo -ns (set_color -r) "^C" (set_color normal) (tput el; or tput ce) else echo -n "^C" end diff --git a/share/functions/__fish_commandline_test.fish b/share/functions/__fish_commandline_test.fish index a7e5e00b7..e89b13f11 100644 --- a/share/functions/__fish_commandline_test.fish +++ b/share/functions/__fish_commandline_test.fish @@ -5,10 +5,10 @@ function __fish_commandline_test for i in (commandline -poc) switch $i case -f --f --fu --fun --func --funct --functi --functio --function - set is_function yes + set is_function yes case -- - break + break end @@ -16,7 +16,7 @@ function __fish_commandline_test switch $is_function case yes - return 0 + return 0 end return 1 diff --git a/share/functions/__fish_complete_abook_formats.fish b/share/functions/__fish_complete_abook_formats.fish index b1c03fd6a..bc58a2267 100644 --- a/share/functions/__fish_complete_abook_formats.fish +++ b/share/functions/__fish_complete_abook_formats.fish @@ -2,11 +2,11 @@ function __fish_complete_abook_formats --description 'Complete abook formats' set -l pat switch $argv[1] case in - set pat '/output:/,$d; /input:\|^$/d' + set pat '/output:/,$d; /input:\|^$/d' case out - set pat '/input:/,/output:/d; /^$/d' + set pat '/input:/,/output:/d; /^$/d' case '*' - return 1 + return 1 end abook --formats | sed -e $pat -e 's/^\s\+//' diff --git a/share/functions/__fish_complete_ant_targets.fish b/share/functions/__fish_complete_ant_targets.fish index 61dde00a6..e93b855c6 100644 --- a/share/functions/__fish_complete_ant_targets.fish +++ b/share/functions/__fish_complete_ant_targets.fish @@ -1,15 +1,16 @@ function __fish_complete_ant_targets -d "Print list of targets from build.xml and imported files" - set -l buildfile "build.xml" - if test -f $buildfile - # show ant targets - __fish_filter_ant_targets $buildfile + set -l buildfile "build.xml" + if test -f $buildfile + # show ant targets + __fish_filter_ant_targets $buildfile - # find files with buildfile - set files (sed -n "s/^.*]* file=[\"']\([^\"']*\)[\"'].*\$/\1/p" < $buildfile) + # find files with buildfile + set files (sed -n "s/^.*]* file=[\"']\([^\"']*\)[\"'].*\$/\1/p" < $buildfile) - # iterate through files and display their targets - for file in $files; - __fish_filter_ant_targets $file - end - end + # iterate through files and display their targets + for file in $files + + __fish_filter_ant_targets $file + end + end end diff --git a/share/functions/__fish_complete_atool_archive_contents.fish b/share/functions/__fish_complete_atool_archive_contents.fish index dcc062f69..0a19c8217 100644 --- a/share/functions/__fish_complete_atool_archive_contents.fish +++ b/share/functions/__fish_complete_atool_archive_contents.fish @@ -1,20 +1,20 @@ function __fish_complete_atool_archive_contents --description 'List archive contents' - set -l cmd (commandline -cop) - set -e cmd[1] - set -l file - for arg in $cmd - switch $arg - case '-*' - case '*' - if test -f $arg - set file $arg - break - end - end - end - if not set -q file[1] - return - end - als $file -qq | sed -r 's/^\s*[0-9]+\s+[0-9-]+\s+[0-9:]+\s+(.*)$/\1/' + set -l cmd (commandline -cop) + set -e cmd[1] + set -l file + for arg in $cmd + switch $arg + case '-*' + case '*' + if test -f $arg + set file $arg + break + end + end + end + if not set -q file[1] + return + end + als $file -qq | sed -r 's/^\s*[0-9]+\s+[0-9-]+\s+[0-9:]+\s+(.*)$/\1/' end diff --git a/share/functions/__fish_complete_bittorrent.fish b/share/functions/__fish_complete_bittorrent.fish index d78d0c100..7e74fdf31 100644 --- a/share/functions/__fish_complete_bittorrent.fish +++ b/share/functions/__fish_complete_bittorrent.fish @@ -1,33 +1,33 @@ # Bittorrent commands function __fish_complete_bittorrent - complete -c $argv -l max_uploads -x --description "Maximum uploads at once" - complete -c $argv -l keepalive_interval -x --description "Number of seconds between keepalives" - complete -c $argv -l download_slice_size -x --description "Bytes per request" - complete -c $argv -l request_backlog -x --description "Requests per pipe" - complete -c $argv -l max_message_length -x --description "Maximum length prefix encoding" - complete -c $argv -l ip --description "IP to report to the tracker" -x -a "(__fish_print_addresses)" - complete -c $argv -l minport --description "Minimum port to listen to" - complete -c $argv -l maxport --description "Maximum port to listen to" - complete -c $argv -l responsefile -r --description "File for server response" - complete -c $argv -l url -x --description "URL to get file from" - complete -c $argv -l saveas -r --description "Local file target" - complete -c $argv -l timeout -x --description "Time to close inactive socket" - complete -c $argv -l timeout_check_interval -x --description "Time between checking timeouts" - complete -c $argv -l max_slice_length -x --description "Maximum outgoing slice length" - complete -c $argv -l max_rate_period -x --description "Maximum time to guess rate" - complete -c $argv -l bind -x --description "IP to bind to locally" -a "(__fish_print_addresses)" - complete -c $argv -l display_interval -x --description "Time between screen updates" - complete -c $argv -l rerequest_interval -x --description "Time to wait between requesting more peers" - complete -c $argv -l min_peers -x --description "Minimum number of peers to not do requesting" - complete -c $argv -l http_timeout -x --description "Number of seconds before assuming http timeout" - complete -c $argv -l max_initiate -x --description "Number of peers at which to stop initiating new connections" - complete -c $argv -l max_allow_in -x --description "Maximum number of connections to allow" - complete -c $argv -l check_hashes -x --description "Whether to check hashes on disk" - complete -c $argv -l max_upload_rate -x --description "Maximum kB/s to upload at" - complete -c $argv -l snub_time -x --description "Seconds to wait for data to come in before assuming choking" - complete -c $argv -l spew -x --description "Whether to display diagnostic info" - complete -c $argv -l rarest_first_cutoff -x --description "Number of downloads at which to switch from random to rarest first" - complete -c $argv -l min_uploads -x --description "Number of uploads to fill out to with optimistic unchokes" - complete -c $argv -l report_hash_failiures -x --description "Whether to inform the user that hash failures occur" + complete -c $argv -l max_uploads -x --description "Maximum uploads at once" + complete -c $argv -l keepalive_interval -x --description "Number of seconds between keepalives" + complete -c $argv -l download_slice_size -x --description "Bytes per request" + complete -c $argv -l request_backlog -x --description "Requests per pipe" + complete -c $argv -l max_message_length -x --description "Maximum length prefix encoding" + complete -c $argv -l ip --description "IP to report to the tracker" -x -a "(__fish_print_addresses)" + complete -c $argv -l minport --description "Minimum port to listen to" + complete -c $argv -l maxport --description "Maximum port to listen to" + complete -c $argv -l responsefile -r --description "File for server response" + complete -c $argv -l url -x --description "URL to get file from" + complete -c $argv -l saveas -r --description "Local file target" + complete -c $argv -l timeout -x --description "Time to close inactive socket" + complete -c $argv -l timeout_check_interval -x --description "Time between checking timeouts" + complete -c $argv -l max_slice_length -x --description "Maximum outgoing slice length" + complete -c $argv -l max_rate_period -x --description "Maximum time to guess rate" + complete -c $argv -l bind -x --description "IP to bind to locally" -a "(__fish_print_addresses)" + complete -c $argv -l display_interval -x --description "Time between screen updates" + complete -c $argv -l rerequest_interval -x --description "Time to wait between requesting more peers" + complete -c $argv -l min_peers -x --description "Minimum number of peers to not do requesting" + complete -c $argv -l http_timeout -x --description "Number of seconds before assuming http timeout" + complete -c $argv -l max_initiate -x --description "Number of peers at which to stop initiating new connections" + complete -c $argv -l max_allow_in -x --description "Maximum number of connections to allow" + complete -c $argv -l check_hashes -x --description "Whether to check hashes on disk" + complete -c $argv -l max_upload_rate -x --description "Maximum kB/s to upload at" + complete -c $argv -l snub_time -x --description "Seconds to wait for data to come in before assuming choking" + complete -c $argv -l spew -x --description "Whether to display diagnostic info" + complete -c $argv -l rarest_first_cutoff -x --description "Number of downloads at which to switch from random to rarest first" + complete -c $argv -l min_uploads -x --description "Number of uploads to fill out to with optimistic unchokes" + complete -c $argv -l report_hash_failiures -x --description "Whether to inform the user that hash failures occur" end diff --git a/share/functions/__fish_complete_cd.fish b/share/functions/__fish_complete_cd.fish index 3ba2ad9d5..381e0b0b7 100644 --- a/share/functions/__fish_complete_cd.fish +++ b/share/functions/__fish_complete_cd.fish @@ -1,32 +1,36 @@ function __fish_complete_cd -d "Completions for the cd command" - set -l token (commandline -ct) - # Absolute path or explicitly from the current directory - no descriptions and no CDPATH - if string match -qr '^\.?\.?/.*' -- $token - for d in $token*/ - # Check if it's accessible - the glob only matches directories - [ -x $d ]; and printf "%s\n" $d - end - else # Relative path - check $CDPATH and use that as description - set -l cdpath $CDPATH - [ -z "$cdpath" ]; and set cdpath "." - # Remove the real path to "." (i.e. $PWD) from cdpath if we're in it - # so it doesn't get printed in the descriptions - if set -l ind (contains -i -- $PWD $cdpath) - and contains -- "." $cdpath - set -e cdpath[$ind] - end - # TODO: There's a subtlety regarding descriptions - if $cdpath[1]/foo and $cdpath[2]/foo exist, we print both - # but want the first description to win - this currently works, but is not guaranteed - for i in $cdpath - set -l desc - # Don't show description for current directory - # and replace $HOME with "~" - [ $i = "." ]; or set -l desc (string replace -r -- "^$HOME" "~" "$i") - # This assumes the CDPATH component itself is cd-able - for d in $i/$token*/ - # Remove the cdpath component again - [ -x $d ]; and printf "%s\t%s\n" (string replace -r "^$i/" "" -- $d) $desc - end - end - end + set -l token (commandline -ct) + # Absolute path or explicitly from the current directory - no descriptions and no CDPATH + if string match -qr '^\.?\.?/.*' -- $token + for d in $token*/ + # Check if it's accessible - the glob only matches directories + [ -x $d ] + and printf "%s\n" $d + end + else # Relative path - check $CDPATH and use that as description + set -l cdpath $CDPATH + [ -z "$cdpath" ] + and set cdpath "." + # Remove the real path to "." (i.e. $PWD) from cdpath if we're in it + # so it doesn't get printed in the descriptions + if set -l ind (contains -i -- $PWD $cdpath) + and contains -- "." $cdpath + set -e cdpath[$ind] + end + # TODO: There's a subtlety regarding descriptions - if $cdpath[1]/foo and $cdpath[2]/foo exist, we print both + # but want the first description to win - this currently works, but is not guaranteed + for i in $cdpath + set -l desc + # Don't show description for current directory + # and replace $HOME with "~" + [ $i = "." ] + or set -l desc (string replace -r -- "^$HOME" "~" "$i") + # This assumes the CDPATH component itself is cd-able + for d in $i/$token*/ + # Remove the cdpath component again + [ -x $d ] + and printf "%s\t%s\n" (string replace -r "^$i/" "" -- $d) $desc + end + end + end end diff --git a/share/functions/__fish_complete_command.fish b/share/functions/__fish_complete_command.fish index 35f5e29b5..f6cc7e20a 100644 --- a/share/functions/__fish_complete_command.fish +++ b/share/functions/__fish_complete_command.fish @@ -1,10 +1,10 @@ function __fish_complete_command --description 'Complete using all available commands' - set -l ctoken (commandline -ct) - switch $ctoken - case '*=*' - set ctoken (string split "=" -- $ctoken) - printf '%s\n' $ctoken[1]=(complete -C$ctoken[2]) - case '*' - complete -C$ctoken - end + set -l ctoken (commandline -ct) + switch $ctoken + case '*=*' + set ctoken (string split "=" -- $ctoken) + printf '%s\n' $ctoken[1]=(complete -C$ctoken[2]) + case '*' + complete -C$ctoken + end end diff --git a/share/functions/__fish_complete_convert_options.fish b/share/functions/__fish_complete_convert_options.fish index 3437cc70b..863c83c7f 100644 --- a/share/functions/__fish_complete_convert_options.fish +++ b/share/functions/__fish_complete_convert_options.fish @@ -1,16 +1,16 @@ function __fish_complete_convert_options --description 'Complete Convert options' --argument what - switch $what - case format Format - convert -list Format | sed '1,/----/d; /^$/,$d; /^$/d; s/^\s*\([a-zA-Z0-9-]\+\)\**\s*\S\+\s\+\\(\S\+\)\s\+\(.\+\S\)\s*$/\1\t\2 \3/' - case color Color - convert -list color | awk '{ print $1"\t"$2" "$3} ' | sed '1,/----/d' - case family - convert -list Font | grep family | sed 's/^\s*.\+: //' | sort -u - case font Font - convert -list Font | grep Font | sed 's/^\s*.\+: //' | sort -u - case '*' - convert -list $what - end + switch $what + case format Format + convert -list Format | sed '1,/----/d; /^$/,$d; /^$/d; s/^\s*\([a-zA-Z0-9-]\+\)\**\s*\S\+\s\+\\(\S\+\)\s\+\(.\+\S\)\s*$/\1\t\2 \3/' + case color Color + convert -list color | awk '{ print $1"\t"$2" "$3} ' | sed '1,/----/d' + case family + convert -list Font | grep family | sed 's/^\s*.\+: //' | sort -u + case font Font + convert -list Font | grep Font | sed 's/^\s*.\+: //' | sort -u + case '*' + convert -list $what + end end diff --git a/share/functions/__fish_complete_directories.fish b/share/functions/__fish_complete_directories.fish index ba222f0b2..35a82e92a 100644 --- a/share/functions/__fish_complete_directories.fish +++ b/share/functions/__fish_complete_directories.fish @@ -5,17 +5,17 @@ function __fish_complete_directories -d "Complete using directories" --argument comp - set desc (_ Directory) + set desc (_ Directory) - if test (count $argv) -gt 1 - set desc $argv[2] - end + if test (count $argv) -gt 1 + set desc $argv[2] + end - eval "set dirs "$comp"*/" + eval "set dirs "$comp"*/" - if test $dirs[1] - printf "%s\t$desc\n" $dirs - end + if test $dirs[1] + printf "%s\t$desc\n" $dirs + end end diff --git a/share/functions/__fish_complete_file_url.fish b/share/functions/__fish_complete_file_url.fish index 28af18080..c19df569e 100644 --- a/share/functions/__fish_complete_file_url.fish +++ b/share/functions/__fish_complete_file_url.fish @@ -1,20 +1,20 @@ function __fish_complete_file_url - set -l comp + set -l comp - if set -q argv[1] - set comp $argv[1] - else - set comp (commandline -ct) - end + if set -q argv[1] + set comp $argv[1] + else + set comp (commandline -ct) + end - set -l prefix (echo $comp|cut -c 1-7) + set -l prefix (echo $comp|cut -c 1-7) - if test file:// = $prefix - set -l stripped (echo $comp|cut -c 8-) - printf "%s\n" file://(complete -C"echo $stripped") - else - echo file:// - end + if test file:// = $prefix + set -l stripped (echo $comp|cut -c 8-) + printf "%s\n" file://(complete -C"echo $stripped") + else + echo file:// + end end diff --git a/share/functions/__fish_complete_ftp.fish b/share/functions/__fish_complete_ftp.fish index 92ff0b088..f651b756a 100644 --- a/share/functions/__fish_complete_ftp.fish +++ b/share/functions/__fish_complete_ftp.fish @@ -1,14 +1,14 @@ function __fish_complete_ftp -d 'Complete ftp, pftp' --argument-names ftp - complete -c $ftp -xa "(__fish_print_hostnames)" -d 'Hostname' - complete -c $ftp -s 4 -d 'Use only IPv4 to contact any host' - complete -c $ftp -s 6 -d 'Use IPv6 only' - complete -c $ftp -s p -d 'Use passive mode for data transfers' - complete -c $ftp -s A -d 'Use active mode for data transfers' - complete -c $ftp -s i -d 'Turn off interactive prompting during multiple file transfers.' - complete -c $ftp -s n -d 'Restrain ftp from attempting "auto-login" upon initial connection' - complete -c $ftp -s e -d 'Disable command editing and history support' - complete -c $ftp -s g -d 'Disable file name globbing' - complete -c $ftp -s m -d 'Do not explicitly bind data and control channels to same interface' - complete -c $ftp -s v -d 'Verbose. Show all server responses and data transfer stats' - complete -c $ftp -s d -d 'Enable debugging' + complete -c $ftp -xa "(__fish_print_hostnames)" -d 'Hostname' + complete -c $ftp -s 4 -d 'Use only IPv4 to contact any host' + complete -c $ftp -s 6 -d 'Use IPv6 only' + complete -c $ftp -s p -d 'Use passive mode for data transfers' + complete -c $ftp -s A -d 'Use active mode for data transfers' + complete -c $ftp -s i -d 'Turn off interactive prompting during multiple file transfers.' + complete -c $ftp -s n -d 'Restrain ftp from attempting "auto-login" upon initial connection' + complete -c $ftp -s e -d 'Disable command editing and history support' + complete -c $ftp -s g -d 'Disable file name globbing' + complete -c $ftp -s m -d 'Do not explicitly bind data and control channels to same interface' + complete -c $ftp -s v -d 'Verbose. Show all server responses and data transfer stats' + complete -c $ftp -s d -d 'Enable debugging' end diff --git a/share/functions/__fish_complete_groups.fish b/share/functions/__fish_complete_groups.fish index ca2f4ccb5..a7a41f0aa 100644 --- a/share/functions/__fish_complete_groups.fish +++ b/share/functions/__fish_complete_groups.fish @@ -1,8 +1,8 @@ function __fish_complete_groups --description "Print a list of local groups, with group members as the description" - if command -s getent >/dev/null - getent group | cut -d ':' -f 1,4 | sed 's/:/\t/' - else - cut -d ':' -f 1,4 /etc/group | sed 's/:/\t/' - end + if command -s getent >/dev/null + getent group | cut -d ':' -f 1,4 | sed 's/:/\t/' + else + cut -d ':' -f 1,4 /etc/group | sed 's/:/\t/' + end end diff --git a/share/functions/__fish_complete_list.fish b/share/functions/__fish_complete_list.fish index 99d65ef19..bfe3ecf91 100644 --- a/share/functions/__fish_complete_list.fish +++ b/share/functions/__fish_complete_list.fish @@ -1,30 +1,30 @@ function __fish_complete_list --argument div cmd prefix iprefix - if not set -q cmd[1] - echo "Usage: + if not set -q cmd[1] + echo "Usage: __fish_complete_list where: separator - a symbol, separating individual entries function - a function which prints a completion list to complete each entry prefix - a prefix, which is printed before the list - itemprefix - a prefix, which is printed before each item" > /dev/stderr - return 1 - end - set -q iprefix[1] - or set -l iprefix "" - set -q prefix[1] - or set -l prefix "" - set -l pat (commandline -t) - #set -l pat $argv[5] - switch $pat - case "*$div*" - for i in (echo $pat | sed "s/^\(.\+$div\)$iprefix.*\$/\1/")$iprefix(eval $cmd) - echo $i - end - case '*' - for i in $prefix$iprefix(eval $cmd) - echo $i - end - end + itemprefix - a prefix, which is printed before each item" >/dev/stderr + return 1 + end + set -q iprefix[1] + or set -l iprefix "" + set -q prefix[1] + or set -l prefix "" + set -l pat (commandline -t) + #set -l pat $argv[5] + switch $pat + case "*$div*" + for i in (echo $pat | sed "s/^\(.\+$div\)$iprefix.*\$/\1/")$iprefix(eval $cmd) + echo $i + end + case '*' + for i in $prefix$iprefix(eval $cmd) + echo $i + end + end end diff --git a/share/functions/__fish_complete_lpr.fish b/share/functions/__fish_complete_lpr.fish index c6b2cbf45..f594147f6 100644 --- a/share/functions/__fish_complete_lpr.fish +++ b/share/functions/__fish_complete_lpr.fish @@ -4,35 +4,35 @@ function __fish_complete_lpr -d 'Complete lpr common options' --argument-names c switch $cmd case lpr lpq lprm - complete -c $cmd -s P -d 'Specifies an alternate printer or class name' -xa '(__fish_print_lpr_printers)' + complete -c $cmd -s P -d 'Specifies an alternate printer or class name' -xa '(__fish_print_lpr_printers)' end switch $cmd case lpq cancel - complete -c $cmd -s a -d 'Apply command to all printers' + complete -c $cmd -s a -d 'Apply command to all printers' end switch $cmd - case lpq cancel lpmove lpstat lprm lpoptions lp reject accept cupsaccept cupsreject cupsenable cupsdisable - complete -c $cmd -s h -d 'Specifies an alternate server' -xa '(__fish_print_hostnames)' + case lpq cancel lpmove lpstat lprm lpoptions lp reject accept cupsaccept cupsreject cupsenable cupsdisable + complete -c $cmd -s h -d 'Specifies an alternate server' -xa '(__fish_print_hostnames)' end switch $cmd case lp lpr - complete -c $cmd -s o -d 'Sets a job option' -xa '(__fish_complete_lpr_option)' - complete -c $cmd -s m -d 'Send an email on job completion' + complete -c $cmd -s o -d 'Sets a job option' -xa '(__fish_complete_lpr_option)' + complete -c $cmd -s m -d 'Send an email on job completion' - complete -c $cmd -s o -xa landscape -d 'Landscape mode' - complete -c $cmd -s o -xa "media=a4 media=letter media=legal" -d 'Media size' - complete -c $cmd -s o -xa page-ranges= -d 'Page ranges' - complete -c $cmd -s o -xa orientation-requested= -d 'Choose orientation (4-landscape)' - complete -c $cmd -s o -xa 'sides-one-sided two-sided-long-edge two-sided-short-edge' -d 'Choose between one/two sided modes' - complete -c $cmd -s o -xa fitplot -d 'Scale the print file to fit on the page' - complete -c $cmd -s o -xa 'number-up=2 number-up=4 number-up=6 number-up=9' -d 'Print multiple document pages on each output page' - complete -c $cmd -s o -xa 'scaling=' -d 'Scale image files to use up to number percent of the page' - complete -c $cmd -s o -xa 'cpi=' -d 'Set the number of characters per inch to use' - complete -c $cmd -s o -xa 'lpi=' -d 'Set the number of lines per inch to use' - complete -c $cmd -s o -xa 'page-bottom= page-left= page-right= page-top=' -d 'Set the page margins when printing text files' + complete -c $cmd -s o -xa landscape -d 'Landscape mode' + complete -c $cmd -s o -xa "media=a4 media=letter media=legal" -d 'Media size' + complete -c $cmd -s o -xa page-ranges= -d 'Page ranges' + complete -c $cmd -s o -xa orientation-requested= -d 'Choose orientation (4-landscape)' + complete -c $cmd -s o -xa 'sides-one-sided two-sided-long-edge two-sided-short-edge' -d 'Choose between one/two sided modes' + complete -c $cmd -s o -xa fitplot -d 'Scale the print file to fit on the page' + complete -c $cmd -s o -xa 'number-up=2 number-up=4 number-up=6 number-up=9' -d 'Print multiple document pages on each output page' + complete -c $cmd -s o -xa 'scaling=' -d 'Scale image files to use up to number percent of the page' + complete -c $cmd -s o -xa 'cpi=' -d 'Set the number of characters per inch to use' + complete -c $cmd -s o -xa 'lpi=' -d 'Set the number of lines per inch to use' + complete -c $cmd -s o -xa 'page-bottom= page-left= page-right= page-top=' -d 'Set the page margins when printing text files' end end diff --git a/share/functions/__fish_complete_lpr_option.fish b/share/functions/__fish_complete_lpr_option.fish index e593aab44..6db627f84 100644 --- a/share/functions/__fish_complete_lpr_option.fish +++ b/share/functions/__fish_complete_lpr_option.fish @@ -1,25 +1,25 @@ function __fish_complete_lpr_option --description 'Complete lpr option' - set -l optstr (commandline -t) - switch $optstr - case '*=*' - set -l IFS = - echo $optstr | read -l opt val - set -l descr - for l in (lpoptions -l ^/dev/null | string match -- "*$opt*" | string replace -r '.*/(.*):\s*(.*)$' '$1 $2' | string split " ") - if not set -q descr[1] - set descr $l - continue - end - set -l default '' - if string match -q '\**' -- $l - set default 'Default ' - set l (string sub -s 2 -- $l) - end - echo $opt=$l\t$default$descr - end - case '*' - lpoptions -l ^/dev/null | string replace -r '(.*)/(.*):.*$' '$1=\t$2' - end + set -l optstr (commandline -t) + switch $optstr + case '*=*' + set -l IFS = + echo $optstr | read -l opt val + set -l descr + for l in (lpoptions -l ^/dev/null | string match -- "*$opt*" | string replace -r '.*/(.*):\s*(.*)$' '$1 $2' | string split " ") + if not set -q descr[1] + set descr $l + continue + end + set -l default '' + if string match -q '\**' -- $l + set default 'Default ' + set l (string sub -s 2 -- $l) + end + echo $opt=$l\t$default$descr + end + case '*' + lpoptions -l ^/dev/null | string replace -r '(.*)/(.*):.*$' '$1=\t$2' + end end diff --git a/share/functions/__fish_complete_lsusb.fish b/share/functions/__fish_complete_lsusb.fish index faf7ae5b2..b6814b29f 100644 --- a/share/functions/__fish_complete_lsusb.fish +++ b/share/functions/__fish_complete_lsusb.fish @@ -1,3 +1,3 @@ function __fish_complete_lsusb - lsusb | awk '{print $2 ":" $4}'| cut -c1-7 + lsusb | awk -F[ :] '{ print $2 ":" $4 }' end diff --git a/share/functions/__fish_complete_man.fish b/share/functions/__fish_complete_man.fish index bd9818bb9..54d201755 100644 --- a/share/functions/__fish_complete_man.fish +++ b/share/functions/__fish_complete_man.fish @@ -1,20 +1,20 @@ function __fish_complete_man - # Try to guess what section to search in. If we don't know, we - # use [^)]*, which should match any section + # Try to guess what section to search in. If we don't know, we + # use [^)]*, which should match any section - set section "" - set prev (commandline -poc) - set -e prev[1] - while set -q prev[1] - switch $prev[1] - case '-**' + set section "" + set prev (commandline -poc) + set -e prev[1] + while set -q prev[1] + switch $prev[1] + case '-**' - case '*' - set section $prev[1] - end - set -e prev[1] - end + case '*' + set section $prev[1] + end + set -e prev[1] + end set section $section"[^)]*" @@ -25,48 +25,52 @@ function __fish_complete_man set token "." end - if test -n "$token" - # Do the actual search - apropos $token ^/dev/null | awk ' - BEGIN { FS="[\t ]- "; OFS="\t"; } - # BSD/Darwin - /^[^( \t]+\('$section'\)/ { - split($1, pages, ", "); - for (i in pages) { - page = pages[i]; - sub(/[ \t]+/, "", page); - paren = index(page, "("); - name = substr(page, 1, paren - 1); - sect = substr(page, paren + 1, length(page) - paren - 1); - print name, sect ": " $2; - } - } - # man-db - /^[^( \t]+ +\('$section'\)/ { - split($1, t, " "); - sect = substr(t[2], 2, length(t[2]) - 2); - print t[1], sect ": " $2; - } - # man-db RHEL 5 with [aliases] - /^[^( \t]+ +\[.*\] +\('$section'\)/ { - split($1, t, " "); - sect = substr(t[3], 2, length(t[3]) - 2); - print t[1], sect ": " $2; - } - # Solaris 11 - # Does not display descriptions - # Solaris apropos outputs embedded backspace in descriptions - /^[0-9]+\. [^( \t]*\('$section'\) / { - split($1, t, " ") - paren = index(t[2], "("); - name = substr(t[2], 1, paren - 1); - sect = substr(t[2], paren + 1, length(t[2]) - paren - 1); - print name, sect - } - ' + if test -n "$token" + # Do the actual search + apropos $token ^/dev/null | awk ' + BEGIN { FS="[\t ]- "; OFS="\t"; } + # BSD/Darwin + /^[^( \t]+\('$section'\)/ { + split($1, pages, ", "); + for (i in pages) { + page = pages[i]; + sub(/[ \t]+/, "", page); + paren = index(page, "("); + name = substr(page, 1, paren - 1); + sect = substr(page, paren + 1, length(page) - paren - 1); + print name, sect ": " $2; + } + } + # man-db + /^[^( \t]+ +\('$section'\)/ { + split($1, t, " "); + sect = substr(t[2], 2, length(t[2]) - 2); + print t[1], sect ": " $2; + } + # man-db RHEL 5 with [aliases] + /^[^( \t]+ +\[.*\] +\('$section'\)/ { + split($1, t, " "); + sect = substr(t[3], 2, length(t[3]) - 2); + print t[1], sect ": " $2; + } + # Solaris 11 + # Does not display descriptions + # Solaris apropos outputs embedded backspace in descriptions + /^[0-9]+\. [^( \t]*\('$section'\) / { + split($1, t, " ") + paren = index(t[2], "("); + name = substr(t[2], 1, paren - 1); + sect = substr(t[2], paren + 1, length(t[2]) - paren - 1); + print name, sect + } + ' + + # Fish commands are not given by apropos + set -l files $__fish_datadir/man/man1/*.1 + string replace -r '.*/([^/]+)\.1$' '$1\tFish command' -- $files else return 1 - end + end return 0 end diff --git a/share/functions/__fish_complete_path.fish b/share/functions/__fish_complete_path.fish index e10ef7069..614d914a8 100644 --- a/share/functions/__fish_complete_path.fish +++ b/share/functions/__fish_complete_path.fish @@ -1,14 +1,14 @@ function __fish_complete_path --description "Complete using path" - set -l target - set -l description - switch (count $argv) - case 0 - # pass - case 1 - set target "$argv[1]" - case 2 "*" - set target "$argv[1]" - set description "$argv[2]" - end - printf "%s\t$description\n" (command ls -dp "$target"*) + set -l target + set -l description + switch (count $argv) + case 0 + # pass + case 1 + set target "$argv[1]" + case 2 "*" + set target "$argv[1]" + set description "$argv[2]" + end + printf "%s\t$description\n" (command ls -dp "$target"*) end diff --git a/share/functions/__fish_complete_pgrep.fish b/share/functions/__fish_complete_pgrep.fish index 816ea238d..c69b4de79 100644 --- a/share/functions/__fish_complete_pgrep.fish +++ b/share/functions/__fish_complete_pgrep.fish @@ -3,14 +3,14 @@ function __fish_complete_pgrep -d 'Complete pgrep/pkill' --argument-names cmd complete -c $cmd -xa '(__fish_complete_proc)' complete -c $cmd -s f -d 'Match pattern against full command line' complete -c $cmd -s g -d 'Only match processes in the process group' -xa '(__fish_complete_list , __fish_complete_groups)' - complete -c $cmd -s G -d "Only match processes whose real group ID is listed. Group 0 is translated into $cmd\'s own process group" -xa '(__fish_complete_list , __fish_complete_groups)' + complete -c $cmd -s G -d "Only match processes whose real group ID is listed. Group 0 is translated into $cmd\'s own process group" -xa '(__fish_complete_list , __fish_complete_groups)' complete -c $cmd -s n -d 'Select only the newest process' complete -c $cmd -s o -d 'Select only the oldest process' complete -c $cmd -s P -d 'Only match processes whose parent process ID is listed' -xa '(__fish_complete_list , __fish_complete_pids)' complete -c $cmd -s s -d "Only match processes whose process session ID is listed. Session ID 0 is translated into $cmd\'s own session ID." complete -c $cmd -s t -d 'Only match processes whose controlling terminal is listed. The terminal name should be specified without the "/dev/" prefix' -r complete -c $cmd -s u -d 'Only match processes whose effective user ID is listed' -xa '(__fish_complete_list , __fish_complete_users)' - complete -c $cmd -s U -d 'Only match processes whose real user ID is listed' -xa '(__fish_complete_list , __fish_complete_users)' + complete -c $cmd -s U -d 'Only match processes whose real user ID is listed' -xa '(__fish_complete_list , __fish_complete_users)' complete -c $cmd -s v -d 'Negates the matching' complete -c $cmd -s x -d ' Only match processes whose name (or command line if -f is specified) exactly match the pattern' end diff --git a/share/functions/__fish_complete_pids.fish b/share/functions/__fish_complete_pids.fish index e974ed61f..d00fbf92d 100644 --- a/share/functions/__fish_complete_pids.fish +++ b/share/functions/__fish_complete_pids.fish @@ -1,11 +1,11 @@ function __fish_complete_pids -d "Print a list of process identifiers along with brief descriptions" - # This may be a bit slower, but it's nice - having the tty displayed is really handy - # 'tail -n +2' deletes the first line, which contains the headers - # %self is removed from output by string match -r -v - set -l SELF %self - - # Display the tty if available - # But not if it's just question marks, meaning no tty - ps axc -o pid,ucomm,tty | string match -r -v '^\s*'$SELF'\s' | tail -n +2 | string replace -r ' *([0-9]+) +([^ ].*[^ ]|[^ ]) +([^ ]+) *$' '$1\t$2 [$3]' | string replace -r ' *\[\?*\] *$' '' + # This may be a bit slower, but it's nice - having the tty displayed is really handy + # 'tail -n +2' deletes the first line, which contains the headers + # %self is removed from output by string match -r -v + set -l SELF %self + + # Display the tty if available + # But not if it's just question marks, meaning no tty + ps axc -o pid,ucomm,tty | string match -r -v '^\s*'$SELF'\s' | tail -n +2 | string replace -r ' *([0-9]+) +([^ ].*[^ ]|[^ ]) +([^ ]+) *$' '$1\t$2 [$3]' | string replace -r ' *\[\?*\] *$' '' end diff --git a/share/functions/__fish_complete_ppp_peer.fish b/share/functions/__fish_complete_ppp_peer.fish index bc4f75448..faabba378 100644 --- a/share/functions/__fish_complete_ppp_peer.fish +++ b/share/functions/__fish_complete_ppp_peer.fish @@ -1,4 +1,4 @@ function __fish_complete_ppp_peer --description 'Complete isp name for pon/poff' - find /etc/ppp/peers/ -type f -printf '%f\n' + find /etc/ppp/peers/ -type f -printf '%f\n' end diff --git a/share/functions/__fish_complete_proc.fish b/share/functions/__fish_complete_proc.fish index d520a0302..ab92bdfb3 100644 --- a/share/functions/__fish_complete_proc.fish +++ b/share/functions/__fish_complete_proc.fish @@ -1,47 +1,47 @@ function __fish_complete_proc --description 'Complete by list of running processes' - # Our function runs ps, followed by a massive list of commands passed to sed - set -l ps_cmd - set -l sed_cmds - if test (uname) = Linux - # comm and ucomm return a truncated name, so parse it from the command line field, - # which means we have to trim off the arguments. - # Unfortunately, it doesn't seem to escape spaces - so we can't distinguish - # between the command name, and the first argument. Still, processes with spaces - # in the name seem more common on OS X than on Linux, so prefer to parse out the - # command line rather than using the stat data. - # If the command line is unavailable, you get the stat data in brackets - so - # parse out brackets too. - set ps_cmd 'ps -A -o command' - - # Erase everything after the first space - set sed_cmds $sed_cmds 's/ .*//' - - # Erases weird stuff Linux gives like kworker/0:0 - set sed_cmds $sed_cmds 's|/[0-9]:[0-9]]$||g' - - # Retain the last path component only - set sed_cmds $sed_cmds 's|.*/||g' - - # Strip off square brackets. Cute, huh? - set sed_cmds $sed_cmds 's/[][]//g' - - # Erase things that are just numbers - set sed_cmds $sed_cmds 's/^[0-9]*$//' - else - # OS X, BSD. Preserve leading spaces. - set ps_cmd 'ps axc -o comm' - - # Delete parenthesized (zombie) processes - set sed_cmds $sed_cmds '/(.*)/d' - end - - # Append sed command to delete first line (the header) - set sed_cmds $sed_cmds '1d' - - # Append sed commands to delete leading dashes and trailing spaces - # In principle, commands may have trailing spaces, but ps emits space padding on OS X - set sed_cmds $sed_cmds 's/^-//' 's/ *$//' - - # Run ps, pipe it through our massive set of sed commands, then sort and unique - eval $ps_cmd | sed '-e '$sed_cmds | sort -u + # Our function runs ps, followed by a massive list of commands passed to sed + set -l ps_cmd + set -l sed_cmds + if test (uname) = Linux + # comm and ucomm return a truncated name, so parse it from the command line field, + # which means we have to trim off the arguments. + # Unfortunately, it doesn't seem to escape spaces - so we can't distinguish + # between the command name, and the first argument. Still, processes with spaces + # in the name seem more common on OS X than on Linux, so prefer to parse out the + # command line rather than using the stat data. + # If the command line is unavailable, you get the stat data in brackets - so + # parse out brackets too. + set ps_opt -A -o command + + # Erase everything after the first space + set sed_cmds $sed_cmds 's/ .*//' + + # Erases weird stuff Linux gives like kworker/0:0 + set sed_cmds $sed_cmds 's|/[0-9]:[0-9]]$||g' + + # Retain the last path component only + set sed_cmds $sed_cmds 's|.*/||g' + + # Strip off square brackets. Cute, huh? + set sed_cmds $sed_cmds 's/[][]//g' + + # Erase things that are just numbers + set sed_cmds $sed_cmds 's/^[0-9]*$//' + else + # OS X, BSD. Preserve leading spaces. + set ps_opt axc -o comm + + # Delete parenthesized (zombie) processes + set sed_cmds $sed_cmds '/(.*)/d' + end + + # Append sed command to delete first line (the header) + set sed_cmds $sed_cmds '1d' + + # Append sed commands to delete leading dashes and trailing spaces + # In principle, commands may have trailing spaces, but ps emits space padding on OS X + set sed_cmds $sed_cmds 's/^-//' 's/ *$//' + + # Run ps, pipe it through our massive set of sed commands, then sort and unique + ps $ps_opt | sed '-e '$sed_cmds | sort -u end diff --git a/share/functions/__fish_complete_setxkbmap.fish b/share/functions/__fish_complete_setxkbmap.fish index 9f8578a58..7260f7e20 100644 --- a/share/functions/__fish_complete_setxkbmap.fish +++ b/share/functions/__fish_complete_setxkbmap.fish @@ -1,3 +1,3 @@ function __fish_complete_setxkbmap --description 'Complete setxkb options' --argument-names what - sed -e "1,/! $what/d" -e '/^\s*$/,$d' /usr/share/X11/xkb/rules/xorg.lst | sed -r 's/\s+(\S+)\s+(.+)/\1\t\2/' + sed -e "1,/! $what/d" -e '/^\s*$/,$d' /usr/share/X11/xkb/rules/xorg.lst | sed -r 's/\s+(\S+)\s+(.+)/\1\t\2/' end diff --git a/share/functions/__fish_complete_ssh.fish b/share/functions/__fish_complete_ssh.fish index b1154a53a..00545dcc7 100644 --- a/share/functions/__fish_complete_ssh.fish +++ b/share/functions/__fish_complete_ssh.fish @@ -1,15 +1,15 @@ function __fish_complete_ssh -d "common completions for ssh commands" --argument command - complete -c $command -s 1 --description "Protocol version 1 only" - complete -c $command -s 2 --description "Protocol version 2 only" - complete -c $command -s 4 --description "IPv4 addresses only" - complete -c $command -s 6 --description "IPv6 addresses only" - complete -c $command -s C --description "Compress all data" - complete -xc $command -s c --description "Encryption algorithm" -a "blowfish 3des des" - complete -r -c $command -s F --description "Configuration file" - complete -r -c $command -s i --description "Identity file" - complete -x -c $command -s o --description "Options" -a " + complete -c $command -s 1 --description "Protocol version 1 only" + complete -c $command -s 2 --description "Protocol version 2 only" + complete -c $command -s 4 --description "IPv4 addresses only" + complete -c $command -s 6 --description "IPv6 addresses only" + complete -c $command -s C --description "Compress all data" + complete -xc $command -s c --description "Encryption algorithm" -a "blowfish 3des des" + complete -r -c $command -s F --description "Configuration file" + complete -r -c $command -s i --description "Identity file" + complete -x -c $command -s o --description "Options" -a " AddressFamily BatchMode BindAddress @@ -56,6 +56,6 @@ function __fish_complete_ssh -d "common completions for ssh commands" --argument UserKnownHostsFile VerifyHostKeyDNS " - complete -c $command -s v --description "Verbose mode" + complete -c $command -s v --description "Verbose mode" end diff --git a/share/functions/__fish_complete_subcommand.fish b/share/functions/__fish_complete_subcommand.fish index 4707450fc..9f5ac1d59 100644 --- a/share/functions/__fish_complete_subcommand.fish +++ b/share/functions/__fish_complete_subcommand.fish @@ -1,5 +1,5 @@ -function __fish_complete_subcommand -d "Complete subcommand" --no-scope-shadowing - set -l skip_next 1 +function __fish_complete_subcommand -d "Complete subcommand" --no-scope-shadowing + set -l skip_next 1 set -l test switch "$argv[1]" case '--fcs-skip=*' @@ -8,38 +8,38 @@ function __fish_complete_subcommand -d "Complete subcommand" --no-scope-shadowi set -e argv[1] end - set -l res "" - set -l had_cmd 0 - set -l cmd (commandline -cop) (commandline -ct) + set -l res "" + set -l had_cmd 0 + set -l cmd (commandline -cop) (commandline -ct) - for i in $cmd + for i in $cmd - if test $skip_next -gt 0 + if test $skip_next -gt 0 set skip_next (math $skip_next - 1) - continue - end + continue + end - if test "$had_cmd" = 1 - set res "$res $i" - else + if test "$had_cmd" = 1 + set res "$res $i" + else - if contains -- $i $argv - set skip_next (math $skip_next + 1) - continue - end + if contains -- $i $argv + set skip_next (math $skip_next + 1) + continue + end - switch $i - case '-*' - case '*=*' - case '*' + switch $i + case '-*' + case '*=*' + case '*' - set had_cmd 1 - set res $i - end - end - end + set had_cmd 1 + set res $i + end + end + end - printf "%s\n" (complete -C$res) + printf "%s\n" (complete -C$res) end diff --git a/share/functions/__fish_complete_subcommand_root.fish b/share/functions/__fish_complete_subcommand_root.fish index 822820fdb..f27984543 100644 --- a/share/functions/__fish_complete_subcommand_root.fish +++ b/share/functions/__fish_complete_subcommand_root.fish @@ -1,6 +1,6 @@ function __fish_complete_subcommand_root -d "Run the __fish_complete_subcommand function using a PATH containing /sbin and /usr/sbin" - set -lx PATH /sbin /usr/sbin $PATH ^/dev/null - __fish_complete_subcommand $argv + set -lx PATH /sbin /usr/sbin $PATH ^/dev/null + __fish_complete_subcommand $argv end diff --git a/share/functions/__fish_complete_suffix.fish b/share/functions/__fish_complete_suffix.fish index d0c264db2..a12d95e6b 100644 --- a/share/functions/__fish_complete_suffix.fish +++ b/share/functions/__fish_complete_suffix.fish @@ -7,47 +7,47 @@ function __fish_complete_suffix -d "Complete using files" - # Variable declarations + # Variable declarations - set -l comp - set -l suff - set -l desc - set -l files + set -l comp + set -l suff + set -l desc + set -l files - switch (count $argv) + switch (count $argv) - case 1 - set comp (commandline -ct) - set suff $argv - set desc "" + case 1 + set comp (commandline -ct) + set suff $argv + set desc "" - case 2 - set comp $argv[1] - set suff $argv[2] - set desc "" + case 2 + set comp $argv[1] + set suff $argv[2] + set desc "" - case 3 - set comp $argv[1] - set suff $argv[2] - set desc $argv[3] + case 3 + set comp $argv[1] + set suff $argv[2] + set desc $argv[3] - end + end - # Perform the completion + # Perform the completion - set base (echo $comp |sed -e 's/\.[a-zA-Z0-9]*$//') - eval "set files $base*$suff" + set base (echo $comp |sed -e 's/\.[a-zA-Z0-9]*$//') + eval "set files $base*$suff" - if test $files[1] - printf "%s\t$desc\n" $files - end + if test $files[1] + printf "%s\t$desc\n" $files + end - # - # Also do directory completion, since there might be files - # with the correct suffix in a subdirectory - # No need to describe directories (#279) - # + # + # Also do directory completion, since there might be files + # with the correct suffix in a subdirectory + # No need to describe directories (#279) + # - __fish_complete_directories $comp "" + __fish_complete_directories $comp "" end diff --git a/share/functions/__fish_complete_svn_diff.fish b/share/functions/__fish_complete_svn_diff.fish index ada2dd0ed..eb67fcc21 100644 --- a/share/functions/__fish_complete_svn_diff.fish +++ b/share/functions/__fish_complete_svn_diff.fish @@ -1,25 +1,25 @@ function __fish_complete_svn_diff --description 'Complete "svn diff" arguments' - set -l cmdl (commandline -cop) -#set -l cmdl svn diff --diff-cmd diff --extensions '-a -b' -set -l diff diff -set -l args -while set -q cmdl[1] -switch $cmdl[1] -case --diff-cmd -if set -q cmdl[2] -set diff $cmdl[2] -set -e cmd[2] -end + set -l cmdl (commandline -cop) + #set -l cmdl svn diff --diff-cmd diff --extensions '-a -b' + set -l diff diff + set -l args + while set -q cmdl[1] + switch $cmdl[1] + case --diff-cmd + if set -q cmdl[2] + set diff $cmdl[2] + set -e cmd[2] + end -case --extensions -if set -q cmdl[2] -set args $cmdl[2] -set -e cmdl[2] -end -end -set -e cmdl[1] -end -set -l token (commandline -cpt) -complete -C"$diff $args $token" + case --extensions + if set -q cmdl[2] + set args $cmdl[2] + set -e cmdl[2] + end + end + set -e cmdl[1] + end + set -l token (commandline -cpt) + complete -C"$diff $args $token" end diff --git a/share/functions/__fish_complete_tar.fish b/share/functions/__fish_complete_tar.fish index 91a795015..f7f654a0e 100644 --- a/share/functions/__fish_complete_tar.fish +++ b/share/functions/__fish_complete_tar.fish @@ -1,35 +1,42 @@ function __fish_complete_tar -d "Peek inside of archives and list all files" - set -l cmd (commandline -poc) - set -e cmd[1] - for i in $cmd - switch $i - case '-*' - continue + set -l cmd (commandline -poc) + set -e cmd[1] + for i in $cmd + switch $i + case '-*' + continue - case '*.tar.bz' '*.tar.bz2' '*.tbz' '*.tbz2' - if test -f $i - set -l file_list (tar -jt <$i) - printf (_ "%s\tArchived file\n") $file_list - end - return + case '*.tar.bz' '*.tar.bz2' '*.tbz' '*.tbz2' + if test -f $i + set -l file_list (tar -jt <$i) + printf (_ "%s\tArchived file\n") $file_list + end + return - case '*.tar.gz' '*.tgz' - if test -f $i - set -l file_list (tar -it <$i) - printf (_ "%s\tArchived file\n") $file_list - end - return + case '*.tar.gz' '*.tgz' + if test -f $i + set -l file_list (tar -it <$i) + printf (_ "%s\tArchived file\n") $file_list + end + return - case '*.tar' - if test -f $i - set -l file_list (tar -t <$i) - printf (_ "%s\tArchived file\n") $file_list - end - return - end - end + case '*.tar.xz' + if test -f $i + set -l file_list (tar -Jt <$i) + printf (_ "%s\tArchived file\n") $file_list + end + return + + case '*.tar' + if test -f $i + set -l file_list (tar -t <$i) + printf (_ "%s\tArchived file\n") $file_list + end + return + end + end end diff --git a/share/functions/__fish_complete_unrar.fish b/share/functions/__fish_complete_unrar.fish index 1c86794e5..c5cbc7ad9 100644 --- a/share/functions/__fish_complete_unrar.fish +++ b/share/functions/__fish_complete_unrar.fish @@ -1,21 +1,21 @@ function __fish_complete_unrar -d "Peek inside of archives and list all files" - set -l cmd (commandline -poc) - set -e cmd[1] - for i in $cmd - switch $i - case '-*' - continue + set -l cmd (commandline -poc) + set -e cmd[1] + for i in $cmd + switch $i + case '-*' + continue - case '*.rar' - if test -f $i - set -l file_list (unrar vb $i) - printf (_ "%s\tArchived file\n") $file_list - end - return - end - end + case '*.rar' + if test -f $i + set -l file_list (unrar vb $i) + printf (_ "%s\tArchived file\n") $file_list + end + return + end + end end diff --git a/share/functions/__fish_complete_users.fish b/share/functions/__fish_complete_users.fish index 199231be1..f7002fe21 100644 --- a/share/functions/__fish_complete_users.fish +++ b/share/functions/__fish_complete_users.fish @@ -1,10 +1,10 @@ function __fish_complete_users --description "Print a list of local users, with the real user name as a description" - if test -x /usr/bin/getent - getent passwd | cut -d : -f 1,5 | string replace -r ':' \t - else if test -x /usr/bin/dscl - dscl . -list /Users RealName | string match -r -v '^_' | string replace -r ' {2,}' \t - else - string match -v -r '^\s*#' < /etc/passwd | cut -d : -f 1,5 | string replace ':' \t - end + if test -x /usr/bin/getent + getent passwd | cut -d : -f 1,5 | string replace -r ':' \t + else if test -x /usr/bin/dscl + dscl . -list /Users RealName | string match -r -v '^_' | string replace -r ' {2,}' \t + else + string match -v -r '^\s*#' /dev/null ^/dev/null' &" + # Generating completions from man pages needs python (see issue #3588). + # Don't do this if we're being invoked as part of running unit tests. + if command -qs python + and not set -q FISH_UNIT_TESTS_RUNNING + # We cannot simply do `fish_update_completions &` because it is a function. Hence the + # need for the convoluted `eval` to run it in a subshell. + eval (string escape "$__fish_bin_dir/fish") "-c 'fish_update_completions >/dev/null ^/dev/null' &" + end end # @@ -179,8 +185,11 @@ function __fish_config_interactive -d "Initializations that should be performed # Also print an error so the user knows if not functions -q "$fish_key_bindings" echo "There is no fish_key_bindings function called: '$fish_key_bindings'" >&2 - if set -q __fish_active_key_bindings + # We need to see if this is a defined function, otherwise we'd be in an endless loop. + if functions -q $__fish_active_key_bindings echo "Keeping $__fish_active_key_bindings" >&2 + # Set the variable to the old value so this error doesn't happen again. + set fish_key_bindings $__fish_active_key_bindings return 1 else if functions -q fish_default_key_bindings echo "Reverting to default bindings" >&2 @@ -228,8 +237,10 @@ function __fish_config_interactive -d "Initializations that should be performed end if test "$TERM_PROGRAM" = "Apple_Terminal" # Suppress duplicative title display on Terminal.app - echo -n \e\]0\;\a # clear existing title - function fish_title + if not functions -q fish_title + echo -n \e\]0\;\a # clear existing title + function fish_title -d 'no-op terminal title' + end end end __update_cwd_osc # Run once because we might have already inherited a PWD from an old tab diff --git a/share/functions/__fish_contains_opt.fish b/share/functions/__fish_contains_opt.fish index cc66a9e75..8e35aa365 100644 --- a/share/functions/__fish_contains_opt.fish +++ b/share/functions/__fish_contains_opt.fish @@ -1,53 +1,53 @@ function __fish_contains_opt -d "Checks if a specific option has been given in the current commandline" - set -l next_short + set -l next_short - set -l short_opt - set -l long_opt + set -l short_opt + set -l long_opt - for i in $argv - if test $next_short - set next_short - set short_opt $short_opt $i - else - switch $i - case -s - set next_short 1 - case '-*' - echo __fish_contains_opt: Unknown option $i - return 1 + for i in $argv + if test $next_short + set next_short + set short_opt $short_opt $i + else + switch $i + case -s + set next_short 1 + case '-*' + echo __fish_contains_opt: Unknown option $i + return 1 - case '**' - set long_opt $long_opt $i - end - end - end + case '**' + set long_opt $long_opt $i + end + end + end - for i in $short_opt + for i in $short_opt - if test -z $i - continue - end + if test -z $i + continue + end - if commandline -cpo | __fish_sgrep -- "^-"$i"\|^-[^-]*"$i >/dev/null - return 0 - end + if commandline -cpo | __fish_sgrep -- "^-"$i"\|^-[^-]*"$i >/dev/null + return 0 + end - if commandline -ct | __fish_sgrep -- "^-"$i"\|^-[^-]*"$i >/dev/null - return 0 - end - end + if commandline -ct | __fish_sgrep -- "^-"$i"\|^-[^-]*"$i >/dev/null + return 0 + end + end - for i in $long_opt - if test -z $i - continue - end + for i in $long_opt + if test -z $i + continue + end - if contains -- --$i (commandline -cpo) - return 0 - end - end + if contains -- --$i (commandline -cpo) + return 0 + end + end - return 1 + return 1 end diff --git a/share/functions/__fish_crux_packages.fish b/share/functions/__fish_crux_packages.fish index fa96e4803..904d1b863 100644 --- a/share/functions/__fish_crux_packages.fish +++ b/share/functions/__fish_crux_packages.fish @@ -1,4 +1,4 @@ # a function to obtain a list of installed packages with CRUX pkgutils function __fish_crux_packages -d 'Obtain a list of installed packages' - pkginfo -i|cut -d' ' -f1 + pkginfo -i | cut -d' ' -f1 end diff --git a/share/functions/__fish_cursor_1337.fish b/share/functions/__fish_cursor_1337.fish new file mode 100644 index 000000000..ec32ff434 --- /dev/null +++ b/share/functions/__fish_cursor_1337.fish @@ -0,0 +1,13 @@ +# Set the cursor using the '\e]1337;' sequence recognized by iTerm2 on macOS and possibly other +# terminals. +function __fish_cursor_1337 -d 'Set cursor using OSC command 1337' + set -l shape $argv[1] + switch "$shape" + case block + echo -en '\e]1337;CursorShape=0\x7' + case underscore + echo -en '\e]1337;CursorShape=2\x7' + case line + echo -en '\e]1337;CursorShape=1\x7' + end +end diff --git a/share/functions/__fish_cursor_konsole.fish b/share/functions/__fish_cursor_konsole.fish index ef7c777b8..e6941a451 100644 --- a/share/functions/__fish_cursor_konsole.fish +++ b/share/functions/__fish_cursor_konsole.fish @@ -1,11 +1,11 @@ function __fish_cursor_konsole -d 'Set cursor (konsole)' - set -l shape $argv[1] - switch "$shape" - case block - echo -en '\e]50;CursorShape=0\x7' - case underscore - echo -en '\e]50;CursorShape=2\x7' - case line - echo -en '\e]50;CursorShape=1\x7' - end + set -l shape $argv[1] + switch "$shape" + case block + echo -en '\e]50;CursorShape=0\x7' + case underscore + echo -en '\e]50;CursorShape=2\x7' + case line + echo -en '\e]50;CursorShape=1\x7' + end end diff --git a/share/functions/__fish_cursor_xterm.fish b/share/functions/__fish_cursor_xterm.fish index c7dd1690f..7a964ba99 100644 --- a/share/functions/__fish_cursor_xterm.fish +++ b/share/functions/__fish_cursor_xterm.fish @@ -1,16 +1,16 @@ function __fish_cursor_xterm -d 'Set cursor (xterm)' - set -l shape $argv[1] + set -l shape $argv[1] - switch "$shape" - case block - set shape 2 - case underscore - set shape 4 - case line - set shape 6 - end - if contains blink $argv - set shape (math $shape - 1) - end - echo -en "\e[$shape q" + switch "$shape" + case block + set shape 2 + case underscore + set shape 4 + case line + set shape 6 + end + if contains blink $argv + set shape (math $shape - 1) + end + echo -en "\e[$shape q" end diff --git a/share/functions/__fish_describe_command.fish b/share/functions/__fish_describe_command.fish index 76971e739..df2efc8d5 100644 --- a/share/functions/__fish_describe_command.fish +++ b/share/functions/__fish_describe_command.fish @@ -3,7 +3,7 @@ # function __fish_describe_command -d "Command used to find descriptions for commands" - apropos $argv ^/dev/null | awk -v FS=" +- +" '{ + apropos $argv ^/dev/null | awk -v FS=" +- +" '{ split($1, names, ", "); for (name in names) if (names[name] ~ /^'"$argv"'.* *\([18]\)/ ) { diff --git a/share/functions/__fish_filter_ant_targets.fish b/share/functions/__fish_filter_ant_targets.fish index 28ce2eb11..242cdb0bc 100644 --- a/share/functions/__fish_filter_ant_targets.fish +++ b/share/functions/__fish_filter_ant_targets.fish @@ -1,3 +1,3 @@ function __fish_filter_ant_targets -d "Display targets within an ant build.xml file" - sed -n "s/^.*]* name=[\"']\([^\"']*\)[\"'].*\$/\1/p" < $argv[1] + sed -n "s/^.*]* name=[\"']\([^\"']*\)[\"'].*\$/\1/p" <$argv[1] end diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index e1ea3476d..0a98f4fd8 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -472,11 +472,11 @@ set -g ___fish_git_prompt_status_order stagedstate invalidstate dirtystate untra function __fish_git_prompt_informative_status - set -l changedFiles (command git diff --name-status | cut -c 1-2) - set -l stagedFiles (command git diff --staged --name-status | cut -c 1-2) + set -l changedFiles (command git diff --name-status | string match -r \\w) + set -l stagedFiles (command git diff --staged --name-status | string match -r \\w) - set -l dirtystate (math (count $changedFiles) - (count (echo $changedFiles | grep "U")) ^/dev/null) - set -l invalidstate (count (echo $stagedFiles | grep "U")) + set -l dirtystate (math (count $changedFiles) - (count (string match -r "U" -- $changedFiles)) ^/dev/null) + set -l invalidstate (count (string match -r "U" -- $stagedFiles)) set -l stagedstate (math (count $stagedFiles) - $invalidstate ^/dev/null) set -l untrackedfiles (command git ls-files --others --exclude-standard | wc -l | string trim) @@ -484,7 +484,8 @@ function __fish_git_prompt_informative_status # If `math` fails for some reason, assume the state is clean - it's the simpler path set -l state (math $dirtystate + $invalidstate + $stagedstate + $untrackedfiles ^/dev/null) - if test -z "$state"; or test "$state" = 0 + if test -z "$state" + or test "$state" = 0 set info $___fish_git_prompt_color_cleanstate$___fish_git_prompt_char_cleanstate$___fish_git_prompt_color_cleanstate_done else for i in $___fish_git_prompt_status_order diff --git a/share/functions/__fish_gnu_complete.fish b/share/functions/__fish_gnu_complete.fish index 62e6dde3e..2fa60edaf 100644 --- a/share/functions/__fish_gnu_complete.fish +++ b/share/functions/__fish_gnu_complete.fish @@ -1,52 +1,52 @@ function __fish_gnu_complete -d "Wrapper for the complete built-in. Skips the long completions on non-GNU systems" - set is_gnu 0 + set is_gnu 0 - set -l argv_out + set -l argv_out - # Check if we are using a gnu system - for i in $argv - switch $i + # Check if we are using a gnu system + for i in $argv + switch $i - case -g --is-gnu - set is_gnu 1 + case -g --is-gnu + set is_gnu 1 - case '*' - set argv_out $argv_out $i - end - end + case '*' + set argv_out $argv_out $i + end + end - set argv $argv_out - set argv_out - set -l skip_next 0 + set argv $argv_out + set argv_out + set -l skip_next 0 - # Remove long option if not on a gnu system - switch $is_gnu - case 0 - for i in $argv + # Remove long option if not on a gnu system + switch $is_gnu + case 0 + for i in $argv - switch $skip_next + switch $skip_next - case 1 - set skip_next 0 - continue + case 1 + set skip_next 0 + continue - end + end - switch $i + switch $i - case -l --long - set skip_next 1 - continue + case -l --long + set skip_next 1 + continue - end + end - set argv_out $argv_out $i - end - set argv $argv_out + set argv_out $argv_out $i + end + set argv $argv_out - end + end - complete $argv + complete $argv end diff --git a/share/functions/__fish_hg_prompt.fish b/share/functions/__fish_hg_prompt.fish index b40e70a24..831f37e47 100644 --- a/share/functions/__fish_hg_prompt.fish +++ b/share/functions/__fish_hg_prompt.fish @@ -23,7 +23,7 @@ set -g fish_prompt_hg_status_order added modified copied deleted untracked unmer function __fish_hg_prompt --description 'Write out the hg prompt' # If hg isn't installed, there's nothing we can do # Return 1 so the calling prompt can deal with it - if not command -s hg > /dev/null + if not command -s hg >/dev/null return 1 end @@ -69,12 +69,18 @@ function __fish_hg_prompt --description 'Write out the hg prompt' # Add a character for each file status if we have one switch $line - case 'A ' ; set hg_statuses $hg_statuses added - case 'M ' ' M' ; set hg_statuses $hg_statuses modified - case 'C ' ; set hg_statuses $hg_statuses copied - case 'D ' ' D' ; set hg_statuses $hg_statuses deleted - case '\? ' ; set hg_statuses $hg_statuses untracked - case 'U*' '*U' 'DD' 'AA'; set hg_statuses $hg_statuses unmerged + case 'A ' + set hg_statuses $hg_statuses added + case 'M ' ' M' + set hg_statuses $hg_statuses modified + case 'C ' + set hg_statuses $hg_statuses copied + case 'D ' ' D' + set hg_statuses $hg_statuses deleted + case '\? ' + set hg_statuses $hg_statuses untracked + case 'U*' '*U' 'DD' 'AA' + set hg_statuses $hg_statuses unmerged end end diff --git a/share/functions/__fish_is_first_token.fish b/share/functions/__fish_is_first_token.fish index 6f943ea78..70aeb7951 100644 --- a/share/functions/__fish_is_first_token.fish +++ b/share/functions/__fish_is_first_token.fish @@ -1,15 +1,16 @@ function __fish_is_first_token -d 'Test if no non-switch argument has been specified yet' - set cmd (commandline -poc) - set -e cmd[1] - for i in $cmd - switch $i - case '-*' + set cmd (commandline -poc) + set -e cmd[1] + for i in $cmd + switch $i + case '-*' - case '*' - return 1; - end - end - return 0 + case '*' + return 1 + + end + end + return 0 end diff --git a/share/functions/__fish_is_token_n.fish b/share/functions/__fish_is_token_n.fish index c6069bde1..eccd9ace2 100644 --- a/share/functions/__fish_is_token_n.fish +++ b/share/functions/__fish_is_token_n.fish @@ -1,5 +1,5 @@ function __fish_is_token_n --description 'Test if current token is on Nth place' --argument n - # Add a fake element to increment without calling math - set -l num (count (commandline -poc) additionalelement) - test $n -eq $num + # Add a fake element to increment without calling math + set -l num (count (commandline -poc) additionalelement) + test $n -eq $num end diff --git a/share/functions/__fish_make_completion_signals.fish b/share/functions/__fish_make_completion_signals.fish index e9dabf77c..2dd88ac47 100644 --- a/share/functions/__fish_make_completion_signals.fish +++ b/share/functions/__fish_make_completion_signals.fish @@ -11,7 +11,8 @@ function __fish_make_completion_signals --description 'Make list of kill signals # The procps `kill -L` produces a more compact table. We can distinguish the two cases by # testing whether it supports `kill -t`; in which case it is the coreutils `kill` command. # Darwin doesn't have kill -t or kill -L - if kill -t ^/dev/null >/dev/null; or not kill -L ^/dev/null >/dev/null + if kill -t ^/dev/null >/dev/null + or not kill -L ^/dev/null >/dev/null # Posix systems print out the name of a signal using 'kill -l SIGNUM'. complete -c kill -s l --description "List names of available signals" for i in (seq 31) @@ -24,7 +25,7 @@ function __fish_make_completion_signals --description 'Make list of kill signals set -g __kill_signals kill -L | sed -e 's/^ //; s/ */ /g; y/ /\n/' | while read -l signo test -z "$signo" - and break # the sed above produces one blank line at the end + and break # the sed above produces one blank line at the end read -l signame set -g __kill_signals $__kill_signals "$signo $signame" end diff --git a/share/functions/__fish_man_page.fish b/share/functions/__fish_man_page.fish index 17a903153..8bc32b76f 100644 --- a/share/functions/__fish_man_page.fish +++ b/share/functions/__fish_man_page.fish @@ -1,4 +1,24 @@ function __fish_man_page - man (basename (commandline -po; echo)[1]) ^/dev/null - or printf \a + # Get all commandline tokens not starting with "-" + set -l args (commandline -po | string match -rv '^-') + + # If commandline is empty, exit. + if not set -q args[1] + printf \a + return + end + + # If there are at least two tokens not starting with "-", the second one might be a subcommand. + # Try "man first-second" and fall back to "man first" if that doesn't work out. + set -l maincmd (basename $args[1]) + if set -q args[2] + man "$maincmd-$args[2]" ^/dev/null + or man "$maincmd" ^/dev/null + or printf \a + else + man "$maincmd" ^/dev/null + or printf \a + end + + commandline -f repaint end diff --git a/share/functions/__fish_move_last.fish b/share/functions/__fish_move_last.fish index 4646561f8..b9c57d805 100644 --- a/share/functions/__fish_move_last.fish +++ b/share/functions/__fish_move_last.fish @@ -1,27 +1,27 @@ function __fish_move_last -d "Move the last element of a directory history from src to dest" - set -l src $argv[1] - set -l dest $argv[2] + set -l src $argv[1] + set -l dest $argv[2] - set -l size_src (count $$src) + set -l size_src (count $$src) - if test $size_src = 0 - # Cannot make this step - printf (_ "Hit end of history…\n") - return 1 - end + if test $size_src = 0 + # Cannot make this step + printf (_ "Hit end of history…\n") + return 1 + end - # Append current dir to the end of the destination - set -g (echo $dest) $$dest (command pwd) + # Append current dir to the end of the destination + set -g (echo $dest) $$dest (command pwd) - set ssrc $$src + set ssrc $$src - # Change dir to the last entry in the source dir-hist - builtin cd $ssrc[$size_src] + # Change dir to the last entry in the source dir-hist + builtin cd $ssrc[$size_src] - # Keep all but the last from the source dir-hist - set -e (echo $src)\[$size_src] + # Keep all but the last from the source dir-hist + set -e (echo $src)\[$size_src] - # All ok, return success - return 0 + # All ok, return success + return 0 end diff --git a/share/functions/__fish_no_arguments.fish b/share/functions/__fish_no_arguments.fish index b2ce27814..cb21fcf96 100644 --- a/share/functions/__fish_no_arguments.fish +++ b/share/functions/__fish_no_arguments.fish @@ -1,15 +1,15 @@ function __fish_no_arguments -d "Internal fish function" - set -l cmd (commandline -poc) (commandline -tc) - set -e cmd[1] - for i in $cmd - switch $i - case '-*' + set -l cmd (commandline -poc) (commandline -tc) + set -e cmd[1] + for i in $cmd + switch $i + case '-*' - case '*' - return 1 - end - end - return 0 + case '*' + return 1 + end + end + return 0 end diff --git a/share/functions/__fish_not_contain_opt.fish b/share/functions/__fish_not_contain_opt.fish index da8d029c7..933e5eec7 100644 --- a/share/functions/__fish_not_contain_opt.fish +++ b/share/functions/__fish_not_contain_opt.fish @@ -1,51 +1,51 @@ function __fish_not_contain_opt -d "Checks that a specific option is not in the current command line" - set -l next_short + set -l next_short - set -l short_opt - set -l long_opt + set -l short_opt + set -l long_opt - for i in $argv - if test $next_short - set next_short - set short_opt $short_opt $i - else - switch $i - case -s - set next_short 1 - case '-*' - echo __fish_contains_opt: Unknown option $i - return 1 + for i in $argv + if test $next_short + set next_short + set short_opt $short_opt $i + else + switch $i + case -s + set next_short 1 + case '-*' + echo __fish_contains_opt: Unknown option $i + return 1 - case '**' - set long_opt $long_opt $i - end - end - end + case '**' + set long_opt $long_opt $i + end + end + end - for i in $short_opt + for i in $short_opt - if test -z $i - continue - end + if test -z $i + continue + end - if commandline -cpo | __fish_sgrep -- "^-"$i"\|^-[^-]*"$i >/dev/null - return 1 - end + if commandline -cpo | __fish_sgrep -- "^-"$i"\|^-[^-]*"$i >/dev/null + return 1 + end - if commandline -ct | __fish_sgrep -- "^-"$i"\|^-[^-]*"$i >/dev/null - return 1 - end - end + if commandline -ct | __fish_sgrep -- "^-"$i"\|^-[^-]*"$i >/dev/null + return 1 + end + end - for i in $long_opt - if test -z $i - continue - end + for i in $long_opt + if test -z $i + continue + end - if contains -- --$i (commandline -cpo) - return 1 - end - end + if contains -- --$i (commandline -cpo) + return 1 + end + end - return 0 + return 0 end diff --git a/share/functions/__fish_paginate.fish b/share/functions/__fish_paginate.fish index 31cdd61fa..95390ac53 100644 --- a/share/functions/__fish_paginate.fish +++ b/share/functions/__fish_paginate.fish @@ -1,13 +1,13 @@ function __fish_paginate -d "Paginate the current command using the users default pager" - set -l cmd less - if set -q PAGER - set cmd $PAGER - end + set -l cmd less + if set -q PAGER + set cmd $PAGER + end - if commandline -j| string match -q -r -v "$cmd *\$" + if commandline -j | string match -q -r -v "$cmd *\$" - commandline -aj " ^&1 |$cmd;" - end + commandline -aj " ^&1 |$cmd;" + end end diff --git a/share/functions/__fish_ports_dirs.fish b/share/functions/__fish_ports_dirs.fish index 969569f95..f4d3dc3bf 100644 --- a/share/functions/__fish_ports_dirs.fish +++ b/share/functions/__fish_ports_dirs.fish @@ -1,5 +1,5 @@ # a function to print a list of ports local collections function __fish_ports_dirs -d 'Obtain a list of ports local collections' - ls /usr/ports + ls /usr/ports end diff --git a/share/functions/__fish_print_VBox_vms.fish b/share/functions/__fish_print_VBox_vms.fish new file mode 100644 index 000000000..3f7e04329 --- /dev/null +++ b/share/functions/__fish_print_VBox_vms.fish @@ -0,0 +1,29 @@ +function __fish_print_VBox_vms + set -l print_names true + set -l print_uuids true + + if contains -- nouuids $argv + set print_uuids false + end + + if contains -- nonames $argv + set print_names false + end + + # `VBoxManage list vms` output example: + # "Machine Name" {222537b0-1ea1-454a-abf0-ed0d6c3c6346} + # "Another Machine" {332537b4-1ea1-454a-abf0-ed1d6c3c2347} + set -l lines (VBoxManage list vms | string match -r '"(.*)" {(.*)}') + + while set -q lines[3] + if test $print_names = true + printf '%s\tVirtual machine\n' $lines[2] + end + + if test $print_uuids = true + printf '%s\t%s virtual machine\n' $lines[3] $lines[2] + end + + set -e lines[1..3] + end +end diff --git a/share/functions/__fish_print_abook_emails.fish b/share/functions/__fish_print_abook_emails.fish index f32b2aed6..671dbb50e 100644 --- a/share/functions/__fish_print_abook_emails.fish +++ b/share/functions/__fish_print_abook_emails.fish @@ -1,4 +1,4 @@ function __fish_print_abook_emails --description 'Print email addresses (abook)' - abook --mutt-query "" | string match -r -v '^\s*$' + abook --mutt-query "" | string match -r -v '^\s*$' end diff --git a/share/functions/__fish_print_addresses.fish b/share/functions/__fish_print_addresses.fish index fd8c60351..ddc9ef5c1 100644 --- a/share/functions/__fish_print_addresses.fish +++ b/share/functions/__fish_print_addresses.fish @@ -1,11 +1,11 @@ function __fish_print_addresses --description "Print a list of known network addresses" - if command -s ip >/dev/null - command ip --oneline address | cut -d" " -f7 | sed "s:\(.*\)/.*:\1:" - else if command -s ifconfig >/dev/null - # This is for OSX/BSD - # There's also linux ifconfig but that has at least two different output formats - # is basically dead, and ip is installed on everything now - ifconfig | awk '/^\tinet/ { print $2 } ' - end + if command -s ip >/dev/null + command ip --oneline address | cut -d" " -f7 | sed "s:\(.*\)/.*:\1:" + else if command -s ifconfig >/dev/null + # This is for OSX/BSD + # There's also linux ifconfig but that has at least two different output formats + # is basically dead, and ip is installed on everything now + ifconfig | awk '/^\tinet/ { print $2 } ' + end end diff --git a/share/functions/__fish_print_arch_daemons.fish b/share/functions/__fish_print_arch_daemons.fish index 681a9546d..3a683c149 100644 --- a/share/functions/__fish_print_arch_daemons.fish +++ b/share/functions/__fish_print_arch_daemons.fish @@ -1,4 +1,4 @@ function __fish_print_arch_daemons --description 'Print arch daemons' - find /etc/rc.d/ -executable -type f -printf '%f\n' + find /etc/rc.d/ -executable -type f -printf '%f\n' end diff --git a/share/functions/__fish_print_debian_apache_confs.fish b/share/functions/__fish_print_debian_apache_confs.fish index c593bc999..39d732e19 100644 --- a/share/functions/__fish_print_debian_apache_confs.fish +++ b/share/functions/__fish_print_debian_apache_confs.fish @@ -1,6 +1,6 @@ function __fish_print_debian_apache_confs - # Helper script for completions for a2enconf/a2disconf - for conf in /etc/apache2/conf-available/*.conf - basename "$conf" .conf - end + # Helper script for completions for a2enconf/a2disconf + for conf in /etc/apache2/conf-available/*.conf + basename "$conf" .conf + end end diff --git a/share/functions/__fish_print_debian_apache_mods.fish b/share/functions/__fish_print_debian_apache_mods.fish index 4e41623ac..36a1fb984 100644 --- a/share/functions/__fish_print_debian_apache_mods.fish +++ b/share/functions/__fish_print_debian_apache_mods.fish @@ -1,6 +1,6 @@ function __fish_print_debian_apache_mods - # Helper script for completions for a2enmod/a2dismod - for mod in /etc/apache2/mods-available/*.load - basename "$mod" .load - end + # Helper script for completions for a2enmod/a2dismod + for mod in /etc/apache2/mods-available/*.load + basename "$mod" .load + end end diff --git a/share/functions/__fish_print_debian_apache_sites.fish b/share/functions/__fish_print_debian_apache_sites.fish index 08436a3ef..d3f1bbe37 100644 --- a/share/functions/__fish_print_debian_apache_sites.fish +++ b/share/functions/__fish_print_debian_apache_sites.fish @@ -1,6 +1,6 @@ function __fish_print_debian_apache_sites - # Helper script for completions for a2ensite/a2dissite - for site in /etc/apache2/sites-available/* - basename "$site" .conf - end + # Helper script for completions for a2ensite/a2dissite + for site in /etc/apache2/sites-available/* + basename "$site" .conf + end end diff --git a/share/functions/__fish_print_debian_services.fish b/share/functions/__fish_print_debian_services.fish index 378e6e39b..394c1e850 100644 --- a/share/functions/__fish_print_debian_services.fish +++ b/share/functions/__fish_print_debian_services.fish @@ -1,7 +1,7 @@ function __fish_print_debian_services --description 'Prints services installed' - for service in /etc/init.d/* - if [ -x $service ] - basename $service + for service in /etc/init.d/* + if [ -x $service ] + basename $service + end end - end end diff --git a/share/functions/__fish_print_encodings.fish b/share/functions/__fish_print_encodings.fish index 5770330b4..f5507d882 100644 --- a/share/functions/__fish_print_encodings.fish +++ b/share/functions/__fish_print_encodings.fish @@ -1,3 +1,3 @@ function __fish_print_encodings -d "Complete using available character encodings" - iconv --list|sed -e 's|//||' + iconv --list | sed -e 's|//||' end diff --git a/share/functions/__fish_print_filesystems.fish b/share/functions/__fish_print_filesystems.fish index c08a6da89..8dbadc7f4 100644 --- a/share/functions/__fish_print_filesystems.fish +++ b/share/functions/__fish_print_filesystems.fish @@ -1,9 +1,9 @@ function __fish_print_filesystems -d "Print a list of all known filesystem types" - set -l fs adfs affs autofs coda coherent cramfs devpts efs ext ext2 ext3 - set fs $fs hfs hpfs iso9660 jfs minix msdos ncpfs nfs ntfs proc qnx4 ramfs - set fs $fs reiserfs romfs smbfs sysv tmpfs udf ufs umsdos vfat xenix xfs xiafs - # Mount has helper binaries to mount filesystems - # These are called mount.* and are placed somewhere in $PATH - printf "%s\n" $fs (string replace -ra ".*/mount." "" -- $PATH/mount.*) + set -l fs adfs affs autofs coda coherent cramfs devpts efs ext ext2 ext3 + set fs $fs hfs hpfs iso9660 jfs minix msdos ncpfs nfs ntfs proc qnx4 ramfs + set fs $fs reiserfs romfs smbfs sysv tmpfs udf ufs umsdos vfat xenix xfs xiafs + # Mount has helper binaries to mount filesystems + # These are called mount.* and are placed somewhere in $PATH + printf "%s\n" $fs (string replace -ra ".*/mount." "" -- $PATH/mount.*) end diff --git a/share/functions/__fish_print_function_prototypes.fish b/share/functions/__fish_print_function_prototypes.fish index 148713523..d50c43d6d 100644 --- a/share/functions/__fish_print_function_prototypes.fish +++ b/share/functions/__fish_print_function_prototypes.fish @@ -1,5 +1,8 @@ function __fish_print_function_prototypes -d "Prints the names of all function prototypes found in the headers in the current directory" - cat *.h*|sed -n "s/^\(.*[^[a-zA-Z_0-9]\|\)\([a-zA-Z_][a-zA-Z_0-9]*\) *(.*);.*\$/\2/p" + set -l headers *.h *.hh *.hpp *.hxx + if set -q headers[1] + sed -n "s/^\(.*[^[a-zA-Z_0-9]\|\)\([a-zA-Z_][a-zA-Z_0-9]*\) *(.*);.*\$/\2/p" $headers + end end diff --git a/share/functions/__fish_print_help.fish b/share/functions/__fish_print_help.fish index 31190e552..30692ee3b 100644 --- a/share/functions/__fish_print_help.fish +++ b/share/functions/__fish_print_help.fish @@ -1,104 +1,104 @@ function __fish_print_help --description "Print help message for the specified fish function or builtin" --argument item - # special support for builtin_help_get() - set -l tty_width - if test "$item" = "--tty-width" - set tty_width $argv[2] - set item $argv[3] - end - - if test "$item" = '.' - set item source - end - - # Do nothing if the file does not exist - if not test -e "$__fish_datadir/man/man1/$item.1" -o -e "$__fish_datadir/man/man1/$item.1.gz" - return - end - - set -l IFS \n\ \t - - # Render help output, save output into the variable 'help' - set -l help - set -l cols - set -l rLL - if test "$tty_width" -gt 0 - set cols $tty_width - else if command test -t 1 - # We want to simulate `man`'s dynamic line length, because - # defaulting to 80 kind of sucks. - # Note: using `command test` instead of `test` because `test -t 1` - # doesn't seem to work right. - # Note: grab the size from the stdout terminal in case it's somehow - # different than the stdin of fish. - # use fd 3 to copy our stdout because we need to pipe the output of stty - begin - stty size 0<&3 | read __ cols - end 3<&1 - end - if test -n "$cols" - set cols (math $cols - 4) # leave a bit of space on the right - set rLL -rLL=$cols[1]n - end - set -lx GROFF_TMAC_PATH $__fish_datadir/groff - if test -e "$__fish_datadir/man/man1/$item.1" - set help (nroff -c -man -mfish -t $rLL "$__fish_datadir/man/man1/$item.1" ^/dev/null) - else if test -e "$__fish_datadir/man/man1/$item.1.gz" - set help (gunzip -c "$__fish_datadir/man/man1/$item.1.gz" ^/dev/null | nroff -c -man -mfish -t $rLL ^/dev/null) + # special support for builtin_help_get() + set -l tty_width 0 + if test "$item" = "--tty-width" + set tty_width $argv[2] + set item $argv[3] end - # The original implementation trimmed off the top 5 lines and bottom 3 lines - # from the nroff output. Perhaps that's reliable, but the magic numbers make - # me extremely nervous. Instead, let's just strip out any lines that start - # in the first column. "normal" manpages put all section headers in the first - # column, but fish manpages only leave NAME like that, which we want to trim - # away anyway. - # - # While we're at it, let's compress sequences of blank lines down to a single - # blank line, to duplicate the default behavior of `man`, or more accurately, - # the `-s` flag to `less` that `man` passes. - set -l state blank - for line in $help - # categorize the line - set -l line_type - switch $line - case ' *' \t\* - # starts with whitespace, check if it has non-whitespace - printf "%s\n" $line | read -l word __ - if test -n $word - set line_type normal - else - # lines with just spaces probably shouldn't happen - # but let's consider them to be blank - set line_type blank - end - case '' - set line_type blank - case '*' - # not leading space, and not empty, so must contain a non-space - # in the first column. That makes it a header/footer. - set line_type meta - end + if test "$item" = '.' + set item source + end - switch $state - case normal - switch $line_type - case normal - printf "%s\n" $line - case blank - set state blank - case meta - # skip it - end - case blank - switch $line_type - case normal - echo # print the blank line - printf "%s\n" $line - set state normal - case blank meta - # skip it - end - end - end | ul # post-process with `ul`, to interpret the old-style grotty escapes - echo # print a trailing blank line + # Do nothing if the file does not exist + if not test -e "$__fish_datadir/man/man1/$item.1" -o -e "$__fish_datadir/man/man1/$item.1.gz" + return + end + + set -l IFS \n\ \t + + # Render help output, save output into the variable 'help' + set -l help + set -l cols + set -l rLL + if test "$tty_width" -gt 0 + set cols $tty_width + else if command test -t 1 + # We want to simulate `man`'s dynamic line length, because + # defaulting to 80 kind of sucks. + # Note: using `command test` instead of `test` because `test -t 1` + # doesn't seem to work right. + # Note: grab the size from the stdout terminal in case it's somehow + # different than the stdin of fish. + # use fd 3 to copy our stdout because we need to pipe the output of stty + begin + stty size 0<&3 | read __ cols + end 3<&1 + end + if test -n "$cols" + set cols (math $cols - 4) # leave a bit of space on the right + set rLL -rLL=$cols[1]n + end + set -lx GROFF_TMAC_PATH $__fish_datadir/groff + if test -e "$__fish_datadir/man/man1/$item.1" + set help (nroff -c -man -mfish -t $rLL "$__fish_datadir/man/man1/$item.1" ^/dev/null) + else if test -e "$__fish_datadir/man/man1/$item.1.gz" + set help (gunzip -c "$__fish_datadir/man/man1/$item.1.gz" ^/dev/null | nroff -c -man -mfish -t $rLL ^/dev/null) + end + + # The original implementation trimmed off the top 5 lines and bottom 3 lines + # from the nroff output. Perhaps that's reliable, but the magic numbers make + # me extremely nervous. Instead, let's just strip out any lines that start + # in the first column. "normal" manpages put all section headers in the first + # column, but fish manpages only leave NAME like that, which we want to trim + # away anyway. + # + # While we're at it, let's compress sequences of blank lines down to a single + # blank line, to duplicate the default behavior of `man`, or more accurately, + # the `-s` flag to `less` that `man` passes. + set -l state blank + for line in $help + # categorize the line + set -l line_type + switch $line + case ' *' \t\* + # starts with whitespace, check if it has non-whitespace + printf "%s\n" $line | read -l word __ + if test -n $word + set line_type normal + else + # lines with just spaces probably shouldn't happen + # but let's consider them to be blank + set line_type blank + end + case '' + set line_type blank + case '*' + # not leading space, and not empty, so must contain a non-space + # in the first column. That makes it a header/footer. + set line_type meta + end + + switch $state + case normal + switch $line_type + case normal + printf "%s\n" $line + case blank + set state blank + case meta + # skip it + end + case blank + switch $line_type + case normal + echo # print the blank line + printf "%s\n" $line + set state normal + case blank meta + # skip it + end + end + end | ul # post-process with `ul`, to interpret the old-style grotty escapes + echo # print a trailing blank line end diff --git a/share/functions/__fish_print_hostnames.fish b/share/functions/__fish_print_hostnames.fish index 7c7a28a81..4bec16fb3 100644 --- a/share/functions/__fish_print_hostnames.fish +++ b/share/functions/__fish_print_hostnames.fish @@ -1,41 +1,38 @@ function __fish_print_hostnames -d "Print a list of known hostnames" - # HACK: This only deals with ipv4 + # HACK: This only deals with ipv4 - # Print all hosts from /etc/hosts - # use 'getent hosts' on OSes that support it (OpenBSD and Cygwin do not) - if type -q getent; and getent hosts > /dev/null 2>&1 # test if 'getent hosts' works and redirect output so errors don't print - # Ignore zero ips - getent hosts | string match -r -v '^0.0.0.0' \ - | string replace -r '[0-9.]*\s*' '' | string split " " - else if test -r /etc/hosts - # Ignore commented lines and functionally empty lines - string match -r -v '^\s*0.0.0.0|^\s*#|^\s*$' < /etc/hosts \ - # Strip comments - | string replace -ra '#.*$' '' \ - | string replace -r '[0-9.]*\s*' '' | string trim | string replace -ra '\s+' '\n' - end + # Print all hosts from /etc/hosts + # use 'getent hosts' on OSes that support it (OpenBSD and Cygwin do not) + if type -q getent + and getent hosts >/dev/null 2>&1 # test if 'getent hosts' works and redirect output so errors don't print + # Ignore zero ips + getent hosts | string match -r -v '^0.0.0.0' | string replace -r '[0-9.]*\s*' '' | string split " " + else if test -r /etc/hosts + # Ignore commented lines and functionally empty lines. Strip comments. + string match -r -v '^\s*0.0.0.0|^\s*#|^\s*$' /dev/null ^/dev/null + set bsd_make 0 + else + set bsd_make 1 + end + + for file in $directory/{GNUmakefile,Makefile,makefile} + if test -f $file + if test "$bsd_make" = 0 + make -C $directory -prRn | awk -v RS= -F: '/^# Files/,/^# Finished Make data base/ {if ($1 !~ "^[#.]") {print $1}}' ^/dev/null + else + make -C $directory -d g1 -rn >/dev/null ^| awk -F, '/^#\*\*\* Input graph:/,/^$/ {if ($1 !~ "^#... ") {gsub(/# /,"",$1); print $1}}' ^/dev/null + end + break + end + end end diff --git a/share/functions/__fish_print_modules.fish b/share/functions/__fish_print_modules.fish index e237e7a1a..b52dd1535 100644 --- a/share/functions/__fish_print_modules.fish +++ b/share/functions/__fish_print_modules.fish @@ -1,4 +1,4 @@ # Helper function for completions that need to enumerate Linux modules function __fish_print_modules - find /lib/modules/(uname -r)/{kernel,misc} -type f ^ /dev/null | sed -e 's$/.*/\([^/.]*\).*$\1$' + find /lib/modules/(uname -r)/{kernel,misc} -type f ^/dev/null | sed -e 's$/.*/\([^/.]*\).*$\1$' end diff --git a/share/functions/__fish_print_mounted.fish b/share/functions/__fish_print_mounted.fish index 0a454b7f2..ef0dfdf24 100644 --- a/share/functions/__fish_print_mounted.fish +++ b/share/functions/__fish_print_mounted.fish @@ -1,13 +1,12 @@ function __fish_print_mounted --description 'Print mounted devices' - if test -r /etc/mtab - # In mtab, spaces are replaced by a literal '\040' - # So it's safe to get the second "field" and then replace it - # \011 encodes a tab, \012 encodes a newline and \\ encodes a backslash - # This will probably break on newlines because of our splitting, though - # and tabs because of descriptions - string replace -r '\S+ (\S+) .*' '$1' /dev/null | string replace -r ':.*' '' + ninja -t targets 2>/dev/null | string replace -r ':.*' '' end end diff --git a/share/functions/__fish_print_packages.fish b/share/functions/__fish_print_packages.fish index a6b84b475..c3985cd13 100644 --- a/share/functions/__fish_print_packages.fish +++ b/share/functions/__fish_print_packages.fish @@ -1,139 +1,139 @@ function __fish_print_packages - # apt-cache is much, much faster than rpm, and can do this in real - # time. We use it if available. + # apt-cache is much, much faster than rpm, and can do this in real + # time. We use it if available. - switch (commandline -tc) - case '-**' - return - end + switch (commandline -tc) + case '-**' + return + end - #Get the word 'Package' in the current language - set -l package (_ Package) + #Get the word 'Package' in the current language + set -l package (_ Package) - # Set up cache directory - if test -z "$XDG_CACHE_HOME" - set XDG_CACHE_HOME $HOME/.cache - end - mkdir -m 700 -p $XDG_CACHE_HOME + # Set up cache directory + if test -z "$XDG_CACHE_HOME" + set XDG_CACHE_HOME $HOME/.cache + end + mkdir -m 700 -p $XDG_CACHE_HOME - if type -q -f apt-cache - # Do not generate the cache as apparently sometimes this is slow. - # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=547550 - apt-cache --no-generate pkgnames (commandline -tc) ^/dev/null | sed -e 's/$/'\t$package'/' - return - end + if type -q -f apt-cache + # Do not generate the cache as apparently sometimes this is slow. + # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=547550 + apt-cache --no-generate pkgnames (commandline -tc) ^/dev/null | sed -e 's/$/'\t$package'/' + return + end - # Pkg is fast on FreeBSD and provides versioning info which we want for - # installed packages - if begin - type -q -f pkg - and test (uname) = "FreeBSD" - end - pkg query "%n-%v" - return - end + # Pkg is fast on FreeBSD and provides versioning info which we want for + # installed packages + if begin + type -q -f pkg + and test (uname) = "FreeBSD" + end + pkg query "%n-%v" + return + end # Caches for 5 minutes - if type -q -f pacman - set cache_file $XDG_CACHE_HOME/.pac-cache.$USER - if test -f $cache_file - cat $cache_file - set age (math (date +%s) - (stat -c '%Y' $cache_file)) - set max_age 250 - if test $age -lt $max_age - return - end - end + if type -q -f pacman + set cache_file $XDG_CACHE_HOME/.pac-cache.$USER + if test -f $cache_file + cat $cache_file + set age (math (date +%s) - (stat -c '%Y' $cache_file)) + set max_age 250 + if test $age -lt $max_age + return + end + end - # prints: Package - pacman -Ssq | sed -e 's/$/\t'$package'/' >$cache_file & - return - end + # prints: Package + pacman -Ssq | sed -e 's/$/\t'$package'/' >$cache_file & + return + end - # Zypper needs caching as it is slow - if type -q -f zypper - # Use libzypp cache file if available - if test -f /var/cache/zypp/solv/@System/solv.idx - cat /var/cache/zypp/solv/*/solv.idx | awk '!/application:|srcpackage:|product:|pattern:|patch:/ {print $1'\t$package'}' - return - end + # Zypper needs caching as it is slow + if type -q -f zypper + # Use libzypp cache file if available + if test -f /var/cache/zypp/solv/@System/solv.idx + awk '!/application:|srcpackage:|product:|pattern:|patch:/ {print $1'\t$package'}' /var/cache/zypp/solv/*/solv.idx + return + end - # If the cache is less than five minutes old, we do not recalculate it + # If the cache is less than five minutes old, we do not recalculate it - set -l cache_file $XDG_CACHE_HOME/.zypper-cache.$USER - if test -f $cache_file - cat $cache_file - set -l age (math (date +%s) - (stat -c '%Y' $cache_file)) - set -l max_age 300 - if test $age -lt $max_age - return - end - end + set -l cache_file $XDG_CACHE_HOME/.zypper-cache.$USER + if test -f $cache_file + cat $cache_file + set -l age (math (date +%s) - (stat -c '%Y' $cache_file)) + set -l max_age 300 + if test $age -lt $max_age + return + end + end - # Remove package version information from output and pipe into cache file - zypper --quiet --non-interactive search --type=package | tail -n +4 | sed -r 's/^. \| ((\w|[-_.])+).*/\1\t'$package'/g' > $cache_file & - return - end + # Remove package version information from output and pipe into cache file + zypper --quiet --non-interactive search --type=package | tail -n +4 | sed -r 's/^. \| ((\w|[-_.])+).*/\1\t'$package'/g' >$cache_file & + return + end - # yum is slow, just like rpm, so go to the background - if type -q -f /usr/share/yum-cli/completion-helper.py + # yum is slow, just like rpm, so go to the background + if type -q -f /usr/share/yum-cli/completion-helper.py - # If the cache is less than six hours old, we do not recalculate it + # If the cache is less than six hours old, we do not recalculate it - set cache_file $XDG_CACHE_HOME/.yum-cache.$USER - if test -f $cache_file - cat $cache_file - set age (math (date +%s) - (stat -c '%Y' $cache_file)) - set max_age 21600 - if test $age -lt $max_age - return - end - end + set cache_file $XDG_CACHE_HOME/.yum-cache.$USER + if test -f $cache_file + cat $cache_file + set age (math (date +%s) - (stat -c '%Y' $cache_file)) + set max_age 21600 + if test $age -lt $max_age + return + end + end - # Remove package version information from output and pipe into cache file - /usr/share/yum-cli/completion-helper.py list all -d 0 -C | sed "s/\..*/\t$package/" >$cache_file & - return - end + # Remove package version information from output and pipe into cache file + /usr/share/yum-cli/completion-helper.py list all -d 0 -C | sed "s/\..*/\t$package/" >$cache_file & + return + end - # Rpm is too slow for this job, so we set it up to do completions - # as a background job and cache the results. + # Rpm is too slow for this job, so we set it up to do completions + # as a background job and cache the results. - if type -q -f rpm + if type -q -f rpm - # If the cache is less than five minutes old, we do not recalculate it + # If the cache is less than five minutes old, we do not recalculate it - set cache_file $XDG_CACHE_HOME/.rpm-cache.$USER - if test -f $cache_file - cat $cache_file - set age (math (date +%s) - (stat -c '%Y' $cache_file)) - set max_age 250 - if test $age -lt $max_age - return - end - end + set cache_file $XDG_CACHE_HOME/.rpm-cache.$USER + if test -f $cache_file + cat $cache_file + set age (math (date +%s) - (stat -c '%Y' $cache_file)) + set max_age 250 + if test $age -lt $max_age + return + end + end - # Remove package version information from output and pipe into cache file - rpm -qa |sed -e 's/-[^-]*-[^-]*$/\t'$package'/' >$cache_file & - return - end + # Remove package version information from output and pipe into cache file + rpm -qa | sed -e 's/-[^-]*-[^-]*$/\t'$package'/' >$cache_file & + return + end - # This completes the package name from the portage tree. - # True for installing new packages. Function for printing - # installed on the system packages is in completions/emerge.fish + # This completes the package name from the portage tree. + # True for installing new packages. Function for printing + # installed on the system packages is in completions/emerge.fish - # eix is MUCH faster than emerge so use it if it is available - if type -q -f eix - eix --only-names "^"(commandline -tc) | cut -d/ -f2 - return - else - # FIXME? Seems to be broken - if type -q -f emerge - emerge -s \^(commandline -tc) | __fish_sgrep "^*" |cut -d\ -f3 |cut -d/ -f2 - return - end - end + # eix is MUCH faster than emerge so use it if it is available + if type -q -f eix + eix --only-names "^"(commandline -tc) | cut -d/ -f2 + return + else + # FIXME? Seems to be broken + if type -q -f emerge + emerge -s \^(commandline -tc) | __fish_sgrep "^*" | cut -d\ -f3 | cut -d/ -f2 + return + end + end end diff --git a/share/functions/__fish_print_pacman_repos.fish b/share/functions/__fish_print_pacman_repos.fish index 1998f7216..92d4919af 100644 --- a/share/functions/__fish_print_pacman_repos.fish +++ b/share/functions/__fish_print_pacman_repos.fish @@ -1,3 +1,3 @@ function __fish_print_pacman_repos --description "Print the repositories configured for arch's pacman package manager" - string replace -r -a "\[(.+)\]" "\1" < /etc/pacman.conf | string match -r -v "^#|options" + string replace -r -a "\[(.+)\]" "\1" /dev/null - return 1 - end + # if svn isn't installed then don't do anything + if not command -s svn >/dev/null + return 1 + end - # make sure that this is a svn repo - set -l checkout_info (command svn info ^/dev/null) - if [ $status -ne 0 ]; - return - end + # make sure that this is a svn repo + set -l checkout_info (command svn info ^/dev/null) + if [ $status -ne 0 ] - # get the current revision number - printf '(%s%s%s' (set_color $__fish_svn_prompt_color_revision) (__fish_print_svn_rev) (set_color normal) + return + end - # resolve the status of the checkout - # 1. perform `svn status` - # 2. remove extra lines that aren't necessary - # 3. cut the output down to the first 7 columns, as these contain the information needed - set -l svn_status_lines (command svn status | sed -e 's=^Summary of conflicts.*==' -e 's=^ Text conflicts.*==' -e 's=^ Property conflicts.*==' -e 's=^ Tree conflicts.*==' -e 's=.*incoming .* upon update.*==' | cut -c 1-7) + # get the current revision number + printf '(%s%s%s' (set_color $__fish_svn_prompt_color_revision) (__fish_print_svn_rev) (set_color normal) - # track the last column to contain a status flag - set -l last_column 0 + # resolve the status of the checkout + # 1. perform `svn status` + # 2. remove extra lines that aren't necessary + # 3. cut the output down to the first 7 columns, as these contain the information needed + set -l svn_status_lines (command svn status | sed -e 's=^Summary of conflicts.*==' -e 's=^ Text conflicts.*==' -e 's=^ Property conflicts.*==' -e 's=^ Tree conflicts.*==' -e 's=.*incoming .* upon update.*==' | cut -c 1-7) - # iterate over the 7 columns of output (the 7 columns are defined on `svn help status`) - for col in (seq 7) - # get the output for a particular column - # 1. echo the whole status flag text - # 2. cut out the current column of characters - # 3. remove spaces and newline characters - set -l column_status (printf '%s\n' $svn_status_lines | cut -c $col | tr -d ' \n') + # track the last column to contain a status flag + set -l last_column 0 - # check that the character count is not zero (this would indicate that there are status flags in this column) - if [ (count $column_status) -ne 0 ]; - # we only want to display unique status flags (eg: if there are 5 modified files, the prompt should only show the modified status once) - set -l column_unique_status (echo $column_status | sort | uniq) - # parse the status flags for this column and create the formatting by calling out to the helper function - set -l svn_status_flags (__fish_svn_prompt_parse_status $column_unique_status) + # iterate over the 7 columns of output (the 7 columns are defined on `svn help status`) + for col in (seq 7) + # get the output for a particular column + # 1. echo the whole status flag text + # 2. cut out the current column of characters + # 3. remove spaces and newline characters + set -l column_status (printf '%s\n' $svn_status_lines | cut -c $col | tr -d ' \n') - # the default separator is empty - set -l prompt_separator "" - for index in (seq (math "$col - $last_column")) - # the prompt separator variable has to be updated with the number of separators needed to represent empty status columns (eg: if a file has the status "A +" then it should display as "A|||+" in the prompt) - set prompt_separator $prompt_separator$__fish_svn_prompt_char_separator - end + # check that the character count is not zero (this would indicate that there are status flags in this column) + if [ (count $column_status) -ne 0 ] - # record that the current column was the last one printed to the prompt - set last_column $col - # print the separator string then the current column's status flags - printf '%s%s' $prompt_separator $svn_status_flags - end - end + # we only want to display unique status flags (eg: if there are 5 modified files, the prompt should only show the modified status once) + set -l column_unique_status (echo $column_status | sort -u) + # parse the status flags for this column and create the formatting by calling out to the helper function + set -l svn_status_flags (__fish_svn_prompt_parse_status $column_unique_status) - # print the close of the svn status prompt - printf ')' -end \ No newline at end of file + # the default separator is empty + set -l prompt_separator "" + for index in (seq (math "$col - $last_column")) + # the prompt separator variable has to be updated with the number of separators needed to represent empty status columns (eg: if a file has the status "A +" then it should display as "A|||+" in the prompt) + set prompt_separator $prompt_separator$__fish_svn_prompt_char_separator + end + + # record that the current column was the last one printed to the prompt + set last_column $col + # print the separator string then the current column's status flags + printf '%s%s' $prompt_separator $svn_status_flags + end + end + + # print the close of the svn status prompt + printf ')' +end diff --git a/share/functions/__fish_systemctl_automounts.fish b/share/functions/__fish_systemctl_automounts.fish index 614412293..e62b8afc5 100644 --- a/share/functions/__fish_systemctl_automounts.fish +++ b/share/functions/__fish_systemctl_automounts.fish @@ -1,9 +1,9 @@ function __fish_systemctl_automounts - if type -q systemctl - if __fish_contains_opt user - systemctl --user list-unit-files --no-legend --type=automount ^/dev/null | cut -f 1 -d ' ' - else - systemctl list-unit-files --no-legend --type=automount ^/dev/null | cut -f 1 -d ' ' - end - end + if type -q systemctl + if __fish_contains_opt user + systemctl --user list-unit-files --no-legend --type=automount ^/dev/null | cut -f 1 -d ' ' + else + systemctl list-unit-files --no-legend --type=automount ^/dev/null | cut -f 1 -d ' ' + end + end end diff --git a/share/functions/__fish_systemctl_devices.fish b/share/functions/__fish_systemctl_devices.fish index bad24a19f..082e65d7d 100644 --- a/share/functions/__fish_systemctl_devices.fish +++ b/share/functions/__fish_systemctl_devices.fish @@ -1,11 +1,11 @@ function __fish_systemctl_devices - if type -q systemctl - if __fish_contains_opt user - # Devices are usually generated at runtime - # Therefore show known _units_, not unit-files - systemctl --user list-units --no-legend --type=device ^/dev/null | cut -f 1 -d ' ' - else - systemctl list-units --no-legend --type=device ^/dev/null | cut -f 1 -d ' ' - end - end + if type -q systemctl + if __fish_contains_opt user + # Devices are usually generated at runtime + # Therefore show known _units_, not unit-files + systemctl --user list-units --no-legend --type=device ^/dev/null | cut -f 1 -d ' ' + else + systemctl list-units --no-legend --type=device ^/dev/null | cut -f 1 -d ' ' + end + end end diff --git a/share/functions/__fish_systemctl_mounts.fish b/share/functions/__fish_systemctl_mounts.fish index b3e7dd6ab..feac7b1a6 100644 --- a/share/functions/__fish_systemctl_mounts.fish +++ b/share/functions/__fish_systemctl_mounts.fish @@ -1,9 +1,9 @@ function __fish_systemctl_mounts - if type -q systemctl - if __fish_contains_opt user - systemctl --user list-unit-files --no-legend --type=mount ^/dev/null | cut -f 1 -d ' ' - else - systemctl list-unit-files --no-legend --type=mount ^/dev/null | cut -f 1 -d ' ' - end - end + if type -q systemctl + if __fish_contains_opt user + systemctl --user list-unit-files --no-legend --type=mount ^/dev/null | cut -f 1 -d ' ' + else + systemctl list-unit-files --no-legend --type=mount ^/dev/null | cut -f 1 -d ' ' + end + end end diff --git a/share/functions/__fish_systemctl_scopes.fish b/share/functions/__fish_systemctl_scopes.fish index f2f5cbccc..3b705718b 100644 --- a/share/functions/__fish_systemctl_scopes.fish +++ b/share/functions/__fish_systemctl_scopes.fish @@ -1,11 +1,11 @@ function __fish_systemctl_scopes - if type -q systemctl - if __fish_contains_opt user - # Scopes are usually generated at runtime - # Therefore show known _units_, not unit-files - systemctl --user list-units --no-legend --type=scope ^/dev/null | cut -f 1 -d ' ' - else - systemctl list-units --no-legend --type=scope ^/dev/null | cut -f 1 -d ' ' - end - end + if type -q systemctl + if __fish_contains_opt user + # Scopes are usually generated at runtime + # Therefore show known _units_, not unit-files + systemctl --user list-units --no-legend --type=scope ^/dev/null | cut -f 1 -d ' ' + else + systemctl list-units --no-legend --type=scope ^/dev/null | cut -f 1 -d ' ' + end + end end diff --git a/share/functions/__fish_systemctl_service_paths.fish b/share/functions/__fish_systemctl_service_paths.fish index 5691ee0d0..5208bf8ba 100644 --- a/share/functions/__fish_systemctl_service_paths.fish +++ b/share/functions/__fish_systemctl_service_paths.fish @@ -1,9 +1,9 @@ function __fish_systemctl_service_paths - if type -q systemctl - if __fish_contains_opt user - systemctl --user list-unit-files --no-legend --type=path ^/dev/null $argv | cut -f 1 -d ' ' - else - systemctl list-unit-files --no-legend --type=path ^/dev/null $argv | cut -f 1 -d ' ' - end - end + if type -q systemctl + if __fish_contains_opt user + systemctl --user list-unit-files --no-legend --type=path ^/dev/null $argv | cut -f 1 -d ' ' + else + systemctl list-unit-files --no-legend --type=path ^/dev/null $argv | cut -f 1 -d ' ' + end + end end diff --git a/share/functions/__fish_systemctl_services.fish b/share/functions/__fish_systemctl_services.fish index ae779828c..c80f7333d 100644 --- a/share/functions/__fish_systemctl_services.fish +++ b/share/functions/__fish_systemctl_services.fish @@ -1,13 +1,13 @@ function __fish_systemctl_services - if type -q systemctl - if __fish_contains_opt user - systemctl --user list-unit-files --no-legend --type=service ^/dev/null $argv | cut -f 1 -d ' ' - systemctl --user list-units --state=loaded --no-legend --type=service ^/dev/null | cut -f 1 -d ' ' - else - # list-unit-files will also show disabled units - systemctl list-unit-files --no-legend --type=service ^/dev/null $argv | cut -f 1 -d ' ' - # list-units will not show disabled units but will show instances (like wpa_supplicant@wlan0.service) - systemctl list-units --state=loaded --no-legend --type=service ^/dev/null | cut -f 1 -d ' ' - end - end + if type -q systemctl + if __fish_contains_opt user + systemctl --user list-unit-files --no-legend --type=service ^/dev/null $argv | cut -f 1 -d ' ' + systemctl --user list-units --state=loaded --no-legend --type=service ^/dev/null | cut -f 1 -d ' ' + else + # list-unit-files will also show disabled units + systemctl list-unit-files --no-legend --type=service ^/dev/null $argv | cut -f 1 -d ' ' + # list-units will not show disabled units but will show instances (like wpa_supplicant@wlan0.service) + systemctl list-units --state=loaded --no-legend --type=service ^/dev/null | cut -f 1 -d ' ' + end + end end diff --git a/share/functions/__fish_systemctl_slices.fish b/share/functions/__fish_systemctl_slices.fish index 40628f98d..4d8ddf6dc 100644 --- a/share/functions/__fish_systemctl_slices.fish +++ b/share/functions/__fish_systemctl_slices.fish @@ -1,11 +1,11 @@ function __fish_systemctl_slices - if type -q systemctl - if __fish_contains_opt user - # Slices are usually generated at runtime - # Therefore show known _units_, not unit-files - systemctl --user list-units --no-legend --type=slice ^/dev/null | cut -f 1 -d ' ' - else - systemctl list-units --no-legend --type=slice ^/dev/null | cut -f 1 -d ' ' - end - end + if type -q systemctl + if __fish_contains_opt user + # Slices are usually generated at runtime + # Therefore show known _units_, not unit-files + systemctl --user list-units --no-legend --type=slice ^/dev/null | cut -f 1 -d ' ' + else + systemctl list-units --no-legend --type=slice ^/dev/null | cut -f 1 -d ' ' + end + end end diff --git a/share/functions/__fish_systemctl_snapshots.fish b/share/functions/__fish_systemctl_snapshots.fish index 7b6cb5ee9..7017d8075 100644 --- a/share/functions/__fish_systemctl_snapshots.fish +++ b/share/functions/__fish_systemctl_snapshots.fish @@ -1,12 +1,12 @@ function __fish_systemctl_snapshots - if type -q systemctl - if __fish_contains_opt user - # Snapshots are usually generated at runtime - # Therefore show known _units_, not unit-files - # They are also often not loaded, so add "--all" - systemctl --user list-units --all --no-legend --type=snapshot ^/dev/null | cut -f 1 -d ' ' - else - systemctl list-units --all --no-legend --type=snapshot ^/dev/null | cut -f 1 -d ' ' - end - end + if type -q systemctl + if __fish_contains_opt user + # Snapshots are usually generated at runtime + # Therefore show known _units_, not unit-files + # They are also often not loaded, so add "--all" + systemctl --user list-units --all --no-legend --type=snapshot ^/dev/null | cut -f 1 -d ' ' + else + systemctl list-units --all --no-legend --type=snapshot ^/dev/null | cut -f 1 -d ' ' + end + end end diff --git a/share/functions/__fish_systemctl_sockets.fish b/share/functions/__fish_systemctl_sockets.fish index d45dfc1b3..5358eaf4c 100644 --- a/share/functions/__fish_systemctl_sockets.fish +++ b/share/functions/__fish_systemctl_sockets.fish @@ -1,9 +1,9 @@ function __fish_systemctl_sockets - if type -q systemctl - if __fish_contains_opt user - systemctl --user list-unit-files --no-legend --type=socket ^/dev/null $argv | cut -f 1 -d ' ' - else - systemctl list-unit-files --no-legend --type=socket ^/dev/null $argv | cut -f 1 -d ' ' - end - end + if type -q systemctl + if __fish_contains_opt user + systemctl --user list-unit-files --no-legend --type=socket ^/dev/null $argv | cut -f 1 -d ' ' + else + systemctl list-unit-files --no-legend --type=socket ^/dev/null $argv | cut -f 1 -d ' ' + end + end end diff --git a/share/functions/__fish_systemctl_swaps.fish b/share/functions/__fish_systemctl_swaps.fish index 57df43676..91547f752 100644 --- a/share/functions/__fish_systemctl_swaps.fish +++ b/share/functions/__fish_systemctl_swaps.fish @@ -1,9 +1,9 @@ function __fish_systemctl_swaps - if type -q systemctl - if __fish_contains_opt user - systemctl --user list-unit-files --no-legend --type=swap ^/dev/null | cut -f 1 -d ' ' - else - systemctl list-unit-files --no-legend --type=swap ^/dev/null | cut -f 1 -d ' ' - end - end + if type -q systemctl + if __fish_contains_opt user + systemctl --user list-unit-files --no-legend --type=swap ^/dev/null | cut -f 1 -d ' ' + else + systemctl list-unit-files --no-legend --type=swap ^/dev/null | cut -f 1 -d ' ' + end + end end diff --git a/share/functions/__fish_systemctl_targets.fish b/share/functions/__fish_systemctl_targets.fish index c63afdea4..d444d0cb6 100644 --- a/share/functions/__fish_systemctl_targets.fish +++ b/share/functions/__fish_systemctl_targets.fish @@ -1,9 +1,9 @@ function __fish_systemctl_targets - if type -q systemctl - if __fish_contains_opt user - systemctl --user list-unit-files --no-legend --type=target ^/dev/null | cut -f 1 -d ' ' - else - systemctl list-unit-files --no-legend --type=target ^/dev/null | cut -f 1 -d ' ' - end - end + if type -q systemctl + if __fish_contains_opt user + systemctl --user list-unit-files --no-legend --type=target ^/dev/null | cut -f 1 -d ' ' + else + systemctl list-unit-files --no-legend --type=target ^/dev/null | cut -f 1 -d ' ' + end + end end diff --git a/share/functions/__fish_systemctl_timers.fish b/share/functions/__fish_systemctl_timers.fish index 1dea2dc18..726a7100a 100644 --- a/share/functions/__fish_systemctl_timers.fish +++ b/share/functions/__fish_systemctl_timers.fish @@ -1,9 +1,9 @@ function __fish_systemctl_timers - if type -q systemctl - if __fish_contains_opt user - systemctl --user list-unit-files --no-legend --type=timer ^/dev/null $argv | cut -f 1 -d ' ' - else - systemctl list-unit-files --no-legend --type=timer ^/dev/null $argv | cut -f 1 -d ' ' - end - end + if type -q systemctl + if __fish_contains_opt user + systemctl --user list-unit-files --no-legend --type=timer ^/dev/null $argv | cut -f 1 -d ' ' + else + systemctl list-unit-files --no-legend --type=timer ^/dev/null $argv | cut -f 1 -d ' ' + end + end end diff --git a/share/functions/__fish_systemd_machine_images.fish b/share/functions/__fish_systemd_machine_images.fish index 8ff0a69d1..c14865a0a 100644 --- a/share/functions/__fish_systemd_machine_images.fish +++ b/share/functions/__fish_systemd_machine_images.fish @@ -1,5 +1,7 @@ # Like for running machines, I'm assuming machinectl doesn't allow spaces in image names # This does not include the special image ".host" since it isn't valid for most operations function __fish_systemd_machine_images - machinectl --no-legend --no-pager list-images | while read -l a b; echo $a; end + machinectl --no-legend --no-pager list-images | while read -l a b + echo $a + end end diff --git a/share/functions/__fish_systemd_machines.fish b/share/functions/__fish_systemd_machines.fish index 09becb2d3..a4ab375f7 100644 --- a/share/functions/__fish_systemd_machines.fish +++ b/share/functions/__fish_systemd_machines.fish @@ -1,4 +1,6 @@ # It seems machinectl will eliminate spaces from machine names so we don't need to handle that function __fish_systemd_machines - machinectl --no-legend --no-pager list --all | while read -l a b; echo $a; end + machinectl --no-legend --no-pager list --all | while read -l a b + echo $a + end end diff --git a/share/functions/__fish_test_arg.fish b/share/functions/__fish_test_arg.fish index 6ebe8fb0b..695c96866 100644 --- a/share/functions/__fish_test_arg.fish +++ b/share/functions/__fish_test_arg.fish @@ -3,7 +3,7 @@ function __fish_test_arg --description "Test if the token under the cursor match switch (commandline -ct) case $argv return 0 - end + end return 1 end diff --git a/share/functions/__fish_toggle_comment_commandline.fish b/share/functions/__fish_toggle_comment_commandline.fish index 8bdd7e822..d6cba8445 100644 --- a/share/functions/__fish_toggle_comment_commandline.fish +++ b/share/functions/__fish_toggle_comment_commandline.fish @@ -13,5 +13,6 @@ function __fish_toggle_comment_commandline --description 'Comment/uncomment the end set -l cmdlines (printf '%s\n' '#'$cmdlines | string replace -r '^##' '') commandline -r $cmdlines - string match -q '#*' $cmdlines[1]; and commandline -f execute + string match -q '#*' $cmdlines[1] + and commandline -f execute end diff --git a/share/functions/__fish_urlencode.fish b/share/functions/__fish_urlencode.fish index df07eee03..0e336813e 100644 --- a/share/functions/__fish_urlencode.fish +++ b/share/functions/__fish_urlencode.fish @@ -1,22 +1,26 @@ function __fish_urlencode --description "URL-encode stdin" - set -l join '' - set -l chars - # Set locale to C and IFS to "" in order to split a line into bytes. - while begin; set -lx LC_ALL C; set -lx IFS ''; read -az chars; end - printf '%s' $join - # chomp off a trailing newline - if test "$chars[-1]" = \n - set -e chars[-1] - set join '%0A%00' - else - set join '%00' - end - for c in $chars - if string match -q -r '[/._~A-Za-z0-9-]' $c - printf '%s' $c - else - printf '%%%02X' "'$c" - end - end - end + set -l join '' + set -l chars + # Set locale to C and IFS to "" in order to split a line into bytes. + while begin + set -lx LC_ALL C + set -lx IFS '' + read -az chars + end + printf '%s' $join + # chomp off a trailing newline + if test "$chars[-1]" = \n + set -e chars[-1] + set join '%0A%00' + else + set join '%00' + end + for c in $chars + if string match -q -r '[/._~A-Za-z0-9-]' $c + printf '%s' $c + else + printf '%%%02X' "'$c" + end + end + end end diff --git a/share/functions/__fish_use_subcommand.fish b/share/functions/__fish_use_subcommand.fish index 1ec2398b1..dd262c15f 100644 --- a/share/functions/__fish_use_subcommand.fish +++ b/share/functions/__fish_use_subcommand.fish @@ -1,14 +1,14 @@ function __fish_use_subcommand -d "Test if a non-switch argument has been given in the current commandline" - set -l cmd (commandline -poc) - set -e cmd[1] - for i in $cmd - switch $i - case '-*' - continue - end - return 1 - end - return 0 + set -l cmd (commandline -poc) + set -e cmd[1] + for i in $cmd + switch $i + case '-*' + continue + end + return 1 + end + return 0 end diff --git a/share/functions/__fish_vcs_prompt.fish b/share/functions/__fish_vcs_prompt.fish index 6695cfbaa..04101a73b 100644 --- a/share/functions/__fish_vcs_prompt.fish +++ b/share/functions/__fish_vcs_prompt.fish @@ -1,5 +1,5 @@ function __fish_vcs_prompt --description "Print the prompts for all available vcsen" - __fish_git_prompt - __fish_hg_prompt - __fish_svn_prompt + __fish_git_prompt + __fish_hg_prompt + __fish_svn_prompt end diff --git a/share/functions/__terlar_git_prompt.fish b/share/functions/__terlar_git_prompt.fish index 9b3c84a85..32ffff9e9 100644 --- a/share/functions/__terlar_git_prompt.fish +++ b/share/functions/__terlar_git_prompt.fish @@ -21,63 +21,70 @@ set -g fish_prompt_git_status_unmerged '!' set -g fish_prompt_git_status_order added modified renamed copied deleted untracked unmerged function __terlar_git_prompt --description 'Write out the git prompt' - # If git isn't installed, there's nothing we can do - # Return 1 so the calling prompt can deal with it - if not command -s git >/dev/null - return 1 - end - set -l branch (git rev-parse --abbrev-ref HEAD ^/dev/null) - if test -z $branch - return - end + # If git isn't installed, there's nothing we can do + # Return 1 so the calling prompt can deal with it + if not command -s git >/dev/null + return 1 + end + set -l branch (git rev-parse --abbrev-ref HEAD ^/dev/null) + if test -z $branch + return + end - echo -n '|' + echo -n '|' - set -l index (git status --porcelain ^/dev/null|cut -c 1-2|sort -u) + set -l index (git status --porcelain ^/dev/null|cut -c 1-2|sort -u) + + if test -z "$index" + set_color $fish_color_git_clean + echo -n $branch'✓' + set_color normal + return + end + + set -l gs + set -l staged + + for i in $index + if echo $i | grep '^[AMRCD]' >/dev/null + set staged 1 + end + + switch $i + case 'A ' + set gs $gs added + case 'M ' ' M' + set gs $gs modified + case 'R ' + set gs $gs renamed + case 'C ' + set gs $gs copied + case 'D ' ' D' + set gs $gs deleted + case '\?\?' + set gs $gs untracked + case 'U*' '*U' 'DD' 'AA' + set gs $gs unmerged + end + end + + if set -q staged[1] + set_color $fish_color_git_staged + else + set_color $fish_color_git_dirty + end + + echo -n $branch'⚡' + + for i in $fish_prompt_git_status_order + if contains $i in $gs + set -l color_name fish_color_git_$i + set -l status_name fish_prompt_git_status_$i + + set_color $$color_name + echo -n $$status_name + end + end - if test -z "$index" - set_color $fish_color_git_clean - echo -n $branch'✓' set_color normal - return - end - - set -l gs - set -l staged - - for i in $index - if echo $i | grep '^[AMRCD]' >/dev/null - set staged 1 - end - - switch $i - case 'A ' ; set gs $gs added - case 'M ' ' M' ; set gs $gs modified - case 'R ' ; set gs $gs renamed - case 'C ' ; set gs $gs copied - case 'D ' ' D' ; set gs $gs deleted - case '\?\?' ; set gs $gs untracked - case 'U*' '*U' 'DD' 'AA'; set gs $gs unmerged - end - end - - if set -q staged[1] - set_color $fish_color_git_staged - else - set_color $fish_color_git_dirty - end - - echo -n $branch'⚡' - - for i in $fish_prompt_git_status_order - if contains $i in $gs - set -l color_name fish_color_git_$i - set -l status_name fish_prompt_git_status_$i - - set_color $$color_name - echo -n $$status_name - end - end - - set_color normal end diff --git a/share/functions/abbr.fish b/share/functions/abbr.fish index cdb528aef..e09651c58 100644 --- a/share/functions/abbr.fish +++ b/share/functions/abbr.fish @@ -1,155 +1,200 @@ function abbr --description "Manage abbreviations" - # parse arguments - set -l mode - set -l mode_flag # the flag that was specified, for better errors - set -l mode_arg - set -l needs_arg no - while set -q argv[1] - set -l new_mode - switch $argv[1] - case '-h' '--help' - __fish_print_help abbr - return 0 - case '-a' '--add' - set new_mode add - set needs_arg multi - case '-e' '--erase' - set new_mode erase - set needs_arg single - case '-l' '--list' - set new_mode list - case '-s' '--show' - set new_mode show - case '--' - set -e argv[1] - break - case '-*' - printf ( _ "%s: invalid option -- %s\n" ) abbr $argv[1] >&2 - return 1 - case '*' - break - end - if test -n "$mode" -a -n "$new_mode" - # we're trying to set two different modes - printf ( _ "%s: %s cannot be specified along with %s\n" ) abbr $argv[1] $mode_flag >&2 - return 1 - end - set mode $new_mode - set mode_flag $argv[1] - set -e argv[1] - end + # parse arguments + set -l mode + set -l mode_flag # the flag that was specified, for better errors + set -l mode_arg + set -l needs_arg no + while set -q argv[1] + set -l new_mode + switch $argv[1] + case '-h' '--help' + __fish_print_help abbr + return 0 + case '-a' '--add' + set new_mode add + set needs_arg multi + case '-r' '--rename' + set new_mode rename + set needs_arg double + case '-e' '--erase' + set new_mode erase + set needs_arg single + case '-l' '--list' + set new_mode list + case '-s' '--show' + set new_mode show + case '--' + set -e argv[1] + break + case '-*' + printf ( _ "%s: invalid option -- %s\n" ) abbr $argv[1] >&2 + return 1 + case '*' + break + end + if test -n "$mode" -a -n "$new_mode" + # we're trying to set two different modes + printf ( _ "%s: %s cannot be specified along with %s\n" ) abbr $argv[1] $mode_flag >&2 + return 1 + end + set mode $new_mode + set mode_flag $argv[1] + set -e argv[1] + end - # If run with no options, treat it like --add if we have an argument, or - # --show if we do not have an argument - if not set -q mode[1] - if set -q argv[1] - set mode add - set needs_arg multi - else - set mode show - end - end + # If run with no options, treat it like --add if we have an argument, or + # --show if we do not have an argument + if not set -q mode[1] + if set -q argv[1] + set mode add + set needs_arg multi + else + set mode show + end + end - if test $needs_arg = single - set mode_arg $argv[1] - set needs_arg no - set -e argv[1] - else if test $needs_arg = multi - set mode_arg $argv - set needs_arg no - set -e argv - end - if test $needs_arg != no - printf ( _ "%s: option requires an argument -- %s\n" ) abbr $mode_flag >&2 - return 1 - end - - # none of our modes want any excess arguments - if set -q argv[1] - printf ( _ "%s: Unexpected argument -- %s\n" ) abbr $argv[1] >&2 - return 1 - end + if test $needs_arg = single + set mode_arg $argv[1] + set needs_arg no + set -e argv[1] + else if test $needs_arg = double + # Pull the two parameters from argv. + # * leave argv non-empty, if there are more than two arguments + # * leave needs_arg set to double if there is not enough arguments + if set -q argv[1] + set param1 $argv[1] + set -e argv[1] + if set -q argv[1] + set param2 $argv[1] + set needs_arg no + set -e argv[1] + end + end + else if test $needs_arg = multi + set mode_arg $argv + set needs_arg no + set -e argv + end + if test $needs_arg != no + printf ( _ "%s: option requires an argument -- %s\n" ) abbr $mode_flag >&2 + return 1 + end - switch $mode - case 'add' - # Convert from old "key=value" syntax - # TODO: This should be removed later - if not set -q mode_arg[2]; and string match -qr '^[^ ]+=' -- $mode_arg - set mode_arg (string split "=" -- $mode_arg) - end + # none of our modes want any excess arguments + if set -q argv[1] + printf ( _ "%s: Unexpected argument -- %s\n" ) abbr $argv[1] >&2 + return 1 + end - # Bail out early if the exact abbr is already in - contains -- "$mode_arg" $fish_user_abbreviations; and return 0 - set -l key $mode_arg[1] - set -e mode_arg[1] - set -l value "$mode_arg" - # Because we later store "$key $value", there can't be any spaces in the key - if string match -q "* *" -- $key - printf ( _ "%s: abbreviation cannot have spaces in the key\n" ) abbr >&2 - return 1 - end - if test -z "$value" - printf ( _ "%s: abbreviation must have a value\n" ) abbr >&2 - return 1 - end - if set -l idx (__fish_abbr_get_by_key $key) - # erase the existing abbreviation - set -e fish_user_abbreviations[$idx] - end - if not set -q fish_user_abbreviations - # initialize as a universal variable, so we can skip the -U later - # and therefore work properly if someone sets this as a global variable - set -U fish_user_abbreviations - end - set fish_user_abbreviations $fish_user_abbreviations "$key $value" - return 0 + switch $mode + case 'add' + # Convert from old "key=value" syntax + # TODO: This should be removed later + if not set -q mode_arg[2] + and string match -qr '^[^ ]+=' -- $mode_arg + set mode_arg (string split "=" -- $mode_arg) + end - case 'erase' - if set -l idx (__fish_abbr_get_by_key $mode_arg) - set -e fish_user_abbreviations[$idx] - return 0 - else - printf ( _ "%s: no such abbreviation '%s'\n" ) abbr $mode_arg >&2 - return 2 - end + # Bail out early if the exact abbr is already in + contains -- "$mode_arg" $fish_user_abbreviations + and return 0 + set -l key $mode_arg[1] + set -e mode_arg[1] + set -l value "$mode_arg" + # Because we later store "$key $value", there can't be any spaces in the key + if string match -q "* *" -- $key + printf ( _ "%s: abbreviation cannot have spaces in the key\n" ) abbr >&2 + return 1 + end + if test -z "$value" + printf ( _ "%s: abbreviation must have a value\n" ) abbr >&2 + return 1 + end + if set -l idx (__fish_abbr_get_by_key $key) + # erase the existing abbreviation + set -e fish_user_abbreviations[$idx] + end + if not set -q fish_user_abbreviations + # initialize as a universal variable, so we can skip the -U later + # and therefore work properly if someone sets this as a global variable + set -U fish_user_abbreviations + end + set fish_user_abbreviations $fish_user_abbreviations "$key $value" + return 0 - case 'show' - for i in $fish_user_abbreviations - set -l opt_double_dash - set -l kv (string split " " -m 1 -- $i) - set -l key $kv[1] - set -l value $kv[2] - - # Check to see if either key or value has a leading dash - # If so, we need to write -- - string match -q -- '-*' $key $value; and set opt_double_dash '--' - echo abbr $opt_double_dash (string escape -- $key $value) - end - return 0 + case 'rename' + set -l old_name $param1 + set -l new_name $param2 - case 'list' - for i in $fish_user_abbreviations - set -l key (string split " " -m 1 -- $i)[1] - printf "%s\n" $key - end - return 0 - end + # if the target name already exists, throw an error + if set -l idx (__fish_abbr_get_by_key $new_name) + printf ( _ "%s: abbreviation '%s' already exists, cannot rename\n" ) abbr $new_name >&2 + return 2 + end + + # Because we later store "$key $value", there can't be any spaces in the key + if string match -q "* *" -- $new_name + printf ( _ "%s: abbreviation cannot have spaces in the key\n" ) abbr >&2 + return 1 + end + + set -l idx (__fish_abbr_get_by_key $old_name) + or begin + printf ( _ "%s: no such abbreviation '%s'\n" ) abbr $old_name >&2 + return 2 + end + + set -l value (string split " " -m 1 -- $fish_user_abbreviations[$idx])[2] + set fish_user_abbreviations[$idx] "$new_name $value" + return 0 + + case 'erase' + if set -l idx (__fish_abbr_get_by_key $mode_arg) + set -e fish_user_abbreviations[$idx] + return 0 + else + printf ( _ "%s: no such abbreviation '%s'\n" ) abbr $mode_arg >&2 + return 2 + end + + case 'show' + for i in $fish_user_abbreviations + set -l opt_double_dash + set -l kv (string split " " -m 1 -- $i) + set -l key $kv[1] + set -l value $kv[2] + + # Check to see if either key or value has a leading dash + # If so, we need to write -- + string match -q -- '-*' $key $value + and set opt_double_dash '--' + echo abbr $opt_double_dash (string escape -- $key $value) + end + return 0 + + case 'list' + for i in $fish_user_abbreviations + set -l key (string split " " -m 1 -- $i)[1] + printf "%s\n" $key + end + return 0 + end end function __fish_abbr_get_by_key - if not set -q argv[1] - echo "__fish_abbr_get_by_key: expected one argument, got none" >&2 - return 2 - end - # Going through all entries is still quicker than calling `seq` - set -l keys - for kv in $fish_user_abbreviations - # If this does not match, we have screwed up before and the error should be reported - set keys $keys (string split " " -m 1 -- $kv)[1] - end - if set -l idx (contains -i -- $argv[1] $keys) - echo $idx - return 0 - end - return 1 + if not set -q argv[1] + echo "__fish_abbr_get_by_key: expected one argument, got none" >&2 + return 2 + end + # Going through all entries is still quicker than calling `seq` + set -l keys + for kv in $fish_user_abbreviations + # If this does not match, we have screwed up before and the error should be reported + set keys $keys (string split " " -m 1 -- $kv)[1] + end + if set -l idx (contains -i -- $argv[1] $keys) + echo $idx + return 0 + end + return 1 end diff --git a/share/functions/alias.fish b/share/functions/alias.fish index 41d1b7ae8..5566e2487 100644 --- a/share/functions/alias.fish +++ b/share/functions/alias.fish @@ -1,5 +1,5 @@ function alias --description 'Creates a function wrapping a command' - if count $argv > /dev/null + if count $argv >/dev/null switch $argv[1] case -h --h --he --hel --help __fish_print_help alias diff --git a/share/functions/contains_seq.fish b/share/functions/contains_seq.fish index 9fae7cacf..d3a20e1c8 100644 --- a/share/functions/contains_seq.fish +++ b/share/functions/contains_seq.fish @@ -1,46 +1,46 @@ function contains_seq --description 'Return true if array contains a sequence' - set -l printnext - switch $argv[1] - case --printnext - set printnext[1] 1 - set -e argv[1] - end - set -l pattern - set -l string - set -l dest pattern - for i in $argv - if test "$i" = -- - set dest string - continue - end - set $dest $$dest $i - end - set -l nomatch 1 - set -l i 1 - for s in $string - if set -q printnext[2] - return 0 - end - if test "$s" = "$pattern[$i]" - set -e nomatch[1] - set i (math $i + 1) - if not set -q pattern[$i] - if set -q printnext[1] - set printnext[2] 1 - continue - end - return 0 - end - else - if not set -q nomatch[1] - set nomatch 1 - set i 1 - end - end - end - if set -q printnext[1] - echo '' - end - set -q printnext[2] + set -l printnext + switch $argv[1] + case --printnext + set printnext[1] 1 + set -e argv[1] + end + set -l pattern + set -l string + set -l dest pattern + for i in $argv + if test "$i" = -- + set dest string + continue + end + set $dest $$dest $i + end + set -l nomatch 1 + set -l i 1 + for s in $string + if set -q printnext[2] + return 0 + end + if test "$s" = "$pattern[$i]" + set -e nomatch[1] + set i (math $i + 1) + if not set -q pattern[$i] + if set -q printnext[1] + set printnext[2] 1 + continue + end + return 0 + end + else + if not set -q nomatch[1] + set nomatch 1 + set i 1 + end + end + end + if set -q printnext[1] + echo '' + end + set -q printnext[2] end diff --git a/share/functions/delete-or-exit.fish b/share/functions/delete-or-exit.fish index 2a8d7286c..5a83ab8ac 100644 --- a/share/functions/delete-or-exit.fish +++ b/share/functions/delete-or-exit.fish @@ -7,17 +7,17 @@ function delete-or-exit - set -l cmd (commandline) + set -l cmd (commandline) - switch "$cmd" + switch "$cmd" - case '' - exit 0 + case '' + exit 0 - case '*' - commandline -f delete-char + case '*' + commandline -f delete-char - end + end end diff --git a/share/functions/dirs.fish b/share/functions/dirs.fish index 207f66328..7fd5b0494 100644 --- a/share/functions/dirs.fish +++ b/share/functions/dirs.fish @@ -1,18 +1,15 @@ function dirs --description 'Print directory stack' - # process options - if count $argv >/dev/null - switch $argv[1] - case -c - # clear directory stack - set -e -g dirstack - return 0 - end + # process options + if set -q argv[1] + switch $argv[1] + case -c + # clear directory stack + set -e -g dirstack + return 0 end + end - # replace $HOME with ~ - echo -n (echo (command pwd) | sed -e "s|^$HOME|~|")" " - for i in $dirstack - echo -n (echo $i | sed -e "s|^$HOME|~|")" " - end - echo + # replace $HOME with ~ + string replace -r '^'"$HOME"'($|/)' '~$1' -- $PWD $dirstack | string join " " + echo end diff --git a/share/functions/down-or-search.fish b/share/functions/down-or-search.fish index 967342391..b21232417 100644 --- a/share/functions/down-or-search.fish +++ b/share/functions/down-or-search.fish @@ -1,28 +1,28 @@ function down-or-search -d "Depending on cursor position and current mode, either search forward or move down one line" - # If we are already in search mode, continue - if commandline --search-mode - commandline -f history-search-forward - return - end + # If we are already in search mode, continue + if commandline --search-mode + commandline -f history-search-forward + return + end - # If we are navigating the pager, then up always navigates - if commandline --paging-mode - commandline -f down-line - return - end + # If we are navigating the pager, then up always navigates + if commandline --paging-mode + commandline -f down-line + return + end - # We are not already in search mode. - # If we are on the bottom line, start search mode, - # otherwise move down - set lineno (commandline -L) - set line_count (count (commandline)) + # We are not already in search mode. + # If we are on the bottom line, start search mode, + # otherwise move down + set lineno (commandline -L) + set line_count (count (commandline)) - switch $lineno - case $line_count - commandline -f history-search-forward + switch $lineno + case $line_count + commandline -f history-search-forward - case '*' - commandline -f down-line - end + case '*' + commandline -f down-line + end end diff --git a/share/functions/edit_command_buffer.fish b/share/functions/edit_command_buffer.fish new file mode 100644 index 000000000..c46f11e20 --- /dev/null +++ b/share/functions/edit_command_buffer.fish @@ -0,0 +1,44 @@ +function edit_command_buffer --description 'Edit the command buffer in an external editor' + set -l f (mktemp) + if set -q f[1] + mv $f $f.fish + set f $f.fish + else + # We should never execute this block but better to be paranoid. + if set -q TMPDIR + set f $TMPDIR/fish.(echo %self).fish + else + set f /tmp/fish.(echo %self).fish + end + touch $f + or return 1 + end + + # Edit the command line with the users preferred editor or vim or emacs. + commandline -b >$f + if set -q VISUAL + eval $VISUAL $f + else if set -q EDITOR + eval $EDITOR $f + else + echo + echo (_ 'External editor requested but $VISUAL or $EDITOR not set.') + echo (_ 'Please set VISUAL or EDITOR to your preferred editor.') + commandline -f repaint + command rm $f + return 1 + end + + # Here we're checking the exit status of the editor. + if test $status -eq 0 -a -s $f + # Set the command to the output of the edited command and move the cursor to the + # end of the edited command. + commandline -r -- (cat $f) + commandline -C 999999 + else + echo + echo (_ "Ignoring the output of your editor since its exit status was non-zero") + echo (_ "or the file was empty") + end + command rm $f +end diff --git a/share/functions/eval.fish b/share/functions/eval.fish index 052d41718..fc5f5aef4 100644 --- a/share/functions/eval.fish +++ b/share/functions/eval.fish @@ -1,65 +1,65 @@ function eval -S -d "Evaluate parameters as a command" - # keep a copy of the previous $status and use restore_status - # to preserve the status in case the block that is evaluated - # does not modify the status itself. - set -l status_copy $status - function __fish_restore_status - return $argv[1] - end + # keep a copy of the previous $status and use restore_status + # to preserve the status in case the block that is evaluated + # does not modify the status itself. + set -l status_copy $status + function __fish_restore_status + return $argv[1] + end - if not set -q argv[2] - # like most builtins, we only check for -h/--help - # if we only have a single argument - switch "$argv[1]" - case -h --help - __fish_print_help eval - return 0 - end - end + if not set -q argv[2] + # like most builtins, we only check for -h/--help + # if we only have a single argument + switch "$argv[1]" + case -h --help + __fish_print_help eval + return 0 + end + end - # If we are in an interactive shell, eval should enable full - # job control since it should behave like the real code was - # executed. If we don't do this, commands that expect to be - # used interactively, like less, wont work using eval. + # If we are in an interactive shell, eval should enable full + # job control since it should behave like the real code was + # executed. If we don't do this, commands that expect to be + # used interactively, like less, wont work using eval. - set -l mode - if status --is-interactive-job-control - set mode interactive - else - if status --is-full-job-control - set mode full - else - set mode none - end - end - if status --is-interactive - status --job-control full - end - __fish_restore_status $status_copy + set -l mode + if status --is-interactive-job-control + set mode interactive + else + if status --is-full-job-control + set mode full + else + set mode none + end + end + if status --is-interactive + status --job-control full + end + __fish_restore_status $status_copy - # To eval 'foo', we construct a block "begin ; foo; end <&3 3<&-" - # Note the redirections are also within the quotes. - # - # We then pipe this to 'source 3<&0’. - # - # You might expect that the dup2(3, stdin) should overwrite stdin, - # and therefore prevent 'source' from reading the piped-in block. This doesn't happen - # because when you pipe to a builtin, we don't overwrite stdin with the read end - # of the block; instead we set a separate fd in a variable 'builtin_stdin', which is - # what it reads from. So builtins are magic in that, in pipes, their stdin - # is not fd 0. - # - # ‘source’ does not apply the redirections to itself. Instead it saves them and passes - # them as block-level redirections to parser.eval(). Ultimately the eval’d code sees - # the following redirections (in the following order): - # dup2 0 -> 3 - # dup2 pipe -> 0 - # dup2 3 -> 0 - # where the pipe is the pipe we get from piping ‘echo’ to ‘source’. Thus the redirection - # effectively makes stdin fd0, instead of the thing that was piped to ‘source’ - echo "begin; $argv "\n" ;end <&3 3<&-" | source 3<&0 - set -l res $status + # To eval 'foo', we construct a block "begin ; foo; end <&3 3<&-" + # Note the redirections are also within the quotes. + # + # We then pipe this to 'source 3<&0’. + # + # You might expect that the dup2(3, stdin) should overwrite stdin, + # and therefore prevent 'source' from reading the piped-in block. This doesn't happen + # because when you pipe to a builtin, we don't overwrite stdin with the read end + # of the block; instead we set a separate fd in a variable 'builtin_stdin', which is + # what it reads from. So builtins are magic in that, in pipes, their stdin + # is not fd 0. + # + # ‘source’ does not apply the redirections to itself. Instead it saves them and passes + # them as block-level redirections to parser.eval(). Ultimately the eval’d code sees + # the following redirections (in the following order): + # dup2 0 -> 3 + # dup2 pipe -> 0 + # dup2 3 -> 0 + # where the pipe is the pipe we get from piping ‘echo’ to ‘source’. Thus the redirection + # effectively makes stdin fd0, instead of the thing that was piped to ‘source’ + echo "begin; $argv "\n" ;end <&3 3<&-" | source 3<&0 + set -l res $status - status --job-control $mode - return $res + status --job-control $mode + return $res end diff --git a/share/functions/fish_clipboard_copy.fish b/share/functions/fish_clipboard_copy.fish index a65efc045..a973e4437 100644 --- a/share/functions/fish_clipboard_copy.fish +++ b/share/functions/fish_clipboard_copy.fish @@ -1,5 +1,5 @@ function fish_clipboard_copy - if type -q pbcopy + if type -q pbcopy commandline | pbcopy else if type -q xsel commandline | xsel --clipboard diff --git a/share/functions/fish_clipboard_paste.fish b/share/functions/fish_clipboard_paste.fish index c6a4a3e45..318b935d3 100644 --- a/share/functions/fish_clipboard_paste.fish +++ b/share/functions/fish_clipboard_paste.fish @@ -1,7 +1,14 @@ function fish_clipboard_paste - if type -q pbpaste + if type -q pbpaste commandline -i -- (pbpaste) else if type -q xsel - commandline -i -- (xsel --clipboard) + # Only run `commandline` if `xsel` succeeded. + # That way any xsel error is printed (to show e.g. a non-functioning X connection), + # but we don't print the redundant (and overly verbose for this) commandline error. + # Also require non-empty contents to not clear the buffer. + if set -l data (xsel --clipboard) + and test -n "$data" + commandline -i -- $data + end end end diff --git a/share/functions/fish_config.fish b/share/functions/fish_config.fish index 9bcac866e..48b113c78 100644 --- a/share/functions/fish_config.fish +++ b/share/functions/fish_config.fish @@ -1,9 +1,9 @@ function fish_config --description "Launch fish's web based configuration" - # Support passing an initial tab like "colors" or "functions" - set -l initial_tab - if count $argv >/dev/null - set initial_tab $argv[1] - end - set -x __fish_bin_dir $__fish_bin_dir - eval (string escape $__fish_datadir/tools/web_config/webconfig.py) $initial_tab + # Support passing an initial tab like "colors" or "functions" + set -l initial_tab + if count $argv >/dev/null + set initial_tab $argv[1] + end + set -x __fish_bin_dir $__fish_bin_dir + eval (string escape $__fish_datadir/tools/web_config/webconfig.py) $initial_tab end diff --git a/share/functions/fish_default_key_bindings.fish b/share/functions/fish_default_key_bindings.fish index 29fccad2d..008b183cb 100644 --- a/share/functions/fish_default_key_bindings.fish +++ b/share/functions/fish_default_key_bindings.fish @@ -1,86 +1,93 @@ - function fish_default_key_bindings -d "Default (Emacs-like) key bindings for fish" - if not set -q argv[1] - # Clear earlier bindings, if any - bind --erase --all - if test "$fish_key_bindings" != "fish_default_key_bindings" - # Allow the user to set the variable universally - set -q fish_key_bindings; or set -g fish_key_bindings - set fish_key_bindings fish_default_key_bindings # This triggers the handler, which calls us again and ensures the user_key_bindings are executed - return - end - end + if contains -- -h $argv + or contains -- --help $argv + echo "Sorry but this function doesn't support -h or --help" + return 1 + end + + if not set -q argv[1] + bind --erase --all # clear earlier bindings, if any + if test "$fish_key_bindings" != "fish_default_key_bindings" + # Allow the user to set the variable universally + set -q fish_key_bindings + or set -g fish_key_bindings + # This triggers the handler, which calls us again and ensures the user_key_bindings + # are executed. + set fish_key_bindings fish_default_key_bindings + return + end + end # These are shell-specific bindings that we share with vi mode. __fish_shared_key_bindings $argv + or return # protect against invalid $argv - # This is the default binding, i.e. the one used if no other binding matches - bind $argv "" self-insert + # This is the default binding, i.e. the one used if no other binding matches + bind $argv "" self-insert + or exit # protect against invalid $argv - bind $argv \n execute - bind $argv \r execute + bind $argv \n execute + bind $argv \r execute - bind $argv \ck kill-line + bind $argv \ck kill-line - bind $argv \eOC forward-char - bind $argv \eOD backward-char - bind $argv \e\[C forward-char - bind $argv \e\[D backward-char - bind $argv -k right forward-char - bind $argv -k left backward-char + bind $argv \eOC forward-char + bind $argv \eOD backward-char + bind $argv \e\[C forward-char + bind $argv \e\[D backward-char + bind $argv -k right forward-char + bind $argv -k left backward-char - bind $argv -k dc delete-char - bind $argv -k backspace backward-delete-char - bind $argv \x7f backward-delete-char + bind $argv -k dc delete-char + bind $argv -k backspace backward-delete-char + bind $argv \x7f backward-delete-char - # for PuTTY - # https://github.com/fish-shell/fish-shell/issues/180 - bind $argv \e\[1~ beginning-of-line - bind $argv \e\[3~ delete-char - bind $argv \e\[4~ end-of-line + # for PuTTY + # https://github.com/fish-shell/fish-shell/issues/180 + bind $argv \e\[1~ beginning-of-line + bind $argv \e\[3~ delete-char + bind $argv \e\[4~ end-of-line - # OS X SnowLeopard doesn't have these keys. Don't show an annoying error message. - bind $argv -k home beginning-of-line 2> /dev/null - bind $argv -k end end-of-line 2> /dev/null - bind $argv \e\[3\;2~ backward-delete-char # Mavericks Terminal.app shift-delete + # OS X SnowLeopard doesn't have these keys. Don't show an annoying error message. + bind $argv -k home beginning-of-line 2>/dev/null + bind $argv -k end end-of-line 2>/dev/null + bind $argv \e\[3\;2~ backward-delete-char # Mavericks Terminal.app shift-ctrl-delete - bind $argv \ca beginning-of-line - bind $argv \ce end-of-line - bind $argv \ch backward-delete-char - bind $argv \cp up-or-search - bind $argv \cn down-or-search - bind $argv \cf forward-char - bind $argv \cb backward-char - bind $argv \ct transpose-chars - bind $argv \et transpose-words - bind $argv \eu upcase-word + bind $argv \ca beginning-of-line + bind $argv \ce end-of-line + bind $argv \ch backward-delete-char + bind $argv \cp up-or-search + bind $argv \cn down-or-search + bind $argv \cf forward-char + bind $argv \cb backward-char + bind $argv \ct transpose-chars + bind $argv \et transpose-words + bind $argv \eu upcase-word - # This clashes with __fish_list_current_token - # bind $argv \el downcase-word - bind $argv \ec capitalize-word - bind $argv \e\x7f backward-kill-word - bind $argv \eb backward-word - bind $argv \ef forward-word - bind $argv \e\[1\;5C forward-word - bind $argv \e\[1\;5D backward-word - bind $argv -k ppage beginning-of-history - bind $argv -k npage end-of-history - bind $argv \e\< beginning-of-buffer - bind $argv \e\> end-of-buffer + # This clashes with __fish_list_current_token + # bind $argv \el downcase-word + bind $argv \ec capitalize-word + bind $argv \e\x7f backward-kill-word + bind $argv \eb backward-word + bind $argv \ef forward-word + bind $argv \e\[1\;5C forward-word + bind $argv \e\[1\;5D backward-word + bind $argv \e\< beginning-of-buffer + bind $argv \e\> end-of-buffer - bind \ed forward-kill-word - bind \ed kill-word + bind \ed forward-kill-word + bind \ed kill-word - # Ignore some known-bad control sequences - # https://github.com/fish-shell/fish-shell/issues/1917 - bind \e\[I 'begin;end' - bind \e\[O 'begin;end' + # Ignore some known-bad control sequences + # https://github.com/fish-shell/fish-shell/issues/1917 + bind \e\[I 'begin;end' + bind \e\[O 'begin;end' - # term-specific special bindings - switch "$TERM" - case 'rxvt*' - bind $argv \e\[8~ end-of-line - bind $argv \eOc forward-word - bind $argv \eOd backward-word - end + # term-specific special bindings + switch "$TERM" + case 'rxvt*' + bind $argv \e\[8~ end-of-line + bind $argv \eOc forward-word + bind $argv \eOd backward-word + end end diff --git a/share/functions/fish_default_mode_prompt.fish b/share/functions/fish_default_mode_prompt.fish new file mode 100644 index 000000000..638c07f9e --- /dev/null +++ b/share/functions/fish_default_mode_prompt.fish @@ -0,0 +1,23 @@ +function fish_default_mode_prompt --description "Display the default mode for the prompt" + # Do nothing if not in vi mode + if test "$fish_key_bindings" = "fish_vi_key_bindings" + or test "$fish_key_bindings" = "fish_hybrid_key_bindings" + switch $fish_bind_mode + case default + set_color --bold --background red white + echo '[N]' + case insert + set_color --bold --background green white + echo '[I]' + case replace-one + set_color --bold --background green white + echo '[R]' + case visual + set_color --bold --background magenta white + echo '[V]' + end + set_color normal + echo -n ' ' + end +end + diff --git a/share/functions/fish_fallback_prompt.fish b/share/functions/fish_fallback_prompt.fish index 1910eeaea..d8b976001 100644 --- a/share/functions/fish_fallback_prompt.fish +++ b/share/functions/fish_fallback_prompt.fish @@ -3,20 +3,20 @@ # Set the default prompt command. function fish_fallback_prompt --description "A simple fallback prompt without too much color or special characters for linux VTs" - set -l color_cwd - set -l suffix - switch $USER - case root toor - if set -q fish_color_cwd_root - set color_cwd $fish_color_cwd_root - else - set color_cwd $fish_color_cwd - end - set suffix '#' - case '*' - set color_cwd $fish_color_cwd - set suffix '>' - end + set -l color_cwd + set -l suffix + switch $USER + case root toor + if set -q fish_color_cwd_root + set color_cwd $fish_color_cwd_root + else + set color_cwd $fish_color_cwd + end + set suffix '#' + case '*' + set color_cwd $fish_color_cwd + set suffix '>' + end - echo -n -s "$USER" @ (prompt_hostname) ' ' (set_color $color_cwd) (prompt_pwd) (set_color normal) "$suffix " + echo -n -s "$USER" @ (prompt_hostname) ' ' (set_color $color_cwd) (prompt_pwd) (set_color normal) "$suffix " end diff --git a/share/functions/fish_hybrid_key_bindings.fish b/share/functions/fish_hybrid_key_bindings.fish new file mode 100644 index 000000000..bf2bbf015 --- /dev/null +++ b/share/functions/fish_hybrid_key_bindings.fish @@ -0,0 +1,18 @@ +function fish_hybrid_key_bindings --description "Vi-style bindings that inherit emacs-style bindings in all modes" + bind --erase --all # clear earlier bindings, if any + + if test "$fish_key_bindings" != "fish_hybrid_key_bindings" + # Allow the user to set the variable universally + set -q fish_key_bindings + or set -g fish_key_bindings + # This triggers the handler, which calls us again and ensures the user_key_bindings + # are executed. + set fish_key_bindings fish_hybrid_key_bindings + return + end + + for mode in default insert visual + fish_default_key_bindings -M $mode + end + fish_vi_key_bindings --no-erase +end diff --git a/share/functions/fish_indent.fish b/share/functions/fish_indent.fish index a97e1c2e8..03e30995a 100644 --- a/share/functions/fish_indent.fish +++ b/share/functions/fish_indent.fish @@ -1,6 +1,6 @@ # check if command fish_indent works and is the same version that # came with this fish. This will happen one time. -command -s fish_indent > /dev/null +command -s fish_indent >/dev/null and command fish_indent --version 2>&1 | string match -rq $FISH_VERSION # if alias doesn't define the function here, this is an autoloaded "nothing". # the command (if there is one) will be used by default. diff --git a/share/functions/fish_key_reader.fish b/share/functions/fish_key_reader.fish index 5a955e13f..0cf5b29a7 100644 --- a/share/functions/fish_key_reader.fish +++ b/share/functions/fish_key_reader.fish @@ -1,6 +1,6 @@ # check if command fish_key_reader works and is the same version that # came with this fish. This will happen one time. -command -s fish_key_reader > /dev/null +command -s fish_key_reader >/dev/null and command fish_key_reader --version 2>&1 | string match -rq $FISH_VERSION # if alias doesn't define the function here, this is an autoloaded "nothing". # the command (if there is one) will be used by default. diff --git a/share/functions/fish_mode_prompt.fish b/share/functions/fish_mode_prompt.fish index eed75d42d..294ebeebb 100644 --- a/share/functions/fish_mode_prompt.fish +++ b/share/functions/fish_mode_prompt.fish @@ -1,22 +1,5 @@ # The fish_mode_prompt function is prepended to the prompt function fish_mode_prompt --description "Displays the current mode" - # Do nothing if not in vi mode - if test "$fish_key_bindings" = "fish_vi_key_bindings" - switch $fish_bind_mode - case default - set_color --bold --background red white - echo '[N]' - case insert - set_color --bold --background green white - echo '[I]' - case replace-one - set_color --bold --background green white - echo '[R]' - case visual - set_color --bold --background magenta white - echo '[V]' - end - set_color normal - echo -n ' ' - end + # To reuse the mode indicator use this function instead + fish_default_mode_prompt end diff --git a/share/functions/fish_prompt.fish b/share/functions/fish_prompt.fish index 7f8581971..153d3adbc 100644 --- a/share/functions/fish_prompt.fish +++ b/share/functions/fish_prompt.fish @@ -3,20 +3,20 @@ # Set the default prompt command. function fish_prompt --description "Write out the prompt" - set -l color_cwd - set -l suffix - switch $USER - case root toor - if set -q fish_color_cwd_root - set color_cwd $fish_color_cwd_root - else - set color_cwd $fish_color_cwd - end - set suffix '#' - case '*' - set color_cwd $fish_color_cwd - set suffix '>' - end + set -l color_cwd + set -l suffix + switch $USER + case root toor + if set -q fish_color_cwd_root + set color_cwd $fish_color_cwd_root + else + set color_cwd $fish_color_cwd + end + set suffix '#' + case '*' + set color_cwd $fish_color_cwd + set suffix '>' + end - echo -n -s "$USER" @ (prompt_hostname) ' ' (set_color $color_cwd) (prompt_pwd) (set_color normal) "$suffix " + echo -n -s "$USER" @ (prompt_hostname) ' ' (set_color $color_cwd) (prompt_pwd) (set_color normal) "$suffix " end diff --git a/share/functions/fish_update_completions.fish b/share/functions/fish_update_completions.fish index 17b47ecb9..0fb007983 100644 --- a/share/functions/fish_update_completions.fish +++ b/share/functions/fish_update_completions.fish @@ -1,4 +1,4 @@ function fish_update_completions --description "Update man-page based completions" - # Clean up old paths - python -B $__fish_datadir/tools/create_manpage_completions.py --manpath --progress --cleanup-in '~/.config/fish/completions' --cleanup-in '~/.config/fish/generated_completions' + # Clean up old paths + python -B $__fish_datadir/tools/create_manpage_completions.py --manpath --progress --cleanup-in '~/.config/fish/completions' --cleanup-in '~/.config/fish/generated_completions' end diff --git a/share/functions/fish_vi_cursor.fish b/share/functions/fish_vi_cursor.fish index 1ab8ef25f..0da5e2a0c 100644 --- a/share/functions/fish_vi_cursor.fish +++ b/share/functions/fish_vi_cursor.fish @@ -12,18 +12,30 @@ function fish_vi_cursor -d 'Set cursor shape for different vi modes' # e.g. tmux started in suckless' st (no support) started in konsole. # But since tmux in konsole seems rather common and that case so uncommon, # we will just fail there (though it seems that tmux or st swallow it anyway). - # + + if set -q INSIDE_EMACS + return + end + + # vte-based terms set $TERM = xterm*, but only gained support relatively recently. + # From https://bugzilla.gnome.org/show_bug.cgi?id=720821, it appears it was version 0.40.0 + if set -q VTE_VERSION + and test "$VTE_VERSION" -lt 4000 ^/dev/null + return + end + # We use the `tput` here just to see if terminfo thinks we can change the cursor. # We cannot use that sequence directly as it's not the correct one for konsole and iTerm, # and because we may want to change the cursor even though terminfo says we can't (tmux). - if not tput Ss > /dev/null ^/dev/null + if not tput Ss >/dev/null ^/dev/null # Whitelist tmux... and not begin set -q TMUX # ...in a supporting term... and begin set -q KONSOLE_PROFILE_NAME or set -q ITERM_PROFILE - or test "$VTE_VERSION" -gt 1910 + or set -q VTE_VERSION # which version is already checked above + or test (string replace -r "XTerm\((\d+)\)" '$1' -- $XTERM_VERSION) -ge 280 end # .. unless an unsupporting terminal has been started in tmux inside a supporting one and begin string match -q "screen*" -- $TERM @@ -31,13 +43,21 @@ function fish_vi_cursor -d 'Set cursor shape for different vi modes' end end and not string match -q "konsole*" -- $TERM - # Blacklist or begin - # vte-based terms set $TERM = xterm*, but only gained support relatively recently. - set -q VTE_VERSION - and test "$VTE_VERSION" -le 1910 + # TERM = xterm is special because plenty of things claim to be it, but aren't fully compatible + # This includes old vte-terms (without $VTE_VERSION), old xterms (without $XTERM_VERSION or < 280) + # and maybe other stuff. + # This needs to be kept _at least_ as long as Ubuntu 14.04 is still a thing + # because that ships a gnome-terminal without support and without $VTE_VERSION. + string match -q 'xterm*' -- $TERM + and not begin set -q KONSOLE_PROFILE_NAME + or set -q ITERM_PROFILE + or set -q VTE_VERSION # which version is already checked above + # If $XTERM_VERSION is undefined, this will return 1 and print an error. Silence it. + or test (string replace -r "XTerm\((\d+)\)" '$1' -- $XTERM_VERSION) -ge 280 ^/dev/null + end end - or set -q INSIDE_EMACS + return end @@ -50,9 +70,11 @@ function fish_vi_cursor -d 'Set cursor shape for different vi modes' switch "$terminal" case auto if set -q KONSOLE_PROFILE_NAME - or set -q ITERM_PROFILE set function __fish_cursor_konsole set uses_echo 1 + else if set -q ITERM_PROFILE + set function __fish_cursor_1337 + set uses_echo 1 else set function __fish_cursor_xterm set uses_echo 1 @@ -68,7 +90,7 @@ function fish_vi_cursor -d 'Set cursor shape for different vi modes' set -l tmux_prefix set -l tmux_postfix if set -q TMUX - and set -q uses_echo[1] + and set -q uses_echo[1] set tmux_prefix echo -ne "'\ePtmux;\e'" set tmux_postfix echo -ne "'\e\\\\'" end diff --git a/share/functions/fish_vi_key_bindings.fish b/share/functions/fish_vi_key_bindings.fish index 1e03359df..51d8adebf 100644 --- a/share/functions/fish_vi_key_bindings.fish +++ b/share/functions/fish_vi_key_bindings.fish @@ -1,29 +1,41 @@ function fish_vi_key_bindings --description 'vi-like key bindings for fish' + if contains -- -h $argv + or contains -- --help $argv + echo "Sorry but this function doesn't support -h or --help" + return 1 + end + # Erase all bindings if not explicitly requested otherwise to # allow for hybrid bindings. # This needs to be checked here because if we are called again # via the variable handler the argument will be gone. - if not contains -- $argv[1] --no-erase - bind --erase --all - else if set -q argv[1] + set -l rebind true + if test "$argv[1]" = "--no-erase" + set rebind false set -e argv[1] + else + bind --erase --all # clear earlier bindings, if any end # Allow just calling this function to correctly set the bindings. # Because it's a rather discoverable name, users will execute it # and without this would then have subtly broken bindings. if test "$fish_key_bindings" != "fish_vi_key_bindings" - # Allow the user to set the variable universally + and test "$rebind" = "true" + # Allow the user to set the variable universally. set -q fish_key_bindings or set -g fish_key_bindings - set fish_key_bindings fish_vi_key_bindings # This triggers the handler, which calls us again and ensures the user_key_bindings are executed + # This triggers the handler, which calls us again and ensures the user_key_bindings + # are executed. + set fish_key_bindings fish_vi_key_bindings return end # The default escape timeout is 300ms. But for users of Vi bindings that can be slightly # annoying when trying to switch to Vi "normal" mode. So set a shorter timeout in this case # unless the user has explicitly set the delay. - set -q fish_escape_delay_ms; or set -g fish_escape_delay_ms 100 + set -q fish_escape_delay_ms + or set -g fish_escape_delay_ms 100 set -l init_mode insert # These are only the special vi-style keys @@ -46,7 +58,7 @@ function fish_vi_key_bindings --description 'vi-like key bindings for fish' bind -M insert \r execute bind -M insert \n execute - + bind -M insert "" self-insert # Add way to kill current command line while in insert mode. @@ -98,17 +110,27 @@ function fish_vi_key_bindings --description 'vi-like key bindings for fish' bind e forward-char forward-word backward-char bind E forward-bigword backward-char - bind x delete-char - bind X backward-delete-char + # OS X SnowLeopard doesn't have these keys. Don't show an annoying error message. + # Vi/Vim doesn't support these keys in insert mode but that seems silly so we do so anyway. + bind -M insert -k home beginning-of-line 2>/dev/null + bind -M default -k home beginning-of-line 2>/dev/null + bind -M insert -k end end-of-line 2>/dev/null + bind -M default -k end end-of-line 2>/dev/null - bind -k dc delete-char + bind -M default x delete-char + bind -M default X backward-delete-char + bind -M insert -k dc delete-char + bind -M default -k dc delete-char # Backspace deletes a char in insert mode, but not in normal/default mode. bind -M insert -k backspace backward-delete-char bind -M default -k backspace backward-char + bind -M insert \ch backward-delete-char + bind -M default \ch backward-char bind -M insert \x7f backward-delete-char bind -M default \x7f backward-char - bind \e\[3\;2~ backward-delete-char # Mavericks Terminal.app shift-delete + bind -M insert \e\[3\;2~ backward-delete-char # Mavericks Terminal.app shift-ctrl-delete + bind -M default \e\[3\;2~ backward-delete-char # Mavericks Terminal.app shift-ctrl-delete bind dd kill-whole-line bind D kill-line diff --git a/share/functions/fish_vi_mode.fish b/share/functions/fish_vi_mode.fish index 49023055e..8e2a92488 100644 --- a/share/functions/fish_vi_mode.fish +++ b/share/functions/fish_vi_mode.fish @@ -1,6 +1,6 @@ function fish_vi_mode - echo 'The `fish_vi_mode` function is deprecated.' >&2 - echo 'Please switch to calling `fish_vi_key_bindings`.' >&2 - # Turn on vi keybindings - set -g fish_key_bindings fish_vi_key_bindings + echo 'The `fish_vi_mode` function is deprecated.' >&2 + echo 'Please switch to calling `fish_vi_key_bindings`.' >&2 + # Turn on vi keybindings + set -g fish_key_bindings fish_vi_key_bindings end diff --git a/share/functions/funced.fish b/share/functions/funced.fish index fd3060a7e..686c89b7c 100644 --- a/share/functions/funced.fish +++ b/share/functions/funced.fish @@ -48,9 +48,9 @@ function funced --description 'Edit function definition' set -l init switch $funcname case '-*' - set init function -- $funcname\n\nend + set init function -- $funcname\n\nend case '*' - set init function $funcname\n\nend + set init function $funcname\n\nend end # Break editor up to get its first command (i.e. discard flags) @@ -63,13 +63,16 @@ function funced --description 'Edit function definition' set editor fish end end - + # If no editor is specified, use fish if test -z "$editor" set editor fish end - if begin; set -q interactive[1]; or test "$editor" = fish; end + if begin + set -q interactive[1] + or test "$editor" = fish + end set -l IFS if functions -q -- $funcname # Shadow IFS here to avoid array splitting in command substitution @@ -89,40 +92,41 @@ function funced --description 'Edit function definition' # OSX mktemp is rather restricted - no suffix, no way to automatically use TMPDIR # Create a directory so we can use a ".fish" suffix for the file - makes editors pick up that it's a fish file - set -q TMPDIR; or set -l TMPDIR /tmp + set -q TMPDIR + or set -l TMPDIR /tmp set -l tmpdir (mktemp -d $TMPDIR/fish.XXXXXX) set -l tmpname $tmpdir/$funcname.fish if functions -q -- $funcname - functions -- $funcname > $tmpname + functions -- $funcname >$tmpname else - echo $init > $tmpname + echo $init >$tmpname end - # Repeatedly edit until it either parses successfully, or the user cancels - # If the editor command itself fails, we assume the user cancelled or the file - # could not be edited, and we do not try again - while true - if not eval $editor $tmpname - _ "Editing failed or was cancelled" - echo - else - if not source $tmpname - # Failed to source the function file. Prompt to try again. - echo # add a line between the parse error and the prompt - set -l repeat - set -l prompt (_ 'Edit the file again\? [Y/n]') - while test -z "$repeat" - read -p "echo $prompt\ " repeat - end - if not contains $repeat n N no NO No nO - continue - end - _ "Cancelled function editing" - echo - end + # Repeatedly edit until it either parses successfully, or the user cancels + # If the editor command itself fails, we assume the user cancelled or the file + # could not be edited, and we do not try again + while true + if not eval $editor $tmpname + _ "Editing failed or was cancelled" + echo + else + if not source $tmpname + # Failed to source the function file. Prompt to try again. + echo # add a line between the parse error and the prompt + set -l repeat + set -l prompt (_ 'Edit the file again\? [Y/n]') + while test -z "$repeat" + read -p "echo $prompt\ " repeat end - break + if not contains $repeat n N no NO No nO + continue + end + _ "Cancelled function editing" + echo + end end + break + end set -l stat $status rm $tmpname >/dev/null and rmdir $tmpdir >/dev/null diff --git a/share/functions/funcsave.fish b/share/functions/funcsave.fish index bbf7a32a8..cbd186efe 100644 --- a/share/functions/funcsave.fish +++ b/share/functions/funcsave.fish @@ -1,43 +1,43 @@ function funcsave --description "Save the current definition of all specified functions to file" - if count $argv >/dev/null - switch $argv[1] - case -h --h --he --hel --help - __fish_print_help funcsave - return 0 - end - else - printf (_ "%s: Expected function name\n") funcsave - __fish_print_help funcsave - return 1 - end + if count $argv >/dev/null + switch $argv[1] + case -h --h --he --hel --help + __fish_print_help funcsave + return 0 + end + else + printf (_ "%s: Expected function name\n") funcsave + __fish_print_help funcsave + return 1 + end - set -l res 0 + set -l res 0 - set -l configdir ~/.config - if set -q XDG_CONFIG_HOME - set configdir $XDG_CONFIG_HOME - end + set -l configdir ~/.config + if set -q XDG_CONFIG_HOME + set configdir $XDG_CONFIG_HOME + end - for i in $configdir $configdir/fish $configdir/fish/functions - if not test -d $i - if not command mkdir $i >/dev/null - printf (_ "%s: Could not create configuration directory\n") funcsave - return 1 - end - end - end + for i in $configdir $configdir/fish $configdir/fish/functions + if not test -d $i + if not command mkdir $i >/dev/null + printf (_ "%s: Could not create configuration directory\n") funcsave + return 1 + end + end + end - for i in $argv - if functions -q -- $i - functions -- $i > $configdir/fish/functions/$i.fish - else - printf (_ "%s: Unknown function '%s'\n") funcsave $i - set res 1 - end - end + for i in $argv + if functions -q -- $i + functions -- $i >$configdir/fish/functions/$i.fish + else + printf (_ "%s: Unknown function '%s'\n") funcsave $i + set res 1 + end + end - return $res + return $res end diff --git a/share/functions/grep.fish b/share/functions/grep.fish index bedf18be7..0647494fa 100644 --- a/share/functions/grep.fish +++ b/share/functions/grep.fish @@ -3,7 +3,7 @@ # if echo | command grep --color=auto "" >/dev/null 2>&1 - function grep - command grep --color=auto $argv - end + function grep + command grep --color=auto $argv + end end diff --git a/share/functions/help.fish b/share/functions/help.fish index 23467a487..341f79aad 100644 --- a/share/functions/help.fish +++ b/share/functions/help.fish @@ -1,154 +1,151 @@ function help --description 'Show help for the fish shell' - - # Declare variables to set correct scope - set -l fish_browser - set -l fish_browser_bg - set -l h syntax completion editor job-control todo bugs history killring help - set h $h color prompt title variables builtin-overview changes expand - set h $h expand-variable expand-home expand-brace expand-wildcard - set -l help_topics $h expand-command-substitution expand-process + # Declare variables to set correct scope + set -l fish_browser - # 'help -h' should launch 'help help' - if count $argv >/dev/null - switch $argv[1] - case -h --h --he --hel --help - __fish_print_help help - return 0 - end - end + set -l h syntax completion editor job-control todo bugs history killring help + set h $h color prompt title variables builtin-overview changes expand + set h $h expand-variable expand-home expand-brace expand-wildcard + set -l help_topics $h expand-command-substitution expand-process - # - # Find a suitable browser for viewing the help pages. This is needed - # by the help function defined below. - # - set -l graphical_browsers htmlview x-www-browser firefox galeon mozilla konqueror epiphany opera netscape rekonq google-chrome chromium-browser - set -l text_browsers htmlview www-browser links elinks lynx w3m + # 'help -h' should launch 'help help' + if count $argv >/dev/null + switch $argv[1] + case -h --h --he --hel --help + __fish_print_help help + return 0 + end + end - if type -q "$BROWSER" - # User has manually set a preferred browser, so we respect that - set fish_browser $BROWSER + # + # Find a suitable browser for viewing the help pages. This is needed + # by the help function defined below. + # + set -l graphical_browsers htmlview x-www-browser firefox galeon mozilla konqueror epiphany opera netscape rekonq google-chrome chromium-browser - # If browser is known to be graphical, put into background - if contains -- $BROWSER $graphical_browsers - set fish_browser_bg 1 - end - else - # Check for a text-based browser. - for i in $text_browsers - if type -q -f $i - set fish_browser $i - break - end - end + if set -q fish_help_browser[1] + # User has set a fish-specific help browser. This overrides the + # browser that may be defined by $BROWSER. The fish_help_browser + # variable may be an array containing a browser name plus options. + set fish_browser $fish_help_browser + else + set -l text_browsers htmlview www-browser links elinks lynx w3m - # If we are in a graphical environment, check if there is a graphical - # browser to use instead. - if test "$DISPLAY" -a \( "$XAUTHORITY" = "$HOME/.Xauthority" -o "$XAUTHORITY" = "" \) - for i in $graphical_browsers - if type -q -f $i - set fish_browser $i - set fish_browser_bg 1 - break - end - end - end + if set -q BROWSER + # User has manually set a preferred browser, so we respect that + set fish_browser $BROWSER + else + # Check for a text-based browser. + for i in $text_browsers + if type -q -f $i + set fish_browser $i + break + end + end - # If the OS appears to be Windows (graphical), try to use cygstart - if type -q cygstart - set fish_browser cygstart - # If xdg-open is available, just use that - else if type -q xdg-open - set fish_browser xdg-open - end - - - # On OS X, we go through osascript by default - if test (uname) = Darwin - if type -q osascript - set fish_browser osascript - end - end + # If we are in a graphical environment, check if there is a graphical + # browser to use instead. + if test "$DISPLAY" -a \( "$XAUTHORITY" = "$HOME/.Xauthority" -o "$XAUTHORITY" = "" \) + for i in $graphical_browsers + if type -q -f $i + set fish_browser $i + break + end + end + end - end + # If the OS appears to be Windows (graphical), try to use cygstart + if type -q cygstart + set fish_browser cygstart + # If xdg-open is available, just use that + else if type -q xdg-open + set fish_browser xdg-open + end - if test -z $fish_browser - printf (_ '%s: Could not find a web browser.\n') help - printf (_ 'Please set the variable $BROWSER to a suitable browser and try again.\n\n') - return 1 - end + # On OS X, we go through osascript by default + if test (uname) = Darwin + if type -q osascript + set fish_browser osascript + end + end + end + end - # In Cygwin, start the user-specified browser using cygstart - if type -q cygstart - if test $fish_browser != "cygstart" - # Escaped quotes are necessary to work with spaces in the path - # when the command is finally eval'd. - set fish_browser cygstart \"$fish_browser\" - end - end + if not set -q fish_browser + printf (_ '%s: Could not find a web browser.\n') help + printf (_ 'Please set the variable $BROWSER or fish_help_browser and try again.\n\n') + return 1 + end - set -l fish_help_item $argv[1] + # In Cygwin, start the user-specified browser using cygstart + if type -q cygstart + if test $fish_browser != "cygstart" + # Escaped quotes are necessary to work with spaces in the path + # when the command is finally eval'd. + set fish_browser cygstart \"$fish_browser\" + end + end - switch "$fish_help_item" - case "" - set fish_help_page index.html - case "." - set fish_help_page "commands.html\#source" - case globbing - set fish_help_page "index.html\#expand" - case (__fish_print_commands) - set fish_help_page "commands.html\#$fish_help_item" - case $help_topics - set fish_help_page "index.html\#$fish_help_item" - case "*" - if type -q -f $fish_help_item - # Prefer to use fish's man pages, to avoid - # the annoying useless "builtin" man page bash - # installs on OS X - set -l man_arg "$__fish_datadir/man/man1/$fish_help_item.1" - if test -f "$man_arg" - man $man_arg - return - end - end - set fish_help_page "index.html" - end - - set -l page_url - if test -f $__fish_help_dir/index.html - # Help is installed, use it - set page_url file://$__fish_help_dir/$fish_help_page + set -l fish_help_item $argv[1] - # In Cygwin, we need to convert the base help dir to a Windows path before converting it to a file URL - if type -q cygpath - set page_url file://(cygpath -m $__fish_help_dir)/$fish_help_page - end - else - # Go to the web. Only include one dot in the version string - set -l version_string (echo $FISH_VERSION| cut -d . -f 1,2) - set page_url http://fishshell.com/docs/$version_string/$fish_help_page - end - - # OS X /usr/bin/open swallows fragments (anchors), so use osascript - # Eval is just a cheesy way of removing the hash escaping - if test "$fish_browser" = osascript - osascript -e 'open location "'(eval echo $page_url)'"' - return - end - - if test $fish_browser_bg + switch "$fish_help_item" + case "" + set fish_help_page index.html + case "." + set fish_help_page "commands.html\#source" + case globbing + set fish_help_page "index.html\#expand" + case (__fish_print_commands) + set fish_help_page "commands.html\#$fish_help_item" + case $help_topics + set fish_help_page "index.html\#$fish_help_item" + case "*" + if type -q -f $fish_help_item + # Prefer to use fish's man pages, to avoid + # the annoying useless "builtin" man page bash + # installs on OS X + set -l man_arg "$__fish_datadir/man/man1/$fish_help_item.1" + if test -f "$man_arg" + man $man_arg + return + end + end + set fish_help_page "index.html" + end - switch $fish_browser - case 'htmlview' 'x-www-browser' - printf (_ 'help: Help is being displayed in your default browser.\n') + set -l page_url + if test -f $__fish_help_dir/index.html + # Help is installed, use it + set page_url file://$__fish_help_dir/$fish_help_page - case '*' - printf (_ 'help: Help is being displayed in %s.\n') $fish_browser + # In Cygwin, we need to convert the base help dir to a Windows path before converting it to a file URL + if type -q cygpath + set page_url file://(cygpath -m $__fish_help_dir)/$fish_help_page + end + else + # Go to the web. Only include one dot in the version string + set -l version_string (echo $FISH_VERSION| cut -d . -f 1,2) + set page_url http://fishshell.com/docs/$version_string/$fish_help_page + end - end + # OS X /usr/bin/open swallows fragments (anchors), so use osascript + # Eval is just a cheesy way of removing the hash escaping + if test "$fish_browser" = osascript + osascript -e 'open location "'(eval echo $page_url)'"' + return + end - eval "$fish_browser $page_url &" - else - eval $fish_browser $page_url - end + + # If browser is known to be graphical, put into background + if contains -- $fish_browser[1] $graphical_browsers + switch $fish_browser[1] + case 'htmlview' 'x-www-browser' + printf (_ 'help: Help is being displayed in your default browser.\n') + case '*' + printf (_ 'help: Help is being displayed in %s.\n') $fish_browser[1] + end + eval "$fish_browser $page_url &" + else + eval $fish_browser $page_url + end end diff --git a/share/functions/hostname.fish b/share/functions/hostname.fish index d4d2d2591..e45d984de 100644 --- a/share/functions/hostname.fish +++ b/share/functions/hostname.fish @@ -1,10 +1,10 @@ # Query for USERDOMAIN to shorten waiting times when OS isn't Windows. set -q USERDOMAIN and switch (uname) -case 'CYGWIN_*' - # Cygwin's hostname is broken when computer name contains Unicode - # characters. This hack "fixes" hostname in Cygwin. - function hostname --description "Show or set the system's host name" - echo $USERDOMAIN - end + case 'CYGWIN_*' + # Cygwin's hostname is broken when computer name contains Unicode + # characters. This hack "fixes" hostname in Cygwin. + function hostname --description "Show or set the system's host name" + echo $USERDOMAIN + end end diff --git a/share/functions/isatty.fish b/share/functions/isatty.fish index df8199250..02282928a 100644 --- a/share/functions/isatty.fish +++ b/share/functions/isatty.fish @@ -1,30 +1,30 @@ function isatty -d "Tests if a file descriptor is a tty" - set -l fd 0 - if count $argv >/dev/null - switch $argv[1] + set -l fd 0 + if count $argv >/dev/null + switch $argv[1] - case -h --h --he --hel --help - __fish_print_help isatty - return 0 + case -h --h --he --hel --help + __fish_print_help isatty + return 0 - case stdin '' - set fd 0 + case stdin '' + set fd 0 - case stdout - set fd 1 + case stdout + set fd 1 - case stderr - set fd 2 + case stderr + set fd 2 - case '*' - set fd $argv[1] + case '*' + set fd $argv[1] - end - end + end + end - # Use `command test` because `builtin test` doesn't open the regular fd's. - # See https://github.com/fish-shell/fish-shell/issues/1228 - command test -t "$fd" + # Use `command test` because `builtin test` doesn't open the regular fd's. + # See https://github.com/fish-shell/fish-shell/issues/1228 + command test -t "$fd" end diff --git a/share/functions/la.fish b/share/functions/la.fish index 818aa11ec..355e1f83a 100644 --- a/share/functions/la.fish +++ b/share/functions/la.fish @@ -2,6 +2,6 @@ # These are very common and useful # function la --description "List contents of directory, including hidden files in directory using long format" - ls -lah $argv + ls -lah $argv end diff --git a/share/functions/ll.fish b/share/functions/ll.fish index d5aba9e57..e8230f4ec 100644 --- a/share/functions/ll.fish +++ b/share/functions/ll.fish @@ -2,5 +2,5 @@ # These are very common and useful # function ll --description "List contents of directory using long format" - ls -lh $argv + ls -lh $argv end diff --git a/share/functions/ls.fish b/share/functions/ls.fish index 2da4d6b81..7418195f4 100644 --- a/share/functions/ls.fish +++ b/share/functions/ls.fish @@ -1,36 +1,37 @@ # -# Make ls use colors if we are on a system that supports this +# Make ls use colors if we are on a system that supports that feature and writing to stdout. # +if command ls --version >/dev/null ^/dev/null + # This appears to be GNU ls. + function ls --description "List contents of directory" + set -l param --color=auto + if isatty 1 + set param $param --indicator-style=classify + end + command ls $param $argv + end -if command ls --version 1>/dev/null 2>/dev/null - # This is GNU ls - function ls --description "List contents of directory" - set -l param --color=auto - if isatty 1 - set param $param --indicator-style=classify - end - command ls $param $argv - end - - if not set -q LS_COLORS - if type -q -f dircolors - set -l colorfile - for file in ~/.dir_colors ~/.dircolors /etc/DIR_COLORS - if test -f $file - set colorfile $file - break - end - end - set -gx LS_COLORS (dircolors -c $colorfile | string replace -r 'setenv LS_COLORS \'(.*)\'' '$1') - end - end - -else - # BSD, OS X and a few more support colors through the -G switch instead - if command ls -G / 1>/dev/null 2>/dev/null - function ls --description "List contents of directory" - command ls -G $argv - end - end + if not set -q LS_COLORS + if command -s dircolors >/dev/null + set -l colorfile + for file in ~/.dir_colors ~/.dircolors /etc/DIR_COLORS + if test -f $file + set colorfile $file + break + end + end + # Here we rely on the legacy behavior of `dircolors -c` producing output suitable for + # csh in order to extract just the data we're interested in. + set -gx LS_COLORS (dircolors -c $colorfile | string split ' ')[3] + # The value should always be quoted but be conservative and check first. + if string match -qr '^([\'"]).*\1$' -- $LS_COLORS + set LS_COLORS (string match -r '^.(.*).$' $LS_COLORS)[2] + end + end + end +else if command ls -G / >/dev/null ^/dev/null + # It looks like BSD, OS X and a few more which support colors through the -G switch instead. + function ls --description "List contents of directory" + command ls -G $argv + end end - diff --git a/share/functions/man.fish b/share/functions/man.fish index 25c81a4bb..c9d3ff7f0 100644 --- a/share/functions/man.fish +++ b/share/functions/man.fish @@ -1,23 +1,24 @@ function man --description "Format and display the on-line manual pages" - # Work around the "builtin" manpage that everything symlinks to, - # by prepending our fish datadir to man. This also ensures that man gives fish's - # man pages priority, without having to put fish's bin directories first in $PATH + # Work around the "builtin" manpage that everything symlinks to, + # by prepending our fish datadir to man. This also ensures that man gives fish's + # man pages priority, without having to put fish's bin directories first in $PATH - # Notice local but exported variable - set -lx MANPATH (string join : $MANPATH) - if test -z "$MANPATH" - type -q manpath; and set MANPATH (command manpath) - end - set -l fish_manpath (dirname $__fish_datadir)/fish/man - if test -d "$fish_manpath" -a -n "$MANPATH" - set MANPATH "$fish_manpath":$MANPATH + # Notice local but exported variable + set -lx MANPATH (string join : $MANPATH) + if test -z "$MANPATH" + type -q manpath + and set MANPATH (command manpath) + end + set -l fish_manpath (dirname $__fish_datadir)/fish/man + if test -d "$fish_manpath" -a -n "$MANPATH" + set MANPATH "$fish_manpath":$MANPATH - # Invoke man with this manpath, and we're done - command man $argv - return - end - - # If fish's man pages could not be found, just invoke man normally - command man $argv + # Invoke man with this manpath, and we're done + command man $argv + return + end + + # If fish's man pages could not be found, just invoke man normally + command man $argv end diff --git a/share/functions/math.fish b/share/functions/math.fish index ed638c695..584d1b27d 100644 --- a/share/functions/math.fish +++ b/share/functions/math.fish @@ -21,9 +21,15 @@ function math --description "Perform math calculations in bc" return 2 # no arguments is an error end - # Stitch lines together manually. We can't rely on BC_LINE_LENGTH because some systems don't - # have a new enough version of bc. - set -l out (echo "scale=$scale; $argv" | bc | string replace -r '\\\\$' '' | string join '') + # Set BC_LINE_LENGTH to a ridiculously high number so it only uses one line for most results. + # We can't use 0 since some systems (including macOS) use an ancient bc that doesn't support it. + # We also can't count on this being recognized since some BSD systems don't recognize this env + # var at all and limit the line length to 70. + set -lx BC_LINE_LENGTH 500 + set -l out (echo "scale=$scale; $argv" | bc) + if set -q out[2] + set out (string join '' (string replace \\ '' $out)) + end switch "$out" case '' # No output indicates an error occurred. diff --git a/share/functions/nextd-or-forward-word.fish b/share/functions/nextd-or-forward-word.fish index 037dd9946..9428b89e2 100644 --- a/share/functions/nextd-or-forward-word.fish +++ b/share/functions/nextd-or-forward-word.fish @@ -1,9 +1,9 @@ function nextd-or-forward-word - set -l cmd (commandline) - if test -z "$cmd" - nextd - commandline -f repaint - else - commandline -f forward-word - end + set -l cmd (commandline) + if test -z "$cmd" + nextd + commandline -f repaint + else + commandline -f forward-word + end end diff --git a/share/functions/nextd.fish b/share/functions/nextd.fish index 3f28d07ac..3a94e7d8e 100644 --- a/share/functions/nextd.fish +++ b/share/functions/nextd.fish @@ -1,18 +1,18 @@ function nextd --description "Move forward in the directory history" - if count $argv >/dev/null - switch $argv[1] - case -h --h --he --hel --help - __fish_print_help nextd - return 0 - end - end + if count $argv >/dev/null + switch $argv[1] + case -h --h --he --hel --help + __fish_print_help nextd + return 0 + end + end - # Parse arguments - set -l show_hist 0 - set -l times 1 - if count $argv > /dev/null + # Parse arguments + set -l show_hist 0 + set -l times 1 + if count $argv >/dev/null for i in (seq (count $argv)) switch $argv[$i] case '-l' --l --li --lis --list @@ -33,12 +33,13 @@ function nextd --description "Move forward in the directory history" end end - # Traverse history - set -l code 1 - if count $times > /dev/null + # Traverse history + set -l code 1 + if count $times >/dev/null for i in (seq $times) # Try one step backward - if __fish_move_last dirnext dirprev; + if __fish_move_last dirnext dirprev + # We consider it a success if we were able to do at least 1 step # (low expectations are the key to happiness ;) set code 0 @@ -48,16 +49,16 @@ function nextd --description "Move forward in the directory history" end end - # Show history if needed - if test $show_hist = 1 - dirh - end + # Show history if needed + if test $show_hist = 1 + dirh + end - # Set direction for 'cd -' - if test $code = 0 ^/dev/null - set -g __fish_cd_direction prev - end + # Set direction for 'cd -' + if test $code = 0 ^/dev/null + set -g __fish_cd_direction prev + end - # All done - return $code + # All done + return $code end diff --git a/share/functions/open.fish b/share/functions/open.fish index 9eaa7eda6..6e606aeba 100644 --- a/share/functions/open.fish +++ b/share/functions/open.fish @@ -4,25 +4,25 @@ # if not command -s open >/dev/null - function open --description "Open file in default application" - if count $argv >/dev/null - switch $argv[1] - case -h --h --he --hel --help - __fish_print_help open - return 0 - end - end + function open --description "Open file in default application" + if count $argv >/dev/null + switch $argv[1] + case -h --h --he --hel --help + __fish_print_help open + return 0 + end + end - if type -q -f cygstart - for i in $argv - cygstart $i - end - else if type -q -f xdg-open - for i in $argv - xdg-open $i - end - else - echo (_ 'No open utility found. Try installing "xdg-open" or "xdg-utils".') - end - end + if type -q -f cygstart + for i in $argv + cygstart $i + end + else if type -q -f xdg-open + for i in $argv + xdg-open $i + end + else + echo (_ 'No open utility found. Try installing "xdg-open" or "xdg-utils".') + end + end end diff --git a/share/functions/popd.fish b/share/functions/popd.fish index 44a19593d..3a8287f5f 100644 --- a/share/functions/popd.fish +++ b/share/functions/popd.fish @@ -1,19 +1,19 @@ function popd --description "Pop directory from the stack and cd to it" - if count $argv >/dev/null - switch $argv[1] - case -h --h --he --hel --help - __fish_print_help popd - return 0 - end - end + if count $argv >/dev/null + switch $argv[1] + case -h --h --he --hel --help + __fish_print_help popd + return 0 + end + end - if test $dirstack[1] - cd $dirstack[1] - else - printf (_ "%s: Directory stack is empty…\n") popd 1>&2 - return 1 - end + if test $dirstack[1] + cd $dirstack[1] + else + printf (_ "%s: Directory stack is empty…\n") popd 1>&2 + return 1 + end - set -e dirstack[1] + set -e dirstack[1] end diff --git a/share/functions/prevd-or-backward-word.fish b/share/functions/prevd-or-backward-word.fish index bbaca8aea..5f0c740ed 100644 --- a/share/functions/prevd-or-backward-word.fish +++ b/share/functions/prevd-or-backward-word.fish @@ -2,7 +2,7 @@ function prevd-or-backward-word set -l cmd (commandline) if test -z "$cmd" prevd - commandline -f repaint + commandline -f repaint else commandline -f backward-word end diff --git a/share/functions/prevd.fish b/share/functions/prevd.fish index a1e2d3d30..3b538d884 100644 --- a/share/functions/prevd.fish +++ b/share/functions/prevd.fish @@ -1,18 +1,18 @@ function prevd --description "Move back in the directory history" - if count $argv >/dev/null - switch $argv[1] - case -h --h --he --hel --help - __fish_print_help prevd - return 0 - end - end + if count $argv >/dev/null + switch $argv[1] + case -h --h --he --hel --help + __fish_print_help prevd + return 0 + end + end - # Parse arguments - set -l show_hist 0 - set -l times 1 - if count $argv > /dev/null + # Parse arguments + set -l show_hist 0 + set -l times 1 + if count $argv >/dev/null for i in (seq (count $argv)) switch $argv[$i] case '-l' --l --li --lis --list @@ -31,14 +31,15 @@ function prevd --description "Move back in the directory history" continue end end - end + end - # Traverse history - set -l code 1 - if count $times > /dev/null + # Traverse history + set -l code 1 + if count $times >/dev/null for i in (seq $times) # Try one step backward - if __fish_move_last dirprev dirnext; + if __fish_move_last dirprev dirnext + # We consider it a success if we were able to do at least 1 step # (low expectations are the key to happiness ;) set code 0 @@ -48,16 +49,16 @@ function prevd --description "Move back in the directory history" end end - # Show history if needed - if test $show_hist = 1 - dirh - end + # Show history if needed + if test $show_hist = 1 + dirh + end - # Set direction for 'cd -' - if test $code = 0 ^/dev/null - set -g __fish_cd_direction next - end + # Set direction for 'cd -' + if test $code = 0 ^/dev/null + set -g __fish_cd_direction next + end - # All done - return $code + # All done + return $code end diff --git a/share/functions/prompt_pwd.fish b/share/functions/prompt_pwd.fish index 96e9b2f33..71dfc461e 100644 --- a/share/functions/prompt_pwd.fish +++ b/share/functions/prompt_pwd.fish @@ -1,21 +1,23 @@ function prompt_pwd --description "Print the current working directory, shortened to fit the prompt" - set -q argv[1]; and switch $argv[1] - case -h --help - __fish_print_help prompt_pwd - return 0 - end + set -q argv[1] + and switch $argv[1] + case -h --help + __fish_print_help prompt_pwd + return 0 + end - # This allows overriding fish_prompt_pwd_dir_length from the outside (global or universal) without leaking it - set -q fish_prompt_pwd_dir_length; or set -l fish_prompt_pwd_dir_length 1 + # This allows overriding fish_prompt_pwd_dir_length from the outside (global or universal) without leaking it + set -q fish_prompt_pwd_dir_length + or set -l fish_prompt_pwd_dir_length 1 - # Replace $HOME with "~" - set realhome ~ - set -l tmp (string replace -r '^'"$realhome"'($|/)' '~$1' $PWD) + # Replace $HOME with "~" + set realhome ~ + set -l tmp (string replace -r '^'"$realhome"'($|/)' '~$1' $PWD) - if [ $fish_prompt_pwd_dir_length -eq 0 ] - echo $tmp - else - # Shorten to at most $fish_prompt_pwd_dir_length characters per directory - string replace -ar '(\.?[^/]{'"$fish_prompt_pwd_dir_length"'})[^/]*/' '$1/' $tmp - end + if [ $fish_prompt_pwd_dir_length -eq 0 ] + echo $tmp + else + # Shorten to at most $fish_prompt_pwd_dir_length characters per directory + string replace -ar '(\.?[^/]{'"$fish_prompt_pwd_dir_length"'})[^/]*/' '$1/' $tmp + end end diff --git a/share/functions/psub.fish b/share/functions/psub.fish index 221045312..afed1788e 100644 --- a/share/functions/psub.fish +++ b/share/functions/psub.fish @@ -1,96 +1,99 @@ function psub --description "Read from stdin into a file and output the filename. Remove the file when the command that called psub exits." - set -l dirname - set -l filename - set -l funcname - set -l suffix - set -l use_fifo 1 + set -l dirname + set -l filename + set -l funcname + set -l suffix + set -l use_fifo 1 - while count $argv >/dev/null + while count $argv >/dev/null - switch $argv[1] - case -h --help - __fish_print_help psub - return 0 + switch $argv[1] + case -h --help + __fish_print_help psub + return 0 - case -f --file - set use_fifo 0 - set -e argv[1] + case -f --file + set use_fifo 0 + set -e argv[1] - case -s --suffix - if not set -q argv[2] - printf "psub: missing operand\n" - return 1 - end - set suffix $argv[2] - set -e argv[1..2] + case -s --suffix + if not set -q argv[2] + printf "psub: missing operand\n" + return 1 + end + set suffix $argv[2] + set -e argv[1..2] - case -- - set -e argv[1] - break + case -- + set -e argv[1] + break - case "-?" "--*" - printf "psub: invalid option: '%s'\n" $argv[1] - return 1 + case "-?" "--*" + printf "psub: invalid option: '%s'\n" $argv[1] + return 1 - case "-*" - # Ungroup short options: -hfs => -h -f -s - set opts "-"(string sub -s 2 -- $argv[1] | string split "") - set -e argv[1] - set argv $opts $argv + case "-*" + # Ungroup short options: -hfs => -h -f -s + set opts "-"(string sub -s 2 -- $argv[1] | string split "") + set -e argv[1] + set argv $opts $argv - case "*" - printf "psub: extra operand: '%s'\n" $argv[1] - return 1 - end - end + case "*" + printf "psub: extra operand: '%s'\n" $argv[1] + return 1 + end + end - if not status --is-command-substitution - echo psub: Not inside of command substitution >&2 - return 1 - end + if not status --is-command-substitution + echo psub: Not inside of command substitution >&2 + return 1 + end - set -l TMPDIR $TMPDIR - if test -z "$TMPDIR[1]" - set TMPDIR /tmp - end + set -l TMPDIR $TMPDIR + if test -z "$TMPDIR[1]" + set TMPDIR /tmp + end - if test use_fifo = 1 - # Write output to pipe. This needs to be done in the background so - # that the command substitution exits without needing to wait for - # all the commands to exit - set dirname (mktemp -d "$TMPDIR[1]"/.psub.XXXXXXXXXX); or return - set filename $dirname/psub.fifo"$suffix" - mkfifo $filename - cat >$filename & - else if test -z $suffix - set filename (mktemp "$TMPDIR[1]"/.psub.XXXXXXXXXX) - cat >$filename - else - set dirname (mktemp -d "$TMPDIR[1]"/.psub.XXXXXXXXXX) - set filename $dirname/psub"$suffix" - cat >$filename - end + if test use_fifo = 1 + # Write output to pipe. This needs to be done in the background so + # that the command substitution exits without needing to wait for + # all the commands to exit + set dirname (mktemp -d "$TMPDIR[1]"/.psub.XXXXXXXXXX) + or return + set filename $dirname/psub.fifo"$suffix" + mkfifo $filename + cat >$filename & + else if test -z $suffix + set filename (mktemp "$TMPDIR[1]"/.psub.XXXXXXXXXX) + cat >$filename + else + set dirname (mktemp -d "$TMPDIR[1]"/.psub.XXXXXXXXXX) + set filename $dirname/psub"$suffix" + cat >$filename + end - # Write filename to stdout - echo $filename + # Write filename to stdout + echo $filename - # Find unique function name - while true - set funcname __fish_psub_(random); - if not functions $funcname >/dev/null ^/dev/null - break; - end - end + # Find unique function name + while true + set funcname __fish_psub_(random) - # Make sure we erase file when caller exits - function $funcname --on-job-exit caller --inherit-variable filename --inherit-variable dirname --inherit-variable funcname - command rm $filename - if count $dirname >/dev/null - command rmdir $dirname - end - functions -e $funcname - end + if not functions $funcname >/dev/null ^/dev/null + break + + end + end + + # Make sure we erase file when caller exits + function $funcname --on-job-exit caller --inherit-variable filename --inherit-variable dirname --inherit-variable funcname + command rm $filename + if count $dirname >/dev/null + command rmdir $dirname + end + functions -e $funcname + end end diff --git a/share/functions/pushd.fish b/share/functions/pushd.fish index 64f213ee1..15e509be5 100644 --- a/share/functions/pushd.fish +++ b/share/functions/pushd.fish @@ -1,77 +1,77 @@ function pushd --description 'Push directory to stack' - if count $argv >/dev/null - # check for --help - switch $argv[1] - case -h --h --he --hel --help - __fish_print_help pushd - return 0 - end + if count $argv >/dev/null + # check for --help + switch $argv[1] + case -h --h --he --hel --help + __fish_print_help pushd + return 0 + end - # emulate bash by checking if argument of form +n or -n - set -l rot_r - set -l rot_l - if string match -qr '^-[0-9]+$' -- $argv[1] - set rot_r (string sub -s 2 -- $argv[1]) - else if string match -qr '^\+[0-9]+$' -- $argv[1] - set rot_l (string sub -s 2 -- $argv[1]) - end - end + # emulate bash by checking if argument of form +n or -n + set -l rot_r + set -l rot_l + if string match -qr '^-[0-9]+$' -- $argv[1] + set rot_r (string sub -s 2 -- $argv[1]) + else if string match -qr '^\+[0-9]+$' -- $argv[1] + set rot_l (string sub -s 2 -- $argv[1]) + end + end - # emulate bash: an empty pushd should switch the top of dirs - if test (count $argv) -eq 0 - # check that the stack isn't empty - if test (count $dirstack) -eq 0 - echo "pushd: no other directory" - return 1 - end + # emulate bash: an empty pushd should switch the top of dirs + if test (count $argv) -eq 0 + # check that the stack isn't empty + if test (count $dirstack) -eq 0 + echo "pushd: no other directory" + return 1 + end - # get the top two values of the dirs stack ... the first is pwd - set -l top_dir (command pwd) - set -l next_dir $dirstack[1] + # get the top two values of the dirs stack ... the first is pwd + set -l top_dir $PWD + set -l next_dir $dirstack[1] - # alter the top of dirstack and move to directory - set -g dirstack[1] $top_dir - cd $next_dir - return - end + # alter the top of dirstack and move to directory + set -g dirstack[1] $top_dir + cd $next_dir + return + end - # emulate bash: check for rotations - if test -n "$rot_l" -o -n "$rot_r" - # grab the current stack - set -l stack (command pwd) $dirstack + # emulate bash: check for rotations + if test -n "$rot_l" -o -n "$rot_r" + # grab the current stack + set -l stack $PWD $dirstack - # translate a right rotation to a left rotation - if test -n "$rot_r" - # check the rotation in range - if test $rot_r -ge (count $stack) - echo "pushd: -$rot_r: directory stack index out of range" - return 1 - end + # translate a right rotation to a left rotation + if test -n "$rot_r" + # check the rotation in range + if test $rot_r -ge (count $stack) + echo "pushd: -$rot_r: directory stack index out of range" + return 1 + end - set rot_l (math (count $stack) - 1 - $rot_r) - end + set rot_l (math (count $stack) - 1 - $rot_r) + end - # check the rotation in range - if test $rot_l -ge (count $stack) - echo "pushd: +$rot_l: directory stack index out of range" - return 1 - else - # rotate stack unless rot_l is 0 - if test $rot_l -gt 0 - set stack $stack[(math $rot_l + 1)..(count $stack)] $stack[1..$rot_l] - end + # check the rotation in range + if test $rot_l -ge (count $stack) + echo "pushd: +$rot_l: directory stack index out of range" + return 1 + else + # rotate stack unless rot_l is 0 + if test $rot_l -gt 0 + set stack $stack[(math $rot_l + 1)..(count $stack)] $stack[1..$rot_l] + end - # now reconstruct dirstack and change directory - set -g dirstack $stack[2..(count $stack)] - cd $stack[1] - end + # now reconstruct dirstack and change directory + set -g dirstack $stack[2..(count $stack)] + cd $stack[1] + end - # print the new stack - dirs - return - end + # print the new stack + dirs + return + end - # argv[1] is a directory - set -g dirstack (command pwd) $dirstack - cd $argv[1] + # argv[1] is a directory + set -g dirstack $PWD $dirstack + cd $argv[1] end diff --git a/share/functions/realpath.fish b/share/functions/realpath.fish index e18cfd84b..f1f6743b6 100644 --- a/share/functions/realpath.fish +++ b/share/functions/realpath.fish @@ -1,50 +1,53 @@ # Provide a minimalist realpath implementation to help deal with platforms that may not provide it -# as a command. If a realpath command is available simply pass all arguments thru to it. If not -# fallback to alternative solutions. +# as a command. If an external realpath or grealpath command is available simply pass all arguments +# thru to it. If not fallback to our builtin. -# The following is slightly subtle. The first time `realpath` is invoked by autoloading this script -# will be read. If we see that there is an external realpath command we just return. That will cause -# fish to run the external command. Or, if there is a grealpath, we alias it. -# On the other hand, if an external command isn't found we provide a function that will facilitate -# fallback behavion through our builtin. +# The following is slightly subtle. We have to define a realpath function even if there is an +# external command by that name. That's because if we don't the parser will select our builtin. +# However, we only want our builtin if there is no external realpath command. -if not command -s realpath >/dev/null - # If there is a HomeBrew installed version of GNU realpath named grealpath use that. - if command -s grealpath >/dev/null - function realpath -w grealpath -d "print the resolved path [grealpath]" - grealpath $argv - end - exit 0 +if command -s realpath >/dev/null + function realpath -w realpath -d "print the resolved path [command realpath]" + command realpath $argv + end + exit 0 +end + +# If there is a HomeBrew installed version of GNU realpath named grealpath use that. +if command -s grealpath >/dev/null + function realpath -w grealpath -d "print the resolved path [command grealpath]" + command grealpath $argv + end + exit 0 +end + +function realpath -d "return an absolute path without symlinks" + if test -z "$argv" + printf "usage: %s%s%s %sfile%s …\n" (set_color -o) $_ (set_color normal) (set_color -u) (set_color normal) + echo " resolves files as absolute paths without symlinks" + return 1 end - function realpath -d "return an absolute path without symlinks" - if test -z "$argv" - printf "usage: %s%s%s %sfile%s …\n" (set_color -o) $_ (set_color normal) (set_color -u) (set_color normal) - echo " resolves files as absolute paths without symlinks" - return 1 - end + # Loop over arguments - allow our realpath to work on more than one path per invocation + # like gnu/bsd realpath. + for arg in $argv + switch $arg + # These - no can do our realpath + case -s --strip --no-symlinks -z --zero --relative-base\* --relative-to\* + __fish_print_help realpath + return 2 - # Loop over arguments - allow our realpath to work on more than one path per invocation - # like gnu/bsd realpath. - for arg in $argv - switch $arg - # These - no can do our realpath - case -s --strip --no-symlinks -z --zero --relative-base\* --relative-to\* - __fish_print_help realpath - return 2 - - case -h --help --version - __fish_print_help realpath - return 0 + case -h --help --version + __fish_print_help realpath + return 0 # Handle commands called with these arguments by dropping the arguments to protect # realpath from them. There are no sure things here. - case -e --canonicalize-existing --physical -P -q --quiet -m --canonicalize-missing - continue + case -e --canonicalize-existing --physical -P -q --quiet -m --canonicalize-missing + continue - case "*" - builtin realpath $arg - end + case "*" + builtin realpath $arg end end end diff --git a/share/functions/seq.fish b/share/functions/seq.fish index 3675c9905..4d2af7541 100644 --- a/share/functions/seq.fish +++ b/share/functions/seq.fish @@ -2,47 +2,47 @@ # We can't call type here because that also calls seq if not command -s seq >/dev/null - # No seq command - function seq --description "Print sequences of numbers" - __fish_fallback_seq $argv - end + # No seq command + function seq --description "Print sequences of numbers" + __fish_fallback_seq $argv + end - function __fish_fallback_seq --description "Fallback implementation of the seq command" - - set -l from 1 - set -l step 1 - set -l to 1 - - switch (count $argv) - case 1 - set to $argv[1] - - case 2 - set from $argv[1] - set to $argv[2] - - case 3 - set from $argv[1] - set step $argv[2] - set to $argv[3] - - case '*' - printf (_ "%s: Expected 1, 2 or 3 arguments, got %d\n") seq (count $argv) - return 1 - - end - - for i in $from $step $to - if not echo $i | grep -E '^-?[0-9]*([0-9]*|\.[0-9]+)$' >/dev/null - printf (_ "%s: '%s' is not a number\n") seq $i - return 1 - end - end - - if [ $step -ge 0 ] - echo "for( i=$from; i<=$to ; i+=$step ) i;" | bc - else - echo "for( i=$from; i>=$to ; i+=$step ) i;" | bc - end - end + function __fish_fallback_seq --description "Fallback implementation of the seq command" + + set -l from 1 + set -l step 1 + set -l to 1 + + switch (count $argv) + case 1 + set to $argv[1] + + case 2 + set from $argv[1] + set to $argv[2] + + case 3 + set from $argv[1] + set step $argv[2] + set to $argv[3] + + case '*' + printf (_ "%s: Expected 1, 2 or 3 arguments, got %d\n") seq (count $argv) + return 1 + + end + + for i in $from $step $to + if not echo $i | grep -E '^-?[0-9]*([0-9]*|\.[0-9]+)$' >/dev/null + printf (_ "%s: '%s' is not a number\n") seq $i + return 1 + end + end + + if [ $step -ge 0 ] + echo "for( i=$from; i<=$to ; i+=$step ) i;" | bc + else + echo "for( i=$from; i>=$to ; i+=$step ) i;" | bc + end + end end diff --git a/share/functions/setenv.fish b/share/functions/setenv.fish index f32a17f6e..23cc94790 100644 --- a/share/functions/setenv.fish +++ b/share/functions/setenv.fish @@ -1,4 +1,4 @@ function setenv --description 'Set global variable. Alias for set -g, made for csh compatibility' - set -gx $argv + set -gx $argv end diff --git a/share/functions/suspend.fish b/share/functions/suspend.fish index af2ce5012..1d6e35a92 100644 --- a/share/functions/suspend.fish +++ b/share/functions/suspend.fish @@ -1,7 +1,8 @@ function suspend -d "Suspend the current shell." - if contains -- $argv --help; or contains -- $argv -h - __fish_print_help suspend - and return 0 + if contains -- $argv --help + or contains -- $argv -h + __fish_print_help suspend + and return 0 end if begin contains -- $argv --force or not status --is-interactive and not status --is-login diff --git a/share/functions/trap.fish b/share/functions/trap.fish index 094d37f1b..248d91f58 100644 --- a/share/functions/trap.fish +++ b/share/functions/trap.fish @@ -1,143 +1,143 @@ function __trap_translate_signal - set upper (echo $argv[1]|tr a-z A-Z) - string replace -r '^SIG' '' -- $upper + set upper (echo $argv[1]|tr a-z A-Z) + string replace -r '^SIG' '' -- $upper end function __trap_switch - switch $argv[1] - case EXIT - echo --on-process-exit %self + switch $argv[1] + case EXIT + echo --on-process-exit %self - case '*' - echo --on-signal $argv[1] - end + case '*' + echo --on-signal $argv[1] + end end function trap -d 'Perform an action when the shell receives a signal' - set -l mode - set -l cmd - set -l sig + set -l mode + set -l cmd + set -l sig - set -l options - set -l longopt - set -l shortopt lph - if not getopt -T > /dev/null - # GNU getopt - set longopt print,help,list-signals - set options -o $shortopt -l $longopt -- - # Verify options - if not getopt -n type $options $argv >/dev/null - return 1 - end - else - # Old getopt, used on OS X - set options $shortopt - # Verify options - if not getopt $options $argv >/dev/null - return 1 - end - end + set -l options + set -l longopt + set -l shortopt lph + if not getopt -T >/dev/null + # GNU getopt + set longopt print,help,list-signals + set options -o $shortopt -l $longopt -- + # Verify options + if not getopt -n type $options $argv >/dev/null + return 1 + end + else + # Old getopt, used on OS X + set options $shortopt + # Verify options + if not getopt $options $argv >/dev/null + return 1 + end + end - # Do the real getopt invocation - set -l tmp (getopt $options $argv) + # Do the real getopt invocation + set -l tmp (getopt $options $argv) - # Break tmp up into an array - set -l opt - eval set opt $tmp + # Break tmp up into an array + set -l opt + eval set opt $tmp - while count $opt >/dev/null - switch $opt[1] - case -h --help - __fish_print_help trap - return 0 + while count $opt >/dev/null + switch $opt[1] + case -h --help + __fish_print_help trap + return 0 - case -p --print - set mode print + case -p --print + set mode print - case -l --list-signals - set mode list + case -l --list-signals + set mode list - case -- - set -e opt[1] - break + case -- + set -e opt[1] + break - end - set -e opt[1] - end + end + set -e opt[1] + end - if not count $mode >/dev/null + if not count $mode >/dev/null - switch (count $opt) + switch (count $opt) - case 0 - set mode print + case 0 + set mode print - case 1 - set mode clear + case 1 + set mode clear - case '*' - if test opt[1] = - - set -e opt[1] - set mode clear - else - set mode set - end - end - end + case '*' + if test opt[1] = - + set -e opt[1] + set mode clear + else + set mode set + end + end + end - switch $mode - case clear - for i in $opt - set sig (__trap_translate_signal $i) - if test $sig - functions -e __trap_handler_$sig - end - end + switch $mode + case clear + for i in $opt + set sig (__trap_translate_signal $i) + if test $sig + functions -e __trap_handler_$sig + end + end - case set - set -l cmd $opt[1] - set -e opt[1] + case set + set -l cmd $opt[1] + set -e opt[1] - for i in $opt + for i in $opt - set -l sig (__trap_translate_signal $i) - set sw (__trap_switch $sig) + set -l sig (__trap_translate_signal $i) + set sw (__trap_switch $sig) - if test $sig - eval "function __trap_handler_$sig $sw; $cmd; end" - else - return 1 - end - end + if test $sig + eval "function __trap_handler_$sig $sw; $cmd; end" + else + return 1 + end + end - case print - set -l names + case print + set -l names - if count $opt >/dev/null - set names $opt - else - set names (functions -na| string match "__trap_handler_*" | string replace '__trap_handler_' '') - end + if count $opt >/dev/null + set names $opt + else + set names (functions -na| string match "__trap_handler_*" | string replace '__trap_handler_' '') + end - for i in $names + for i in $names - set sig (__trap_translate_signal $i) + set sig (__trap_translate_signal $i) - if test sig - functions __trap_handler_$i - else - return 1 - end + if test sig + functions __trap_handler_$i + else + return 1 + end - end + end - case list - kill -l + case list + kill -l - end + end end diff --git a/share/functions/type.fish b/share/functions/type.fish index ed113ea5d..ab0cd28b1 100644 --- a/share/functions/type.fish +++ b/share/functions/type.fish @@ -1,153 +1,156 @@ function type --description "Print the type of a command" - # Initialize - set -l res 1 - set -l mode normal - set -l multi no - set -l selection all - set -l IFS \n\ \t + # Initialize + set -l res 1 + set -l mode normal + set -l multi no + set -l selection all + set -l IFS \n\ \t - # Parse options - set -l names - if test (count $argv) -gt 0 - for i in (seq (count $argv)) - set -l arg $argv[$i] - set -l needbreak 0 - while test -n $arg - set -l flag $arg - set arg '' - switch $flag - case '--*' - # do nothing; this just prevents it matching the next case - case '-??*' - # combined flags - set -l IFS - echo -n $flag | read __ flag arg - set flag -$flag - set arg -$arg - end - switch $flag - case -t --type - if test $mode != quiet - set mode type - end + # Parse options + set -l names + if test (count $argv) -gt 0 + for i in (seq (count $argv)) + set -l arg $argv[$i] + set -l needbreak 0 + while test -n $arg + set -l flag $arg + set arg '' + switch $flag + case '--*' + # do nothing; this just prevents it matching the next case + case '-??*' + # combined flags + set -l IFS + echo -n $flag | read __ flag arg + set flag -$flag + set arg -$arg + end + switch $flag + case -t --type + if test $mode != quiet + set mode type + end - case -p --path - if test $mode != quiet - set mode path - end + case -p --path + if test $mode != quiet + set mode path + end - case -P --force-path - if test $mode != quiet - set mode path - end - set selection files + case -P --force-path + if test $mode != quiet + set mode path + end + set selection files - case -a --all - set multi yes + case -a --all + set multi yes - case -f --no-functions - set selection files + case -f --no-functions + set selection files - case -q --quiet - set mode quiet + case -q --quiet + set mode quiet - case -h --help - __fish_print_help type - return 0 + case -h --help + __fish_print_help type + return 0 - case -- - set names $argv[$i..-1] - set -e names[1] - set needbreak 1 - break + case -- + set names $argv[$i..-1] + set -e names[1] + set needbreak 1 + break - case '*' - set names $argv[$i..-1] - set needbreak 1 - break - end - end - if test $needbreak -eq 1 - break - end - end - end + case '*' + set names $argv[$i..-1] + set needbreak 1 + break + end + end + if test $needbreak -eq 1 + break + end + end + end - # Check all possible types for the remaining arguments - for i in $names - # Found will be set to 1 if a match is found - set -l found 0 + # Check all possible types for the remaining arguments + for i in $names + # Found will be set to 1 if a match is found + set -l found 0 - if test $selection != files + if test $selection != files - if functions -q -- $i - set res 0 - set found 1 - switch $mode - case normal - printf (_ '%s is a function with definition\n') $i - if isatty stdout - functions $i | fish_indent --ansi - else - functions $i | fish_indent - end - case type - echo (_ 'function') - end - if test $multi != yes - continue - end - end + if functions -q -- $i + set res 0 + set found 1 + switch $mode + case normal + printf (_ '%s is a function with definition\n') $i + if isatty stdout + functions $i | fish_indent --ansi + else + functions $i | fish_indent + end + case type + echo (_ 'function') + end + if test $multi != yes + continue + end + end - if contains -- $i (builtin -n) + if contains -- $i (builtin -n) - set res 0 - set found 1 - switch $mode - case normal - printf (_ '%s is a builtin\n') $i + set res 0 + set found 1 + switch $mode + case normal + printf (_ '%s is a builtin\n') $i - case type - echo (_ 'builtin') - end - if test $multi != yes - continue - end - end + case type + echo (_ 'builtin') + end + if test $multi != yes + continue + end + end - end + end - set -l paths - if test $multi != yes - set paths (command -s -- $i) - else - set paths (command which -a -- $i ^/dev/null) - end - for path in $paths - set res 0 - set found 1 - switch $mode - case normal - printf (_ '%s is %s\n') $i $path + set -l paths + if test $multi != yes + set paths (command -s -- $i) + else + set paths (command which -a -- $i ^/dev/null) + end + for path in $paths + set res 0 + set found 1 + switch $mode + case normal + printf (_ '%s is %s\n') $i $path - case type - echo (_ 'file') + case type + echo (_ 'file') - case path - echo $path - end - if test $multi != yes - continue - end - end + case path + echo $path + end + if test $multi != yes + continue + end + end - if begin; test $found = 0; and test $mode != quiet; end - printf (_ "%s: Could not find '%s'\n") type $i >&2 - end + if begin + test $found = 0 + and test $mode != quiet + end + printf (_ "%s: Could not find '%s'\n") type $i >&2 + end - end + end - return $res + return $res end diff --git a/share/functions/umask.fish b/share/functions/umask.fish index a03c39b7e..4ad547818 100644 --- a/share/functions/umask.fish +++ b/share/functions/umask.fish @@ -1,216 +1,218 @@ function __fish_umask_parse -d "Internal umask function" - # Test if already a valid octal mask, and pad it with zeros - if echo $argv | __fish_sgrep -E '^0?[0-7]{1,3}$' >/dev/null - set -l char_count (echo $argv| wc -c) - for i in (seq (math 5 - $char_count)); set argv 0$argv; end - echo $argv - else - # Test if argument really is a valid symbolic mask - if not echo $argv | __fish_sgrep -E '^(((u|g|o|a|)(=|\+|-)|)(r|w|x)*)(,(((u|g|o|a|)(=|\+|-)|)(r|w|x)*))*$' >/dev/null - printf (_ "%s: Invalid mask '%s'\n") umask $argv >&2 - return 1 - end + # Test if already a valid octal mask, and pad it with zeros + if echo $argv | __fish_sgrep -E '^0?[0-7]{1,3}$' >/dev/null + set -l char_count (echo $argv| wc -c) + for i in (seq (math 5 - $char_count)) + set argv 0$argv + end + echo $argv + else + # Test if argument really is a valid symbolic mask + if not echo $argv | __fish_sgrep -E '^(((u|g|o|a|)(=|\+|-)|)(r|w|x)*)(,(((u|g|o|a|)(=|\+|-)|)(r|w|x)*))*$' >/dev/null + printf (_ "%s: Invalid mask '%s'\n") umask $argv >&2 + return 1 + end - set -l implicit_all + set -l implicit_all - # Insert inverted umask into res variable + # Insert inverted umask into res variable - set -l mode - set -l val - set -l tmp $umask - set -l res + set -l mode + set -l val + set -l tmp $umask + set -l res - for i in 1 2 3 - set tmp (echo $tmp|cut -c 2-) - set -l char_count (echo $tmp|cut -c 1) - set res[$i] (math 7 - $char_count) - end + for i in 1 2 3 + set tmp (echo $tmp|cut -c 2-) + set -l char_count (echo $tmp|cut -c 1) + set res[$i] (math 7 - $char_count) + end - set -l el (echo $argv|tr , \n) - for i in $el - switch $i - case 'u*' - set idx 1 - set i (echo $i| cut -c 2-) + set -l el (echo $argv|tr , \n) + for i in $el + switch $i + case 'u*' + set idx 1 + set i (echo $i| cut -c 2-) - case 'g*' - set idx 2 - set i (echo $i| cut -c 2-) + case 'g*' + set idx 2 + set i (echo $i| cut -c 2-) - case 'o*' - set idx 3 - set i (echo $i| cut -c 2-) + case 'o*' + set idx 3 + set i (echo $i| cut -c 2-) - case 'a*' - set idx 1 2 3 - set i (echo $i| cut -c 2-) + case 'a*' + set idx 1 2 3 + set i (echo $i| cut -c 2-) - case '*' - set implicit_all 1 - set idx 1 2 3 - end + case '*' + set implicit_all 1 + set idx 1 2 3 + end - switch $i - case '=*' - set mode set - set i (echo $i| cut -c 2-) + switch $i + case '=*' + set mode set + set i (echo $i| cut -c 2-) - case '+*' - set mode add - set i (echo $i| cut -c 2-) + case '+*' + set mode add + set i (echo $i| cut -c 2-) - case '-*' - set mode remove - set i (echo $i| cut -c 2-) + case '-*' + set mode remove + set i (echo $i| cut -c 2-) - case '*' - if not count $implicit_all >/dev/null - printf (_ "%s: Invalid mask '%s'\n") umask $argv >&2 - return - end - set mode set - end + case '*' + if not count $implicit_all >/dev/null + printf (_ "%s: Invalid mask '%s'\n") umask $argv >&2 + return + end + set mode set + end - if not echo $perm| __fish_sgrep -E '^(r|w|x)*$' >/dev/null - printf (_ "%s: Invalid mask '%s'\n") umask $argv >&2 - return - end + if not echo $perm | __fish_sgrep -E '^(r|w|x)*$' >/dev/null + printf (_ "%s: Invalid mask '%s'\n") umask $argv >&2 + return + end - set val 0 - if echo $i | __fish_sgrep 'r' >/dev/null - set val 4 - end - if echo $i | __fish_sgrep 'w' >/dev/null - set val (math $val + 2) - end - if echo $i | __fish_sgrep 'x' >/dev/null - set val (math $val + 1) - end + set val 0 + if echo $i | __fish_sgrep 'r' >/dev/null + set val 4 + end + if echo $i | __fish_sgrep 'w' >/dev/null + set val (math $val + 2) + end + if echo $i | __fish_sgrep 'x' >/dev/null + set val (math $val + 1) + end - for j in $idx - switch $mode - case set - set res[$j] $val + for j in $idx + switch $mode + case set + set res[$j] $val - case add - set res[$j] (perl -e 'print( ( '$res[$j]'|'$val[$j]' )."\n" )') + case add + set res[$j] (perl -e 'print( ( '$res[$j]'|'$val[$j]' )."\n" )') - case remove - set res[$j] (perl -e 'print( ( (7-'$res[$j]')&'$val[$j]' )."\n" )') - end - end - end + case remove + set res[$j] (perl -e 'print( ( (7-'$res[$j]')&'$val[$j]' )."\n" )') + end + end + end - for i in 1 2 3 - set res[$i] (math 7 - $res[$i]) - end - echo 0$res[1]$res[2]$res[3] - end + for i in 1 2 3 + set res[$i] (math 7 - $res[$i]) + end + echo 0$res[1]$res[2]$res[3] + end end function __fish_umask_print_symbolic - set -l res "" - set -l letter a u g o + set -l res "" + set -l letter a u g o - for i in 2 3 4 - set res $res,$letter[$i]= - set val (echo $umask|cut -c $i) + for i in 2 3 4 + set res $res,$letter[$i]= + set val (echo $umask|cut -c $i) - if contains $val 0 1 2 3 - set res {$res}r - end + if contains $val 0 1 2 3 + set res {$res}r + end - if contains $val 0 1 4 5 - set res {$res}w - end + if contains $val 0 1 4 5 + set res {$res}w + end - if contains $val 0 2 4 6 - set res {$res}x - end + if contains $val 0 2 4 6 + set res {$res}x + end - end + end - echo $res|cut -c 2- + echo $res | cut -c 2- end function umask --description "Set default file permission mask" - set -l as_command 0 - set -l symbolic 0 - - set -l options - set -l shortopt pSh - if not getopt -T >/dev/null - # GNU getopt - set longopt -l as-command,symbolic,help - set options -o $shortopt $longopt -- - # Verify options - if not getopt -n umask $options $argv >/dev/null - return 1 - end - else - # Old getopt, used on OS X - set options $shortopt - # Verify options - if not getopt $options $argv >/dev/null - return 1 - end - end + set -l as_command 0 + set -l symbolic 0 - set -l tmp (getopt $options $argv) - eval set opt $tmp + set -l options + set -l shortopt pSh + if not getopt -T >/dev/null + # GNU getopt + set longopt -l as-command,symbolic,help + set options -o $shortopt $longopt -- + # Verify options + if not getopt -n umask $options $argv >/dev/null + return 1 + end + else + # Old getopt, used on OS X + set options $shortopt + # Verify options + if not getopt $options $argv >/dev/null + return 1 + end + end - while count $opt >/dev/null + set -l tmp (getopt $options $argv) + eval set opt $tmp - switch $opt[1] - case -h --help - __fish_print_help umask - return 0 + while count $opt >/dev/null - case -p --as-command - set as_command 1 + switch $opt[1] + case -h --help + __fish_print_help umask + return 0 - case -S --symbolic - set symbolic 1 + case -p --as-command + set as_command 1 - case -- - set -e opt[1] - break + case -S --symbolic + set symbolic 1 - end + case -- + set -e opt[1] + break - set -e opt[1] + end - end + set -e opt[1] - switch (count $opt) + end - case 0 - if not set -q umask - set -g umask 113 - end - if test $as_command -eq 1 - echo umask $umask - else - if test $symbolic -eq 1 - __fish_umask_print_symbolic $umask - else - echo $umask - end - end + switch (count $opt) - case 1 - set -l parsed (__fish_umask_parse $opt) - if test (count $parsed) -eq 1 - set -g umask $parsed - return 0 - end - return 1 + case 0 + if not set -q umask + set -g umask 113 + end + if test $as_command -eq 1 + echo umask $umask + else + if test $symbolic -eq 1 + __fish_umask_print_symbolic $umask + else + echo $umask + end + end - case '*' - printf (_ '%s: Too many arguments\n') umask >&2 + case 1 + set -l parsed (__fish_umask_parse $opt) + if test (count $parsed) -eq 1 + set -g umask $parsed + return 0 + end + return 1 - end + case '*' + printf (_ '%s: Too many arguments\n') umask >&2 + + end end diff --git a/share/functions/up-or-search.fish b/share/functions/up-or-search.fish index 98179ad7c..e0e64f6dd 100644 --- a/share/functions/up-or-search.fish +++ b/share/functions/up-or-search.fish @@ -1,26 +1,26 @@ function up-or-search -d "Depending on cursor position and current mode, either search backward or move up one line" - # If we are already in search mode, continue - if commandline --search-mode - commandline -f history-search-backward - return - end + # If we are already in search mode, continue + if commandline --search-mode + commandline -f history-search-backward + return + end - # If we are navigating the pager, then up always navigates - if commandline --paging-mode - commandline -f up-line - return - end + # If we are navigating the pager, then up always navigates + if commandline --paging-mode + commandline -f up-line + return + end - # We are not already in search mode. - # If we are on the top line, start search mode, - # otherwise move up - set lineno (commandline -L) + # We are not already in search mode. + # If we are on the top line, start search mode, + # otherwise move up + set lineno (commandline -L) - switch $lineno - case 1 - commandline -f history-search-backward + switch $lineno + case 1 + commandline -f history-search-backward - case '*' - commandline -f up-line - end + case '*' + commandline -f up-line + end end diff --git a/share/functions/vared.fish b/share/functions/vared.fish index 97c233348..f14794df7 100644 --- a/share/functions/vared.fish +++ b/share/functions/vared.fish @@ -4,43 +4,43 @@ # function vared --description "Edit variable value" - if test (count $argv) = 1 - switch $argv + if test (count $argv) = 1 + switch $argv - case '-h' '--h' '--he' '--hel' '--help' - __fish_print_help vared - return 0 + case '-h' '--h' '--he' '--hel' '--help' + __fish_print_help vared + return 0 - case '-*' - printf (_ "%s: Unknown option %s\n") vared $argv - return 1 + case '-*' + printf (_ "%s: Unknown option %s\n") vared $argv + return 1 - case '*' - if test (count $$argv ) -lt 2 - set -l init '' - if test $$argv - set init $$argv - end - set -l prompt 'set_color green; echo '$argv'; set_color normal; echo "> "' - if read -p $prompt -c $init tmp + case '*' + if test (count $$argv ) -lt 2 + set -l init '' + if test $$argv + set init $$argv + end + set -l prompt 'set_color green; echo '$argv'; set_color normal; echo "> "' + if read -p $prompt -c $init tmp - # If variable already exists, do not add any - # switches, so we don't change export rules. But - # if it does not exist, we make the variable - # global, so that it will not die when this - # function dies + # If variable already exists, do not add any + # switches, so we don't change export rules. But + # if it does not exist, we make the variable + # global, so that it will not die when this + # function dies - if test $$argv - set $argv $tmp - else - set -g $argv $tmp - end - end - else - printf (_ '%s: %s is an array variable. Use %svared%s %s[n]%s to edit the n:th element of %s\n') vared $argv (set_color $fish_color_command; echo) (set_color $fish_color_normal; echo) $argv (set_color reset; echo) $argv - end - end - else - printf (_ '%s: Expected exactly one argument, got %s.\n\nSynopsis:\n\t%svared%s VARIABLE\n') vared (count $argv) (set_color $fish_color_command; echo) (set_color $fish_color_normal; echo) - end + if test $$argv + set $argv $tmp + else + set -g $argv $tmp + end + end + else + printf (_ '%s: %s is an array variable. Use %svared%s %s[n]%s to edit the n:th element of %s\n') vared $argv (set_color $fish_color_command; echo) (set_color $fish_color_normal; echo) $argv (set_color normal; echo) $argv + end + end + else + printf (_ '%s: Expected exactly one argument, got %s.\n\nSynopsis:\n\t%svared%s VARIABLE\n') vared (count $argv) (set_color $fish_color_command; echo) (set_color $fish_color_normal; echo) + end end diff --git a/share/tools/create_manpage_completions.py b/share/tools/create_manpage_completions.py index a65c057bb..e79744568 100755 --- a/share/tools/create_manpage_completions.py +++ b/share/tools/create_manpage_completions.py @@ -857,12 +857,26 @@ def parse_and_output_man_pages(paths, output_directory, show_progress): def get_paths_from_manpath(): # Return all the paths to man(1) and man(8) files in the manpath import subprocess, os - proc = subprocess.Popen(['manpath'], stdout=subprocess.PIPE) - manpath, err_data = proc.communicate() + # $MANPATH takes precedence, just like with `man` on the CLI. + if os.getenv("MANPATH"): + manpath = os.getenv("MANPATH") + else: + # Some systems have manpath, others have `man --path` (like Haiku). + # TODO: Deal with systems that have neither (OpenBSD) + for prog in [['manpath'], ['man', '--path']]: + try: + proc = subprocess.Popen(prog, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + except OSError: # Command does not exist, keep trying + continue + break # Command exists, use it. + manpath, err_data = proc.communicate() parent_paths = manpath.decode().strip().split(':') - if not parent_paths: - sys.stderr.write("Unable to get the manpath (tried manpath)\n") - sys.exit(-1) + if not parent_paths or proc.returncode > 0: + # HACK: Use some fallback in case we can't get anything else. + # `mandoc` does not provide `manpath` or `man --path` and $MANPATH might not be set, so just use the default for mandoc (minus /usr/X11R6/man, because that's not relevant). + # The alternative is reading its config file (/etc/man.conf) + sys.stderr.write("Unable to get the manpath, falling back to /usr/share/man:/usr/local/share/man. Please set $MANPATH if that is not correct.\n") + parent_paths = ["/usr/share/man", "/usr/local/share/man"] result = [] for parent_path in parent_paths: for section in ['man1', 'man6', 'man8']: diff --git a/share/tools/web_config/fishconfig.css b/share/tools/web_config/fishconfig.css index 9d6ef5eb5..1c9043732 100644 --- a/share/tools/web_config/fishconfig.css +++ b/share/tools/web_config/fishconfig.css @@ -117,7 +117,7 @@ body { padding-top: 6px; padding-bottom: 11px; padding-left: 5px; - padding-right: 22px; + padding-right: 22px; font-size: 12pt; /* Make our border overlap the detail, even if we're unselected (so it doesn't jump when selected) */ position: relative; @@ -130,10 +130,10 @@ body { border: 1px solid #555; border-right: none; background-color: #181818; - + border-top-left-radius: 5; border-bottom-left-radius: 5; - + /* Pad one less than .master_element, to accomodate our border. */ padding-top: 5px; padding-bottom: 10px; @@ -231,7 +231,7 @@ body { vertical-align: top; overflow:hidden; border-bottom: #444 dotted 1px; - word-wrap: break-word; + word-wrap: break-word; } .history_delete { diff --git a/share/tools/web_config/js/angular.js b/share/tools/web_config/js/angular.js index 719bc648e..1d6b16487 100644 --- a/share/tools/web_config/js/angular.js +++ b/share/tools/web_config/js/angular.js @@ -203,7 +203,7 @@ function nextUid() { /** * Set or clear the hashkey for an object. - * @param obj object + * @param obj object * @param h the hashkey (!truthy to delete the hashkey) */ function setHashKey(obj, h) { @@ -2154,21 +2154,21 @@ forEach({ } } return false; - }; + }; events[type] = []; - + // Refer to jQuery's implementation of mouseenter & mouseleave // Read about mouseenter and mouseleave: // http://www.quirksmode.org/js/events_mouse.html#link8 - var eventmap = { mouseleave : "mouseout", mouseenter : "mouseover"} + var eventmap = { mouseleave : "mouseout", mouseenter : "mouseover"} bindFn(element, eventmap[type], function(event) { var ret, target = this, related = event.relatedTarget; // For mousenter/leave call the handler if related is outside the target. // NB: No relatedTarget if the mouse left/entered the browser window if ( !related || (related !== target && !contains(target, related)) ){ handle(event, type); - } + } }); @@ -3472,18 +3472,18 @@ function $BrowserProvider(){ * * @description * Factory that constructs cache objects and gives access to them. - * + * *
- * 
+ *
  *  var cache = $cacheFactory('cacheId');
  *  expect($cacheFactory.get('cacheId')).toBe(cache);
  *  expect($cacheFactory.get('noSuchCacheId')).not.toBeDefined();
  *
  *  cache.put("key", "value");
  *  cache.put("another key", "another value");
- * 
+ *
  *  expect(cache.info()).toEqual({id: 'cacheId', size: 2}); // Since we've specified no options on creation
- * 
+ *
  * 
* * @@ -3660,10 +3660,10 @@ function $CacheFactoryProvider() { * @name ng.$templateCache * * @description - * The first time a template is used, it is loaded in the template cache for quick retrieval. You can - * load templates directly into the cache in a `script` tag, or by consuming the `$templateCache` + * The first time a template is used, it is loaded in the template cache for quick retrieval. You can + * load templates directly into the cache in a `script` tag, or by consuming the `$templateCache` * service directly. - * + * * Adding via the `script` tag: *
  * 
@@ -3675,29 +3675,29 @@ function $CacheFactoryProvider() {
  *   ...
  * 
  * 
- * - * **Note:** the `script` tag containing the template does not need to be included in the `head` of the document, but + * + * **Note:** the `script` tag containing the template does not need to be included in the `head` of the document, but * it must be below the `ng-app` definition. - * + * * Adding via the $templateCache service: - * + * *
  * var myApp = angular.module('myApp', []);
  * myApp.run(function($templateCache) {
  *   $templateCache.put('templateId.html', 'This is the content of the template');
  * });
  * 
- * + * * To retrieve the template later, simply use it in your HTML: *
  * 
*
- * + * * or get it via Javascript: *
  * $templateCache.get('templateId.html')
  * 
- * + * * See {@link ng.$cacheFactory $cacheFactory}. * */ @@ -6902,25 +6902,25 @@ function $ParseProvider() { * you can treat promises attached to a scope as if they were the resulting values. * - Q has many more features than $q, but that comes at a cost of bytes. $q is tiny, but contains * all the important functionality needed for common async tasks. - * + * * # Testing - * + * *
  *    it('should simulate promise', inject(function($q, $rootScope) {
  *      var deferred = $q.defer();
  *      var promise = deferred.promise;
  *      var resolvedValue;
- * 
+ *
  *      promise.then(function(value) { resolvedValue = value; });
  *      expect(resolvedValue).toBeUndefined();
- * 
+ *
  *      // Simulate resolving of promise
  *      deferred.resolve(123);
  *      // Note that the 'then' function does not get called synchronously.
  *      // This is because we want the promise API to always be async, whether or not
  *      // it got called synchronously or asynchronously.
  *      expect(resolvedValue).toBeUndefined();
- * 
+ *
  *      // Propagate promise resolution to 'then' functions using $apply().
  *      $rootScope.$apply();
  *      expect(resolvedValue).toEqual(123);
@@ -8140,7 +8140,7 @@ function $RootScopeProvider(){
        *
        * @description
        * Broadcasted when a scope and its children are being destroyed.
-       * 
+       *
        * Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to
        * clean up DOM bindings before an element is removed from the DOM.
        */
@@ -8164,7 +8164,7 @@ function $RootScopeProvider(){
        * Just before a scope is destroyed a `$destroy` event is broadcasted on this scope.
        * Application code can register a `$destroy` event handler that will give it chance to
        * perform any necessary cleanup.
-       * 
+       *
        * Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to
        * clean up DOM bindings before an element is removed from the DOM.
        */
@@ -12677,8 +12677,8 @@ var ngValueDirective = function() {
  * Typically, you don't use `ngBind` directly, but instead you use the double curly markup like
  * `{{ expression }}` which is similar but less verbose.
  *
- * It is preferrable to use `ngBind` instead of `{{ expression }}` when a template is momentarily 
- * displayed by the browser in its raw state before Angular compiles it. Since `ngBind` is an 
+ * It is preferrable to use `ngBind` instead of `{{ expression }}` when a template is momentarily
+ * displayed by the browser in its raw state before Angular compiles it. Since `ngBind` is an
  * element attribute, it makes the bindings invisible to the user while the page is loading.
  *
  * An alternative solution to this problem would be using the
@@ -13174,20 +13174,20 @@ var ngControllerDirective = [function() {
  * @element html
  * @description
  * Enables [CSP (Content Security Policy)](https://developer.mozilla.org/en/Security/CSP) support.
- * 
+ *
  * This is necessary when developing things like Google Chrome Extensions.
- * 
+ *
  * CSP forbids apps to use `eval` or `Function(string)` generated functions (among other things).
  * For us to be compatible, we just need to implement the "getterFn" in $parse without violating
  * any of these restrictions.
- * 
+ *
  * AngularJS uses `Function(string)` generated functions as a speed optimization. By applying `ngCsp`
  * it is be possible to opt into the CSP compatible mode. When this mode is on AngularJS will
  * evaluate all expressions up to 30% slower than in non-CSP mode, but no security violations will
  * be raised.
- * 
+ *
  * In order to use this feature put `ngCsp` directive on the root element of the application.
- * 
+ *
  * @example
  * This example shows how to apply the `ngCsp` directive to the `html` tag.
    
diff --git a/share/tools/web_config/js/app.js b/share/tools/web_config/js/app.js
index 6c5733898..0a31e89c2 100644
--- a/share/tools/web_config/js/app.js
+++ b/share/tools/web_config/js/app.js
@@ -41,9 +41,9 @@ fishconfig.config(function($httpProvider, $compileProvider) {
     var global_error_element = null;
 
     var showMessage = function(content) {
-        global_error_element.text(content); 
+        global_error_element.text(content);
     };
-    
+
     $httpProvider.responseInterceptors.push(function($q) {
         return function(promise) {
             return promise.then(function(successResponse) {
diff --git a/share/tools/web_config/js/colorutils.js b/share/tools/web_config/js/colorutils.js
index 9222b3990..3b9fdebf0 100644
--- a/share/tools/web_config/js/colorutils.js
+++ b/share/tools/web_config/js/colorutils.js
@@ -74,7 +74,7 @@ function adjust_lightness(color_str, func) {
     if (color_str[0] == '#') {
         color_str = color_str.substring(1);
     }
-	
+
     /* Hack to handle for example F00 */
     if (color_str.length == 3) {
         color_str = color_str[0] + color_str[0] + color_str[1] + color_str[1] + color_str[2] + color_str[2]
@@ -128,7 +128,7 @@ function text_color_for_color(color_str) {
     return adjust_lightness(color_str, compute_constrast);
 }
 
-function rgb_to_hsl(r, g, b) {	
+function rgb_to_hsl(r, g, b) {
     r /= 255, g /= 255, b /= 255;
     var max = Math.max(r, g, b), min = Math.min(r, g, b);
     var h, s, l = (max + min) / 2;
@@ -243,12 +243,12 @@ var color_scheme_fish_default = {
 var TomorrowTheme = {
     tomorrow_night: {'Background': '1d1f21', 'Current Line': '282a2e', 'Selection': '373b41', 'Foreground': 'c5c8c6', 'Comment': '969896', 'Red': 'cc6666', 'Orange': 'de935f',  'Yellow': 'f0c674', 'Green': 'b5bd68', 'Aqua': '8abeb7', 'Blue': '81a2be', 'Purple': 'b294bb'
     },
-    
+
     tomorrow: {'Background': 'ffffff', 'Current Line': 'efefef', 'Selection': 'd6d6d6', 'Foreground': '4d4d4c', 'Comment': '8e908c', 'Red': 'c82829', 'Orange': 'f5871f', 'Yellow': 'eab700', 'Green': '718c00', 'Aqua': '3e999f', 'Blue': '4271ae', 'Purple': '8959a8'
     },
-    
+
     tomorrow_night_bright: {'Background': '000000', 'Current Line': '2a2a2a', 'Selection': '424242', 'Foreground': 'eaeaea', 'Comment': '969896', 'Red': 'd54e53', 'Orange': 'e78c45', 'Yellow': 'e7c547', 'Green': 'b9ca4a', 'Aqua': '70c0b1', 'Blue': '7aa6da', 'Purple': 'c397d8'},
-    
+
     apply: function(theme, receiver){
         receiver['autosuggestion'] = theme['Comment']
         receiver['command'] = theme['Purple']
@@ -258,7 +258,7 @@ var TomorrowTheme = {
         receiver['param'] = theme['Blue']
         receiver['quote'] = theme['Green']
         receiver['redirection'] = theme['Aqua']
-        
+
         receiver['colors'] = []
         for (var key in theme) receiver['colors'].push(theme[key])
     }
@@ -273,9 +273,9 @@ var solarized = {
 var color_scheme_solarized_light = {
     name: "Solarized Light",
     colors: dict_values(solarized),
-    
+
     preferred_background: '#' + solarized.base3,
-    
+
     autosuggestion: solarized.base1,
     command: solarized.base01,
     comment: solarized.base1,
@@ -284,7 +284,7 @@ var color_scheme_solarized_light = {
     param: solarized.base00,
     quote: solarized.base0,
     redirection: solarized.violet,
-    
+
     url: 'http://ethanschoonover.com/solarized'
 };
 
@@ -292,7 +292,7 @@ var color_scheme_solarized_dark = {
     name: "Solarized Dark",
     colors: dict_values(solarized),
     preferred_background: '#' + solarized.base03,
-    
+
     autosuggestion: solarized.base01,
     command: solarized.base1,
     comment: solarized.base01,
@@ -301,7 +301,7 @@ var color_scheme_solarized_dark = {
     param: solarized.base0,
     quote: solarized.base00,
     redirection: solarized.violet,
-    
+
     url: 'http://ethanschoonover.com/solarized'
 };
 
@@ -332,15 +332,15 @@ function construct_scheme_analogous(label, background, color_list) {
         name: label,
         preferred_background: background,
         colors: color_list,
-        
+
         command: color_list[0],
         quote: color_list[6],
         param: color_list[5],
         autosuggestion: color_list[4],
-        
+
         error: color_list[9],
         comment: color_list[12],
-        
+
         end: color_list[10],
         redirection: color_list[11]
     };
@@ -351,16 +351,16 @@ function construct_scheme_triad(label, background, color_list) {
         name: label,
         preferred_background: background,
         colors: color_list,
-        
+
         command: color_list[0],
         quote: color_list[2],
         param: color_list[1],
         autosuggestion: color_list[3],
         redirection: color_list[4],
-        
+
         error: color_list[8],
         comment: color_list[10],
-        
+
         end: color_list[7],
     };
 }
@@ -370,30 +370,30 @@ function construct_scheme_complementary(label, background, color_list) {
         name: label,
         preferred_background: background,
         colors: color_list,
-        
+
         command: color_list[0],
         quote: color_list[4],
         param: color_list[3],
         autosuggestion: color_list[2],
         redirection: color_list[6],
-        
+
         error: color_list[5],
         comment: color_list[8],
-        
+
         end: color_list[9],
     };
 }
 
 function construct_color_scheme_mono(label, background, from_end) {
     var mono_colors = ['000000', '121212', '1c1c1c', '262626', '303030', '3a3a3a', '444444', '4e4e4e', '585858', '5f5f5f', '626262', '6c6c6c', '767676', '808080', '878787', '8a8a8a', '949494', '9e9e9e', 'a8a8a8', 'afafaf', 'b2b2b2', 'bcbcbc', 'c6c6c6', 'd0d0d0', 'd7d7d7', 'dadada', 'e4e4e4', 'eeeeee', 'ffffff'];
-    
+
     if (from_end) mono_colors.reverse();
-    
+
     return {
         name: label,
         preferred_background: background,
         colors: mono_colors,
-        
+
         autosuggestion: '777777',
         command: mono_colors[0],
         comment: mono_colors[7],
@@ -407,21 +407,21 @@ function construct_color_scheme_mono(label, background, from_end) {
 
 var additional_color_schemes = [
     construct_scheme_analogous('Snow Day', 'white', ['164CC9', '325197', '072D83', '4C7AE4', '7596E4', '4319CC', '4C3499', '260885', '724EE5', '9177E5', '02BDBD', '248E8E', '007B7B', '39DEDE', '65DEDE']),
-    
+
     construct_scheme_analogous('Lava', '#232323', ['FF9400', 'BF8330', 'A66000', 'FFAE40', 'FFC473', 'FFC000', 'BF9C30', 'A67D00', 'FFD040', 'FFDD73', 'FF4C00', 'BF5B30', 'A63100', 'FF7940', 'FF9D73']),
-    
+
     construct_scheme_analogous('Seaweed', '#232323', ['00BF32', '248F40', '007C21', '38DF64', '64DF85', '04819E', '206676', '015367', '38B2CE', '60B9CE', '8EEB00', '7CB02C', '5C9900', 'ACF53D', 'C0F56E']),
-    
+
     construct_scheme_triad('Fairground', '#003', ['0772A1', '225E79', '024A68', '3BA3D0', '63AFD0', 'D9005B', 'A3295C', '8D003B', 'EC3B86', 'EC6AA1', 'FFE100', 'BFAE30', 'A69200', 'FFE840', 'FFEE73']),
-    
+
     construct_scheme_complementary('Bay Cruise', 'black', ['009999', '1D7373', '006363', '33CCCC', '5CCCCC', 'FF7400', 'BF7130', 'A64B00', 'FF9640', 'FFB273']),
 
 {
     'name': 'Old School',
     'preferred_background': 'black',
-    
+
     colors: ['00FF00', '30BE30', '00A400', '44FF44', '7BFF7B', 'FF0000', 'BE3030', 'A40000', 'FF7B7B', '777777', 'CCCCCC'],
-    
+
     autosuggestion: '777777',
     command: '00FF00',
     comment: '30BE30',
@@ -435,9 +435,9 @@ var additional_color_schemes = [
 {
     'name': 'Just a Touch',
     'preferred_background': 'black',
-    
+
     colors: ['B0B0B0', '969696', '789276', 'F4F4F4', 'A0A0F0', '666A80', 'F0F0F0', 'D7D7D7', 'B7B7B7', 'FFA779', 'FAFAFA'],
-    
+
     autosuggestion: '9C9C9C',
     command: 'F4F4F4',
     comment: 'B0B0B0',
@@ -448,6 +448,22 @@ var additional_color_schemes = [
     redirection: 'FAFAFA'
 },
 
+{
+    'name': 'Dracula',
+    'preferred_background': '#282a36',
+
+    colors: ['282A36', '44475A', '44475A', 'F8F8F2', '6272A4', '8BE9FD', '50FA7B', 'FFB86C', 'FF79C6', 'BD93F9', 'FF5555', 'F1FA8C'],
+
+    autosuggestion: 'BD93F9',
+    command: 'F8F8F2',
+    comment: '6272A4',
+    end: '50FA7B',
+    error: 'FFB86C',
+    param: 'FF79C6',
+    quote: 'F1FA8C',
+    redirection: '8BE9FD'
+},
+
 construct_color_scheme_mono('Mono Lace', 'white', false),
 construct_color_scheme_mono('Mono Smoke', 'black', true)
 ];
diff --git a/share/tools/web_config/js/controllers.js b/share/tools/web_config/js/controllers.js
index 73985b7a5..76d3aaab4 100644
--- a/share/tools/web_config/js/controllers.js
+++ b/share/tools/web_config/js/controllers.js
@@ -22,7 +22,7 @@ controllers.controller("colorsController", function($scope, $http) {
         $scope.colorArraysArray = $scope.getColorArraysArray();
         //TODO: Save button should be shown only when colors are changed
         $scope.showSaveButton = true;
-        
+
         $scope.noteThemeChanged();
     }
 
@@ -31,7 +31,7 @@ controllers.controller("colorsController", function($scope, $http) {
     }
 
     $scope.text_color_for_color = text_color_for_color;
-    
+
     $scope.border_color_for_color = border_color_for_color;
 
     $scope.getColorArraysArray = function() {
@@ -42,7 +42,7 @@ controllers.controller("colorsController", function($scope, $http) {
             result =  get_colors_as_nested_array(term_256_colors, 32);
         return result;
     }
-    
+
     $scope.beginCustomizationWithSetting = function(setting) {
     	if (! $scope.customizationActive) {
 	    	$scope.customizationActive = true;
@@ -51,14 +51,14 @@ controllers.controller("colorsController", function($scope, $http) {
 			$scope.csUserVisibleTitle = user_visible_title_for_setting_name(setting);
     	}
     }
-        
+
     $scope.selectColorSetting = function(name) {
     	$scope.selectedColorSetting = name;
     	$scope.csEditingType = $scope.customizationActive ? name : '';
     	$scope.csUserVisibleTitle = user_visible_title_for_setting_name(name);
     	$scope.beginCustomizationWithSetting(name);
     }
-    
+
     $scope.toggleCustomizationActive = function() {
 	    if (! $scope.customizationActive) {
 	    	$scope.beginCustomizationWithSetting($scope.selectedColorSetting || 'command');
@@ -93,7 +93,7 @@ controllers.controller("colorsController", function($scope, $http) {
      })};
 
 	$scope.saveThemeButtonTitle = "Set Theme";
-	
+
 	$scope.noteThemeChanged = function() {
 		$scope.saveThemeButtonTitle = "Set Theme";
 	}
@@ -135,7 +135,7 @@ controllers.controller("promptController", function($scope, $http) {
 
     $scope.selectPrompt = function(prompt) {
         $scope.selectedPrompt= prompt;
-        
+
         $scope.savePromptButtonTitle = "Set Prompt";
     }
 
@@ -163,7 +163,7 @@ controllers.controller("promptController", function($scope, $http) {
 
 controllers.controller("functionsController", function($scope, $http) {
     $scope.selectedFunction = null;
-    $scope.functionDefinition = ""; 
+    $scope.functionDefinition = "";
 
     $scope.selectFunction = function(fun) {
         $scope.selectedFunction = fun;
diff --git a/share/tools/web_config/sample_prompts/acidhub.fish b/share/tools/web_config/sample_prompts/acidhub.fish
index 08fd47fe7..24d675396 100644
--- a/share/tools/web_config/sample_prompts/acidhub.fish
+++ b/share/tools/web_config/sample_prompts/acidhub.fish
@@ -12,7 +12,7 @@ function fish_prompt -d "Write out the prompt"
     if [ (_git_branch_name) ]
         set -l git_branch (set_color -o blue)(_git_branch_name)
         if [ (_is_git_dirty) ]
-            for i in (git branch -qv --no-color | string match -r \* | cut -d' ' -f4- | cut -d] -f1 | tr , \n)\
+            for i in (git branch -qv --no-color | string match -r '\*' | cut -d' ' -f4- | cut -d] -f1 | tr , \n)\
  (git status --porcelain | cut -c 1-2 | uniq)
                 switch $i
                     case "*[ahead *"
diff --git a/share/tools/web_config/webconfig.py b/share/tools/web_config/webconfig.py
index eb5dc5c51..fcf79e0af 100755
--- a/share/tools/web_config/webconfig.py
+++ b/share/tools/web_config/webconfig.py
@@ -1,50 +1,49 @@
 #!/usr/bin/env python
 
 from __future__ import unicode_literals
-# Whether we're Python 2
-import sys
+from __future__ import print_function
+import binascii
+import cgi
+import glob
 import multiprocessing.pool
-import os
 import operator
+import os
+import random
+import re
+import select
 import socket
+import string
+import subprocess
+import sys
+import webbrowser
+
+FISH_BIN_PATH = False  # will be set later
 IS_PY2 = sys.version_info[0] == 2
 
 if IS_PY2:
     import SimpleHTTPServer
     import SocketServer
     from urlparse import parse_qs
-
 else:
     import http.server as SimpleHTTPServer
     import socketserver as SocketServer
     from urllib.parse import parse_qs
 
-# Check to see if IPv6 is enabled in the kernel
-HAS_IPV6 = True
-try:
-    s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
-    s.close()
-except:
-    HAS_IPV6 = False
-
 # Disable CLI web browsers
 term = os.environ.pop('TERM', None)
-import webbrowser
 if term:
     os.environ['TERM'] = term
 
-import subprocess
-import re, socket, cgi, select, time, glob, random, string, binascii
 try:
     import json
 except ImportError:
     import simplejson as json
 
-FISH_BIN_PATH = False # will be set later
+
 def run_fish_cmd(text):
-    from subprocess import PIPE
-    # ensure that fish is using UTF-8
-    ctype = os.environ.get("LC_ALL", os.environ.get("LC_CTYPE", os.environ.get("LANG")))
+    # Ensure that fish is using UTF-8.
+    ctype = os.environ.get("LC_ALL", os.environ.get("LC_CTYPE",
+                                                    os.environ.get("LANG")))
     env = None
     if ctype is None or re.search(r"\.utf-?8$", ctype, flags=re.I) is None:
         # override LC_CTYPE with en_US.UTF-8
@@ -52,11 +51,14 @@ def run_fish_cmd(text):
         # Fish makes the same assumption in config.fish
         env = os.environ.copy()
         env.update(LC_CTYPE="en_US.UTF-8", LANG="en_US.UTF-8")
-    p = subprocess.Popen([FISH_BIN_PATH], stdin=PIPE, stdout=PIPE, stderr=PIPE, env=env)
+    p = subprocess.Popen([FISH_BIN_PATH], stdin=subprocess.PIPE,
+                         stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+                         env=env)
     out, err = p.communicate(text.encode('utf-8'))
     out = out.decode('utf-8', 'replace')
     err = err.decode('utf-8', 'replace')
-    return(out, err)
+    return out, err
+
 
 def escape_fish_cmd(text):
     # Replace one backslash with two, and single quotes with backslash-quote
@@ -64,56 +66,52 @@ def escape_fish_cmd(text):
     return "'" + escaped + "'"
 
 named_colors = {
-    'black'     : '000000',
-    'red'       : '800000',
-    'green'     : '008000',
-    'brown'     : '725000',
-    'yellow'    : '808000',
-    'blue'      : '000080',
-    'magenta'   : '800080',
-    'purple'    : '800080',
-    'cyan'      : '008080',
-    'grey'      : 'e5e5e5',
-    'brgrey'    : '555555',
-    'white'     : 'c0c0c0',
-    'brblack'   : '808080',
-    'brred'     : 'ff0000',
-    'brgreen'   : '00ff00',
-    'brbrown'   : 'ffff00',
-    'bryellow'  : 'ffff00',
-    'brblue'    : '0000ff',
-    'brmagenta' : 'ff00ff',
-    'brpurple'  : 'ff00ff',
-    'brcyan'    : '00ffff',
-    'brwhite'   : 'ffffff'
+    'black': '000000', 'red': '800000', 'green': '008000', 'brown': '725000',
+    'yellow': '808000', 'blue': '000080', 'magenta': '800080',
+    'purple': '800080', 'cyan': '008080', 'grey': 'e5e5e5', 'brgrey': '555555',
+    'white': 'c0c0c0', 'brblack': '808080', 'brred': 'ff0000',
+    'brgreen': '00ff00', 'brbrown': 'ffff00', 'bryellow': 'ffff00',
+    'brblue': '0000ff', 'brmagenta': 'ff00ff', 'brpurple': 'ff00ff',
+    'brcyan': '00ffff', 'brwhite': 'ffffff'
 }
 
 bindings_blacklist = set(["self-insert", "'begin;end'"])
 
+
 def parse_one_color(comp):
     """ A basic function to parse a single color value like 'FFA000' """
     if comp in named_colors:
         # Named color
         return named_colors[comp]
-    elif re.match(r"[0-9a-fA-F]{3}", comp) is not None or re.match(r"[0-9a-fA-F]{6}", comp) is not None:
+    elif (re.match(r"[0-9a-fA-F]{3}", comp) is not None or
+          re.match(r"[0-9a-fA-F]{6}", comp) is not None):
         # Hex color
         return comp
     else:
         # Unknown
         return ''
 
+
 def better_color(c1, c2):
     """ Indicate which color is "better", i.e. prefer term256 colors """
-    if not c2: return c1
-    if not c1: return c2
-    if c1 == 'normal': return c2
-    if c2 == 'normal': return c1
-    if c2 in named_colors: return c1
-    if c1 in named_colors: return c2
+    if not c2:
+        return c1
+    if not c1:
+        return c2
+    if c1 == 'normal':
+        return c2
+    if c2 == 'normal':
+        return c1
+    if c2 in named_colors:
+        return c1
+    if c1 in named_colors:
+        return c2
     return c1
 
+
 def parse_color(color_str):
-    """ A basic function to parse a color string, for example, 'red' '--bold' """
+    """ A basic function to parse a color string, for example, 'red' '--bold'.
+    """
     comps = color_str.split(' ')
     color = 'normal'
     background_color = ''
@@ -127,21 +125,69 @@ def parse_color(color_str):
             underline = True
         elif comp.startswith('--background='):
             # Background color
-            background_color = better_color(background_color, parse_one_color(comp[len('--background='):]))
+            background_color = better_color(
+                background_color, parse_one_color(comp[len('--background='):]))
         else:
             # Regular color
             color = better_color(color, parse_one_color(comp))
 
-    return {"color": color, "background": background_color, "bold": bold, "underline": underline}
+    return {"color": color, "background": background_color, "bold": bold,
+            "underline": underline}
+
 
 def parse_bool(val):
     val = val.lower()
-    if val.startswith('f') or val.startswith('0'): return False
-    if val.startswith('t') or val.startswith('1'): return True
+    if val.startswith('f') or val.startswith('0'):
+        return False
+    if val.startswith('t') or val.startswith('1'):
+        return True
     return bool(val)
 
+
 def html_color_for_ansi_color_index(val):
-    arr = ['black', '#AA0000', '#00AA00', '#AA5500', '#0000AA', '#AA00AA', '#00AAAA', '#AAAAAA', '#555555', '#FF5555', '#55FF55', '#FFFF55', '#5555FF', '#FF55FF', '#55FFFF', 'white', '#000000', '#00005f', '#000087', '#0000af', '#0000d7', '#0000ff', '#005f00', '#005f5f', '#005f87', '#005faf', '#005fd7', '#005fff', '#008700', '#00875f', '#008787', '#0087af', '#0087d7', '#0087ff', '#00af00', '#00af5f', '#00af87', '#00afaf', '#00afd7', '#00afff', '#00d700', '#00d75f', '#00d787', '#00d7af', '#00d7d7', '#00d7ff', '#00ff00', '#00ff5f', '#00ff87', '#00ffaf', '#00ffd7', '#00ffff', '#5f0000', '#5f005f', '#5f0087', '#5f00af', '#5f00d7', '#5f00ff', '#5f5f00', '#5f5f5f', '#5f5f87', '#5f5faf', '#5f5fd7', '#5f5fff', '#5f8700', '#5f875f', '#5f8787', '#5f87af', '#5f87d7', '#5f87ff', '#5faf00', '#5faf5f', '#5faf87', '#5fafaf', '#5fafd7', '#5fafff', '#5fd700', '#5fd75f', '#5fd787', '#5fd7af', '#5fd7d7', '#5fd7ff', '#5fff00', '#5fff5f', '#5fff87', '#5fffaf', '#5fffd7', '#5fffff', '#870000', '#87005f', '#870087', '#8700af', '#8700d7', '#8700ff', '#875f00', '#875f5f', '#875f87', '#875faf', '#875fd7', '#875fff', '#878700', '#87875f', '#878787', '#8787af', '#8787d7', '#8787ff', '#87af00', '#87af5f', '#87af87', '#87afaf', '#87afd7', '#87afff', '#87d700', '#87d75f', '#87d787', '#87d7af', '#87d7d7', '#87d7ff', '#87ff00', '#87ff5f', '#87ff87', '#87ffaf', '#87ffd7', '#87ffff', '#af0000', '#af005f', '#af0087', '#af00af', '#af00d7', '#af00ff', '#af5f00', '#af5f5f', '#af5f87', '#af5faf', '#af5fd7', '#af5fff', '#af8700', '#af875f', '#af8787', '#af87af', '#af87d7', '#af87ff', '#afaf00', '#afaf5f', '#afaf87', '#afafaf', '#afafd7', '#afafff', '#afd700', '#afd75f', '#afd787', '#afd7af', '#afd7d7', '#afd7ff', '#afff00', '#afff5f', '#afff87', '#afffaf', '#afffd7', '#afffff', '#d70000', '#d7005f', '#d70087', '#d700af', '#d700d7', '#d700ff', '#d75f00', '#d75f5f', '#d75f87', '#d75faf', '#d75fd7', '#d75fff', '#d78700', '#d7875f', '#d78787', '#d787af', '#d787d7', '#d787ff', '#d7af00', '#d7af5f', '#d7af87', '#d7afaf', '#d7afd7', '#d7afff', '#d7d700', '#d7d75f', '#d7d787', '#d7d7af', '#d7d7d7', '#d7d7ff', '#d7ff00', '#d7ff5f', '#d7ff87', '#d7ffaf', '#d7ffd7', '#d7ffff', '#ff0000', '#ff005f', '#ff0087', '#ff00af', '#ff00d7', '#ff00ff', '#ff5f00', '#ff5f5f', '#ff5f87', '#ff5faf', '#ff5fd7', '#ff5fff', '#ff8700', '#ff875f', '#ff8787', '#ff87af', '#ff87d7', '#ff87ff', '#ffaf00', '#ffaf5f', '#ffaf87', '#ffafaf', '#ffafd7', '#ffafff', '#ffd700', '#ffd75f', '#ffd787', '#ffd7af', '#ffd7d7', '#ffd7ff', '#ffff00', '#ffff5f', '#ffff87', '#ffffaf', '#ffffd7', '#ffffff', '#080808', '#121212', '#1c1c1c', '#262626', '#303030', '#3a3a3a', '#444444', '#4e4e4e', '#585858', '#626262', '#6c6c6c', '#767676', '#808080', '#8a8a8a', '#949494', '#9e9e9e', '#a8a8a8', '#b2b2b2', '#bcbcbc', '#c6c6c6', '#d0d0d0', '#dadada', '#e4e4e4', '#eeeeee']
+    arr = ['black', '#AA0000', '#00AA00', '#AA5500', '#0000AA', '#AA00AA',
+           '#00AAAA', '#AAAAAA', '#555555', '#FF5555', '#55FF55', '#FFFF55',
+           '#5555FF', '#FF55FF', '#55FFFF', 'white', '#000000', '#00005f',
+           '#000087', '#0000af', '#0000d7', '#0000ff', '#005f00', '#005f5f',
+           '#005f87', '#005faf', '#005fd7', '#005fff', '#008700', '#00875f',
+           '#008787', '#0087af', '#0087d7', '#0087ff', '#00af00', '#00af5f',
+           '#00af87', '#00afaf', '#00afd7', '#00afff', '#00d700', '#00d75f',
+           '#00d787', '#00d7af', '#00d7d7', '#00d7ff', '#00ff00', '#00ff5f',
+           '#00ff87', '#00ffaf', '#00ffd7', '#00ffff', '#5f0000', '#5f005f',
+           '#5f0087', '#5f00af', '#5f00d7', '#5f00ff', '#5f5f00', '#5f5f5f',
+           '#5f5f87', '#5f5faf', '#5f5fd7', '#5f5fff', '#5f8700', '#5f875f',
+           '#5f8787', '#5f87af', '#5f87d7', '#5f87ff', '#5faf00', '#5faf5f',
+           '#5faf87', '#5fafaf', '#5fafd7', '#5fafff', '#5fd700', '#5fd75f',
+           '#5fd787', '#5fd7af', '#5fd7d7', '#5fd7ff', '#5fff00', '#5fff5f',
+           '#5fff87', '#5fffaf', '#5fffd7', '#5fffff', '#870000', '#87005f',
+           '#870087', '#8700af', '#8700d7', '#8700ff', '#875f00', '#875f5f',
+           '#875f87', '#875faf', '#875fd7', '#875fff', '#878700', '#87875f',
+           '#878787', '#8787af', '#8787d7', '#8787ff', '#87af00', '#87af5f',
+           '#87af87', '#87afaf', '#87afd7', '#87afff', '#87d700', '#87d75f',
+           '#87d787', '#87d7af', '#87d7d7', '#87d7ff', '#87ff00', '#87ff5f',
+           '#87ff87', '#87ffaf', '#87ffd7', '#87ffff', '#af0000', '#af005f',
+           '#af0087', '#af00af', '#af00d7', '#af00ff', '#af5f00', '#af5f5f',
+           '#af5f87', '#af5faf', '#af5fd7', '#af5fff', '#af8700', '#af875f',
+           '#af8787', '#af87af', '#af87d7', '#af87ff', '#afaf00', '#afaf5f',
+           '#afaf87', '#afafaf', '#afafd7', '#afafff', '#afd700', '#afd75f',
+           '#afd787', '#afd7af', '#afd7d7', '#afd7ff', '#afff00', '#afff5f',
+           '#afff87', '#afffaf', '#afffd7', '#afffff', '#d70000', '#d7005f',
+           '#d70087', '#d700af', '#d700d7', '#d700ff', '#d75f00', '#d75f5f',
+           '#d75f87', '#d75faf', '#d75fd7', '#d75fff', '#d78700', '#d7875f',
+           '#d78787', '#d787af', '#d787d7', '#d787ff', '#d7af00', '#d7af5f',
+           '#d7af87', '#d7afaf', '#d7afd7', '#d7afff', '#d7d700', '#d7d75f',
+           '#d7d787', '#d7d7af', '#d7d7d7', '#d7d7ff', '#d7ff00', '#d7ff5f',
+           '#d7ff87', '#d7ffaf', '#d7ffd7', '#d7ffff', '#ff0000', '#ff005f',
+           '#ff0087', '#ff00af', '#ff00d7', '#ff00ff', '#ff5f00', '#ff5f5f',
+           '#ff5f87', '#ff5faf', '#ff5fd7', '#ff5fff', '#ff8700', '#ff875f',
+           '#ff8787', '#ff87af', '#ff87d7', '#ff87ff', '#ffaf00', '#ffaf5f',
+           '#ffaf87', '#ffafaf', '#ffafd7', '#ffafff', '#ffd700', '#ffd75f',
+           '#ffd787', '#ffd7af', '#ffd7d7', '#ffd7ff', '#ffff00', '#ffff5f',
+           '#ffff87', '#ffffaf', '#ffffd7', '#ffffff', '#080808', '#121212',
+           '#1c1c1c', '#262626', '#303030', '#3a3a3a', '#444444', '#4e4e4e',
+           '#585858', '#626262', '#6c6c6c', '#767676', '#808080', '#8a8a8a',
+           '#949494', '#9e9e9e', '#a8a8a8', '#b2b2b2', '#bcbcbc', '#c6c6c6',
+           '#d0d0d0', '#dadada', '#e4e4e4', '#eeeeee']
     if val < 0 or val >= len(arr):
         return ''
     else:
@@ -149,6 +195,8 @@ def html_color_for_ansi_color_index(val):
 
 # Function to return special ANSI escapes like exit_attribute_mode
 g_special_escapes_dict = None
+
+
 def get_special_ansi_escapes():
     global g_special_escapes_dict
     if g_special_escapes_dict is None:
@@ -160,8 +208,10 @@ def get_special_ansi_escapes():
         def get_tparm(key):
             val = None
             key = curses.tigetstr("sgr0")
-            if key: val = curses.tparm(key)
-            if val: val = val.decode('utf-8')
+            if key:
+                val = curses.tparm(key)
+            if val:
+                val = val.decode('utf-8')
             return val
 
         # Just a few for now
@@ -173,6 +223,8 @@ def get_special_ansi_escapes():
 
 # Given a known ANSI escape sequence, convert it to HTML and append to the list
 # Returns whether we have an open 
+
+
 def append_html_for_ansi_escape(full_val, result, span_open):
 
     # Strip off the initial \x1b[ and terminating m
@@ -187,16 +239,16 @@ def append_html_for_ansi_escape(full_val, result, span_open):
     match = re.match('38;5;(\d+)', val)
     if match is not None:
         close_span()
-        html_color =  html_color_for_ansi_color_index(int(match.group(1)))
+        html_color = html_color_for_ansi_color_index(int(match.group(1)))
         result.append('')
-        return True # span now open
+        return True  # span now open
 
     # term8 foreground color
     if val in [str(x) for x in range(30, 38)]:
         close_span()
-        html_color =  html_color_for_ansi_color_index(int(val) - 30)
+        html_color = html_color_for_ansi_color_index(int(val) - 30)
         result.append('')
-        return True # span now open
+        return True  # span now open
 
     # Try special escapes
     special_escapes = get_special_ansi_escapes()
@@ -209,15 +261,17 @@ def append_html_for_ansi_escape(full_val, result, span_open):
     # Do nothing on failure
     return span_open
 
+
 def strip_ansi(val):
     # Make a half-assed effort to strip ANSI control sequences
     # We assume that all such sequences start with 0x1b and end with m,
     # which catches most cases
     return re.sub("\x1b[^m]*m", '', val)
 
+
 def ansi_prompt_line_width(val):
-    # Given an ANSI prompt, return the length of its longest line, as in the number of characters it takes up
-    # Start by stripping off ANSI
+    # Given an ANSI prompt, return the length of its longest line, as in the
+    # number of characters it takes up. Start by stripping off ANSI.
     stripped_val = strip_ansi(val)
 
     # Now count the longest line
@@ -225,10 +279,10 @@ def ansi_prompt_line_width(val):
 
 
 def ansi_to_html(val):
-    # Split us up by ANSI escape sequences
-    # We want to catch not only the standard color codes, but also things like sgr0
-    # Hence this lame check
-    # Note that Python 2.6 doesn't have a flag param to re.split, so we have to compile it first
+    # Split us up by ANSI escape sequences. We want to catch not only the
+    # standard color codes, but also things like sgr0. Hence this lame check.
+    # Note that Python 2.6 doesn't have a flag param to re.split, so we have to
+    # compile it first.
     reg = re.compile("""
         (                        # Capture
          \x1b                    # Escape
@@ -253,10 +307,12 @@ def ansi_to_html(val):
             result.append(cgi.escape(strip_ansi(component)))
         else:
             # It's an escape sequence. Close the previous escape.
-            span_open = append_html_for_ansi_escape(component, result, span_open)
+            span_open = append_html_for_ansi_escape(component, result,
+                                                    span_open)
 
     # Close final escape
-    if span_open: result.append('')
+    if span_open:
+        result.append('')
 
     # Remove empty elements
     result = [x for x in result if x]
@@ -272,6 +328,7 @@ def ansi_to_html(val):
 
     return ''.join(result)
 
+
 class FishVar:
     """ A class that represents a variable """
     def __init__(self, name, value):
@@ -283,15 +340,20 @@ class FishVar:
     def get_json_obj(self):
         # Return an array(3): name, value, flags
         flags = []
-        if self.universal: flags.append('universal')
-        if self.exported: flags.append('exported')
-        return {"name": self.name, "value": self.value, "Flags": ', '.join(flags)}
+        if self.universal:
+            flags.append('universal')
+        if self.exported:
+            flags.append('exported')
+        return {"name": self.name, "value": self.value,
+                "Flags": ', '.join(flags)}
+
 
 class FishBinding:
     """A class that represents keyboard binding """
 
-    def __init__(self, command, raw_binding, readable_binding, description=None):
-        self.command =  command
+    def __init__(self, command, raw_binding, readable_binding,
+                 description=None):
+        self.command = command
         self.bindings = []
         self.description = description
         self.add_binding(raw_binding, readable_binding)
@@ -302,23 +364,24 @@ class FishBinding:
                 i['raw_bindings'].append(raw_binding)
                 break
         else:
-            self.bindings.append({'readable_binding':readable_binding, 'raw_bindings':[raw_binding]})
+            self.bindings.append({'readable_binding': readable_binding,
+                                  'raw_bindings': [raw_binding]})
 
     def get_json_obj(self):
-        return {"command" : self.command, "bindings": self.bindings, "description": self.description}
+        return {"command": self.command, "bindings": self.bindings,
+                "description": self.description}
 
 
 class BindingParser:
     """ Class to parse codes for bind command """
 
-    #TODO: What does snext and sprevious mean ?
-    readable_keys=  { "dc":"Delete", "npage": "Page Up", "ppage":"Page Down",
-                    "sdc": "Shift Delete", "shome": "Shift Home",
-                    "left": "Left Arrow", "right": "Right Arrow",
-                    "up": "Up Arrow", "down": "Down Arrow",
-                    "sleft": "Shift Left", "sright": "Shift Right",
-                    "btab": "Shift Tab"
-                    }
+    # TODO: What does snext and sprevious mean ?
+    readable_keys = {"dc": "Delete", "npage": "Page Up", "ppage": "Page Down",
+                     "sdc": "Shift Delete", "shome": "Shift Home",
+                     "left": "Left Arrow", "right": "Right Arrow",
+                     "up": "Up Arrow", "down": "Down Arrow",
+                     "sleft": "Shift Left", "sright": "Shift Right",
+                     "btab": "Shift Tab"}
 
     def set_buffer(self, buffer):
         """ Sets code to parse """
@@ -356,7 +419,8 @@ class BindingParser:
 
         # \[1\; is start of control sequence
         if c == '1':
-            b = self.get_char(); c = self.get_char()
+            b = self.get_char()
+            c = self.get_char()
             if b == '\\' and c == '~':
                 result += "Home"
             elif c == ";":
@@ -369,7 +433,8 @@ class BindingParser:
 
         # \[4\~ is End
         if c == '4':
-            b = self.get_char(); c = self.get_char()
+            b = self.get_char()
+            c = self.get_char()
             if b == '\\' and c == '~':
                 result += "End"
 
@@ -466,7 +531,7 @@ class FishConfigTCPServer(SocketServer.TCPServer):
     """TCPServer that only accepts connections from localhost (IPv4/IPv6)."""
     WHITELIST = set(['::1', '::ffff:127.0.0.1', '127.0.0.1'])
 
-    address_family = socket.AF_INET6 if HAS_IPV6 else socket.AF_INET
+    address_family = socket.AF_INET6 if socket.has_ipv6 else socket.AF_INET
 
     def verify_request(self, request, client_address):
         return client_address[0] in FishConfigTCPServer.WHITELIST
@@ -526,7 +591,7 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
             for match in re.finditer(r"^fish_color_(\S+) ?(.*)", line):
                 color_name, color_value = [x.strip() for x in match.group(1, 2)]
                 color_desc = descriptions.get(color_name, '')
-                data = { "name": color_name, "description" : color_desc }
+                data = {"name": color_name, "description": color_desc}
                 data.update(parse_color(color_value))
                 result.append(data)
                 remaining.discard(color_name)
@@ -564,18 +629,22 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
         vars = {}
         for line in out.split('\n'):
             comps = line.split(' ', 1)
-            if len(comps) < 2: continue
+            if len(comps) < 2:
+                continue
             fish_var = FishVar(comps[0], comps[1])
             vars[fish_var.name] = fish_var
 
         # Mark universal variables. L means don't abbreviate.
         for name in self.do_get_variable_names('set -nUL'):
-            if name in vars: vars[name].universal = True
+            if name in vars:
+                vars[name].universal = True
         # Mark exported variables. L means don't abbreviate.
         for name in self.do_get_variable_names('set -nxL'):
-            if name in vars: vars[name].exported = True
+            if name in vars:
+                vars[name].exported = True
 
-        return [vars[key].get_json_obj() for key in sorted(vars.keys(), key=lambda x: x.lower())]
+        return [vars[key].get_json_obj() for key
+                in sorted(vars.keys(), key=lambda x: x.lower())]
 
     def do_get_bindings(self):
         """ Get key bindings """
@@ -621,29 +690,37 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
                 bindings.append(fish_binding)
                 command_to_binding[command] = fish_binding
 
-        return [ binding.get_json_obj() for binding in bindings ]
+        return [binding.get_json_obj() for binding in bindings]
 
     def do_get_history(self):
-        # Use \x1e ("record separator") to distinguish between history items. The first
-        # backslash is so Python passes one backslash to fish
+        # Use \x1e ("record separator") to distinguish between history items.
+        # The first backslash is so Python passes one backslash to fish.
         out, err = run_fish_cmd('for val in $history; echo -n $val \\x1e; end')
         result = out.split(' \x1e')
-        if result: result.pop() # Trim off the trailing element
+        if result:
+            result.pop()  # trim off the trailing element
         return result
 
     def do_get_color_for_variable(self, name):
-        "Return the color with the given name, or the empty string if there is none"
+        # Return the color with the given name, or the empty string if there is
+        # none.
         out, err = run_fish_cmd("echo -n $" + name)
         return out
 
-    def do_set_color_for_variable(self, name, color, background_color, bold, underline):
-        if not color: color = 'normal'
+    def do_set_color_for_variable(self, name, color, background_color, bold,
+                                  underline):
+        if not color:
+            color = 'normal'
         "Sets a color for a fish color name, like 'autosuggestion'"
         command = 'set -U fish_color_' + name
-        if color: command += ' ' + color
-        if background_color: command += ' --background=' + background_color
-        if bold: command += ' --bold'
-        if underline: command += ' --underline'
+        if color:
+            command += ' ' + color
+        if background_color:
+            command += ' --background=' + background_color
+        if bold:
+            command += ' --bold'
+        if underline:
+            command += ' --underline'
 
         out, err = run_fish_cmd(command)
         return out
@@ -655,7 +732,7 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
     def do_delete_history_item(self, history_item_text):
         # It's really lame that we always return success here
         cmd = ('builtin history delete --exact -- %s; builtin history save' %
-            escape_fish_cmd(history_item_text))
+               escape_fish_cmd(history_item_text))
         out, err = run_fish_cmd(cmd)
         return True
 
@@ -669,29 +746,35 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
         prompt_demo_ansi, err = run_fish_cmd(command_to_run)
         prompt_demo_html = ansi_to_html(prompt_demo_ansi)
         prompt_demo_font_size = self.font_size_for_ansi_prompt(prompt_demo_ansi)
-        result = {'function': prompt_function_text, 'demo': prompt_demo_html, 'font_size': prompt_demo_font_size }
+        result = {'function': prompt_function_text, 'demo': prompt_demo_html,
+                  'font_size': prompt_demo_font_size}
         if extras_dict:
             result.update(extras_dict)
         return result
 
     def do_get_current_prompt(self):
-        # Return the current prompt
-        # We run 'false' to demonstrate how the prompt shows the command status (#1624)
+        # Return the current prompt. We run 'false' to demonstrate how the
+        # prompt shows the command status (#1624).
         prompt_func, err = run_fish_cmd('functions fish_prompt')
-        result = self.do_get_prompt('builtin cd "' + initial_wd + '" ; false ; fish_prompt', prompt_func.strip(), {'name': 'Current'})
+        result = self.do_get_prompt(
+            'builtin cd "' + initial_wd + '" ; false ; fish_prompt',
+            prompt_func.strip(), {'name': 'Current'})
         return result
 
     def do_get_sample_prompt(self, text, extras_dict):
-        # Return the prompt you get from the given text
-        # extras_dict is a dictionary whose values get merged in
-        # We run 'false' to demonstrate how the prompt shows the command status (#1624)
-        cmd = text + "\n builtin cd \"" + initial_wd + "\" \n false \n fish_prompt\n"
+        # Return the prompt you get from the given text. Extras_dict is a
+        # dictionary whose values get merged in. We run 'false' to demonstrate
+        # how the prompt shows the command status (#1624)
+        cmd = (text + "\n builtin cd \"" + initial_wd +
+               "\" \n false \n fish_prompt\n")
         return self.do_get_prompt(cmd, text.strip(), extras_dict)
 
     def parse_one_sample_prompt_hash(self, line, result_dict):
         # Allow us to skip whitespace, etc.
-        if not line: return True
-        if line.isspace(): return True
+        if not line:
+            return True
+        if line.isspace():
+            return True
 
         # Parse a comment hash like '# name: Classic'
         match = re.match(r"#\s*(\w+?): (.+)", line, re.IGNORECASE)
@@ -703,7 +786,6 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
         # Skip other hash comments
         return line.startswith('#')
 
-
     def read_one_sample_prompt(self, path):
         try:
             with open(path, 'rb') as fd:
@@ -713,10 +795,13 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
                 parsing_hashes = True
                 unicode_lines = (line.decode('utf-8') for line in fd)
                 for line in unicode_lines:
-                    # Parse hashes until parse_one_sample_prompt_hash return False
+                    # Parse hashes until parse_one_sample_prompt_hash return
+                    # False.
                     if parsing_hashes:
-                        parsing_hashes = self.parse_one_sample_prompt_hash(line, extras_dict)
-                    # Maybe not we're not parsing hashes, or maybe we already were not
+                        parsing_hashes = self.parse_one_sample_prompt_hash(
+                            line, extras_dict)
+                    # Maybe not we're not parsing hashes, or maybe we already
+                    # were not.
                     if not parsing_hashes:
                         function_lines.append(line)
                 func = ''.join(function_lines).strip()
@@ -752,37 +837,46 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
 
     def do_remove_abbreviation(self, abbreviation):
         out, err = run_fish_cmd('abbr --erase %s' % abbreviation['word'])
-        if out or err:
-            return err
-        else:
-            return True
-
-    def do_save_abbreviation(self, abbreviation):
-        out, err = run_fish_cmd('abbr --add \'%s %s\'' % (abbreviation['word'], abbreviation['phrase']))
         if err:
             return err
         else:
-            return True
+            return None
+
+    def do_save_abbreviation(self, abbreviation):
+        out, err = run_fish_cmd('abbr --add \'%s\' \'%s\'' % (
+            abbreviation['word'], abbreviation['phrase']))
+        if err:
+            return err
+        else:
+            return None
 
     def secure_startswith(self, haystack, needle):
         if len(haystack) < len(needle):
             return False
         bits = 0
-        for x,y in zip(haystack, needle):
+        for x, y in zip(haystack, needle):
             bits |= ord(x) ^ ord(y)
         return bits == 0
 
     def font_size_for_ansi_prompt(self, prompt_demo_ansi):
         width = ansi_prompt_line_width(prompt_demo_ansi)
         # Pick a font size
-        if width >= 70: font_size = '8pt'
-        if width >= 60: font_size = '10pt'
-        elif width >= 50: font_size = '11pt'
-        elif width >= 40: font_size = '13pt'
-        elif width >= 30: font_size = '15pt'
-        elif width >= 25: font_size = '16pt'
-        elif width >= 20: font_size = '17pt'
-        else: font_size = '18pt'
+        if width >= 70:
+            font_size = '8pt'
+        if width >= 60:
+            font_size = '10pt'
+        elif width >= 50:
+            font_size = '11pt'
+        elif width >= 40:
+            font_size = '13pt'
+        elif width >= 30:
+            font_size = '15pt'
+        elif width >= 25:
+            font_size = '16pt'
+        elif width >= 20:
+            font_size = '17pt'
+        else:
+            font_size = '18pt'
         return font_size
 
     def do_GET(self):
@@ -820,7 +914,7 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
 
         # Return valid output
         self.send_response(200)
-        self.send_header('Content-type','application/json')
+        self.send_header('Content-type', 'application/json')
         self.end_headers()
         self.write_to_wfile('\n')
 
@@ -861,7 +955,9 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
 
             if what:
                 # Not sure why we get lists here?
-                output = self.do_set_color_for_variable(what[0], color[0], background_color[0], parse_bool(bold[0]), parse_bool(underline[0]))
+                output = self.do_set_color_for_variable(
+                    what[0], color[0], background_color[0],
+                    parse_bool(bold[0]), parse_bool(underline[0]))
             else:
                 output = 'Bad request'
         elif p == '/get_function/':
@@ -880,23 +976,23 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
             else:
                 output = ["Unable to set prompt"]
         elif p == '/save_abbreviation/':
-            r = self.do_save_abbreviation(postvars)
-            if r == True:
-                output = ["OK"]
+            errmsg = self.do_save_abbreviation(postvars)
+            if errmsg:
+                output = [errmsg]
             else:
-                output = [r]
+                output = ["OK"]
         elif p == '/remove_abbreviation/':
-            r = self.do_remove_abbreviation(postvars)
-            if r == True:
-                output = ["OK"]
+            errmsg = self.do_remove_abbreviation(postvars)
+            if errmsg:
+                output = [errmsg]
             else:
-                output = [r]
+                output = ["OK"]
         else:
             return self.send_error(404)
 
         # Return valid output
         self.send_response(200)
-        self.send_header('Content-type','application/json')
+        self.send_header('Content-type', 'application/json')
         self.end_headers()
         self.write_to_wfile('\n')
 
@@ -932,7 +1028,8 @@ redirect_template_html = """
 fish_bin_dir = os.environ.get('__fish_bin_dir')
 fish_bin_path = None
 if not fish_bin_dir:
-    print('The __fish_bin_dir environment variable is not set. Looking in $PATH...')
+    print('The __fish_bin_dir environment variable is not set. '
+          'Looking in $PATH...')
     # distutils.spawn is terribly broken, because it looks in wd before PATH,
     # and doesn't actually validate that the file is even executable
     for p in os.environ['PATH'].split(os.pathsep):
@@ -950,7 +1047,8 @@ else:
     fish_bin_path = os.path.join(fish_bin_dir, 'fish')
 
 if not os.access(fish_bin_path, os.X_OK):
-    print("fish could not be executed at path '%s'. Is fish installed correctly?" % fish_bin_path)
+    print("fish could not be executed at path '%s'. "
+          "Is fish installed correctly?" % fish_bin_path)
     sys.exit(-1)
 FISH_BIN_PATH = fish_bin_path
 
@@ -958,8 +1056,8 @@ FISH_BIN_PATH = fish_bin_path
 # so get the current working directory
 initial_wd = os.getcwd()
 
-# Make sure that the working directory is the one that contains the script server file,
-# because the document root is the working directory
+# Make sure that the working directory is the one that contains the script
+# server file, because the document root is the working directory.
 where = os.path.dirname(sys.argv[0])
 os.chdir(where)
 
@@ -968,7 +1066,7 @@ authkey = binascii.b2a_hex(os.urandom(16)).decode('ascii')
 
 # Try to find a suitable port
 PORT = 8000
-HOST = "::" if HAS_IPV6 else "localhost"
+HOST = "::" if socket.has_ipv6 else "localhost"
 while PORT <= 9000:
     try:
         Handler = FishConfigHTTPRequestHandler
@@ -992,16 +1090,17 @@ if PORT > 9000:
 # Just look at the first letter
 initial_tab = ''
 if len(sys.argv) > 1:
-    for tab in ['functions', 'prompt', 'colors', 'variables', 'history', 'bindings', 'abbreviations']:
+    for tab in ['functions', 'prompt', 'colors', 'variables', 'history',
+                'bindings', 'abbreviations']:
         if tab.startswith(sys.argv[1]):
             initial_tab = '#' + tab
             break
 
 url = 'http://localhost:%d/%s/%s' % (PORT, authkey, initial_tab)
 
-# Create temporary file to hold redirect to real server
-# This prevents exposing the URL containing the authentication key on the command line
-# (see CVE-2014-2914 or https://github.com/fish-shell/fish-shell/issues/1438)
+# Create temporary file to hold redirect to real server. This prevents exposing
+# the URL containing the authentication key on the command line (see
+# CVE-2014-2914 or https://github.com/fish-shell/fish-shell/issues/1438).
 if 'XDG_CACHE_HOME' in os.environ:
     dirname = os.path.expanduser(os.path.expandvars('$XDG_CACHE_HOME/fish/'))
 else:
@@ -1012,11 +1111,12 @@ try:
     os.makedirs(dirname, 0o0700)
 except OSError as e:
     if e.errno == 17:
-       pass
+        pass
     else:
-       raise e
+        raise e
 
-randtoken = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(6))
+randtoken = ''.join(random.choice(string.ascii_uppercase + string.digits)
+                    for _ in range(6))
 filename = dirname + 'web_config-%s.html' % randtoken
 
 f = open(filename, 'w')
diff --git a/src/autoload.cpp b/src/autoload.cpp
index a10de1364..0b25b6f4d 100644
--- a/src/autoload.cpp
+++ b/src/autoload.cpp
@@ -1,7 +1,6 @@
 // The classes responsible for autoloading functions and completions.
 #include "config.h"  // IWYU pragma: keep
 
-#include 
 #include 
 #include 
 #include 
@@ -26,7 +25,7 @@
 static const int kAutoloadStalenessInterval = 15;
 
 file_access_attempt_t access_file(const wcstring &path, int mode) {
-    // printf("Touch %ls\n", path.c_str());
+    // fwprintf(stderr, L"Touch %ls\n", path.c_str());
     file_access_attempt_t result = {};
     struct stat statbuf;
     if (wstat(path, &statbuf)) {
@@ -47,24 +46,22 @@ file_access_attempt_t access_file(const wcstring &path, int mode) {
     return result;
 }
 
-autoload_t::autoload_t(const wcstring &env_var_name_var, const builtin_script_t *const scripts,
-                       size_t script_count)
+autoload_t::autoload_t(const wcstring &env_var_name_var,
+                       command_removed_function_t cmd_removed_callback)
     : lock(),
       env_var_name(env_var_name_var),
-      builtin_scripts(scripts),
-      builtin_script_count(script_count) {
+      command_removed(cmd_removed_callback) {
     pthread_mutex_init(&lock, NULL);
 }
 
 autoload_t::~autoload_t() { pthread_mutex_destroy(&lock); }
 
-void autoload_t::node_was_evicted(autoload_function_t *node) {
+void autoload_t::entry_was_evicted(wcstring key, autoload_function_t node) {
     // This should only ever happen on the main thread.
     ASSERT_IS_MAIN_THREAD();
 
     // Tell ourselves that the command was removed if it was loaded.
-    if (node->is_loaded) this->command_removed(node->key);
-    delete node;
+    if (node.is_loaded) this->command_removed(std::move(key));
 }
 
 int autoload_t::unload(const wcstring &cmd) { return this->evict_node(cmd); }
@@ -123,15 +120,10 @@ bool autoload_t::can_load(const wcstring &cmd, const env_vars_snapshot_t &vars)
     return this->locate_file_and_maybe_load_it(cmd, false, false, path_list);
 }
 
-static bool script_name_precedes_script_name(const builtin_script_t &script1,
-                                             const builtin_script_t &script2) {
-    return wcscmp(script1.name, script2.name) < 0;
-}
-
 /// Check whether the given command is loaded.
 bool autoload_t::has_tried_loading(const wcstring &cmd) {
     scoped_lock locker(lock);
-    autoload_function_t *func = this->get_node(cmd);
+    autoload_function_t *func = this->get(cmd);
     return func != NULL;
 }
 
@@ -145,14 +137,16 @@ static bool is_stale(const autoload_function_t *func) {
 autoload_function_t *autoload_t::get_autoloaded_function_with_creation(const wcstring &cmd,
                                                                        bool allow_eviction) {
     ASSERT_IS_LOCKED(lock);
-    autoload_function_t *func = this->get_node(cmd);
+    autoload_function_t *func = this->get(cmd);
     if (!func) {
-        func = new autoload_function_t(cmd);
+        bool added;
         if (allow_eviction) {
-            this->add_node(func);
+            added = this->insert(cmd, autoload_function_t(false));
         } else {
-            this->add_node_without_eviction(func);
+            added = this->insert_no_eviction(cmd, autoload_function_t(false));
         }
+        func = this->get(cmd);
+        assert(func);
     }
     return func;
 }
@@ -189,7 +183,7 @@ bool autoload_t::locate_file_and_maybe_load_it(const wcstring &cmd, bool really_
     {
         bool allow_stale_functions = !reload;
         scoped_lock locker(lock);
-        autoload_function_t *func = this->get_node(cmd);  // get the function
+        autoload_function_t *func = this->get(cmd);  // get the function
 
         // If we can use this function, return whether we were able to access it.
         if (use_cached(func, really_load, allow_stale_functions)) {
@@ -199,110 +193,78 @@ bool autoload_t::locate_file_and_maybe_load_it(const wcstring &cmd, bool really_
 
     // The source of the script will end up here.
     wcstring script_source;
-    bool has_script_source = false;
 
     // Whether we found an accessible file.
     bool found_file = false;
 
-    // Look for built-in scripts via a binary search.
-    const builtin_script_t *matching_builtin_script = NULL;
-    if (builtin_script_count > 0) {
-        const builtin_script_t test_script = {cmd.c_str(), NULL};
-        const builtin_script_t *array_end = builtin_scripts + builtin_script_count;
-        const builtin_script_t *found = std::lower_bound(builtin_scripts, array_end, test_script,
-                                                         script_name_precedes_script_name);
-        if (found != array_end && !wcscmp(found->name, test_script.name)) {
-            matching_builtin_script = found;
-        }
-    }
-    if (matching_builtin_script) {
-        has_script_source = true;
-        script_source = str2wcstring(matching_builtin_script->def);
+    // Iterate over path searching for suitable completion files.
+    for (size_t i = 0; i < path_list.size() && !found_file; i++) {
+        wcstring next = path_list.at(i);
+        wcstring path = next + L"/" + cmd + L".fish";
 
-        // Make a node representing this function.
+        const file_access_attempt_t access = access_file(path, R_OK);
+        if (!access.accessible) {
+            continue;
+        }
+
+        // Now we're actually going to take the lock.
         scoped_lock locker(lock);
-        autoload_function_t *func = this->get_autoloaded_function_with_creation(cmd, really_load);
+        autoload_function_t *func = this->get(cmd);
 
-        // This function is internalized.
-        func->is_internalized = true;
+        // Generate the source if we need to load it.
+        bool need_to_load_function =
+            really_load &&
+            (func == NULL || func->access.mod_time != access.mod_time || !func->is_loaded);
+        if (need_to_load_function) {
+            // Generate the script source.
+            script_source = L"source " + escape_string(path, ESCAPE_ALL);
 
-        // It's a fiction to say the script is loaded at this point, but we're definitely going to
-        // load it down below.
-        if (really_load) func->is_loaded = true;
+            // Remove any loaded command because we are going to reload it. Note that this
+            // will deadlock if command_removed calls back into us.
+            if (func && func->is_loaded) {
+                command_removed(cmd);
+                func->is_placeholder = false;
+            }
+
+            // Mark that we're reloading it.
+            reloaded = true;
+        }
+
+        // Create the function if we haven't yet. This does not load it. Do not trigger
+        // eviction unless we are actually loading, because we don't want to evict off of
+        // the main thread.
+        if (!func) func = get_autoloaded_function_with_creation(cmd, really_load);
+
+        // It's a fiction to say the script is loaded at this point, but we're definitely
+        // going to load it down below.
+        if (need_to_load_function) func->is_loaded = true;
+
+        // Unconditionally record our access time.
+        func->access = access;
+        found_file = true;
     }
 
-    if (!has_script_source) {
-        // Iterate over path searching for suitable completion files.
-        for (size_t i = 0; i < path_list.size() && !found_file; i++) {
-            wcstring next = path_list.at(i);
-            wcstring path = next + L"/" + cmd + L".fish";
-
-            const file_access_attempt_t access = access_file(path, R_OK);
-            if (!access.accessible) {
-                continue;
+    // If no file or builtin script was found we insert a placeholder function. Later we only
+    // research if the current time is at least five seconds later. This way, the files won't be
+    // searched over and over again.
+    if (!found_file && script_source.empty()) {
+        scoped_lock locker(lock);
+        // Generate a placeholder.
+        autoload_function_t *func = this->get(cmd);
+        if (!func) {
+            if (really_load) {
+                this->insert(cmd, autoload_function_t(true));
+            } else {
+                this->insert(cmd, autoload_function_t(true));
             }
-
-            // Now we're actually going to take the lock.
-            scoped_lock locker(lock);
-            autoload_function_t *func = this->get_node(cmd);
-
-            // Generate the source if we need to load it.
-            bool need_to_load_function =
-                really_load &&
-                (func == NULL || func->access.mod_time != access.mod_time || !func->is_loaded);
-            if (need_to_load_function) {
-                // Generate the script source.
-                wcstring esc = escape_string(path, 1);
-                script_source = L"source " + esc;
-                has_script_source = true;
-
-                // Remove any loaded command because we are going to reload it. Note that this
-                // will deadlock if command_removed calls back into us.
-                if (func && func->is_loaded) {
-                    command_removed(cmd);
-                    func->is_placeholder = false;
-                }
-
-                // Mark that we're reloading it.
-                reloaded = true;
-            }
-
-            // Create the function if we haven't yet. This does not load it. Do not trigger
-            // eviction unless we are actually loading, because we don't want to evict off of
-            // the main thread.
-            if (!func) func = get_autoloaded_function_with_creation(cmd, really_load);
-
-            // It's a fiction to say the script is loaded at this point, but we're definitely
-            // going to load it down below.
-            if (need_to_load_function) func->is_loaded = true;
-
-            // Unconditionally record our access time.
-            func->access = access;
-            found_file = true;
-        }
-
-        // If no file or builtin script was found we insert a placeholder function. Later we only
-        // research if the current time is at least five seconds later. This way, the files won't be
-        // searched over and over again.
-        if (!found_file && !has_script_source) {
-            scoped_lock locker(lock);
-            // Generate a placeholder.
-            autoload_function_t *func = this->get_node(cmd);
-            if (!func) {
-                func = new autoload_function_t(cmd);
-                func->is_placeholder = true;
-                if (really_load) {
-                    this->add_node(func);
-                } else {
-                    this->add_node_without_eviction(func);
-                }
-            }
-            func->access.last_checked = time(NULL);
+            func = this->get(cmd);
+            assert(func);
         }
+        func->access.last_checked = time(NULL);
     }
 
     // If we have a script, either built-in or a file source, then run it.
-    if (really_load && has_script_source) {
+    if (really_load && !script_source.empty()) {
         // Do nothing on failure.
         exec_subshell(script_source, false /* do not apply exit status */);
     }
@@ -311,5 +273,5 @@ bool autoload_t::locate_file_and_maybe_load_it(const wcstring &cmd, bool really_
         return reloaded;
     }
 
-    return found_file || has_script_source;
+    return found_file || !script_source.empty();
 }
diff --git a/src/autoload.h b/src/autoload.h
index 49891828f..15ab14f27 100644
--- a/src/autoload.h
+++ b/src/autoload.h
@@ -25,13 +25,9 @@ struct file_access_attempt_t {
 };
 file_access_attempt_t access_file(const wcstring &path, int mode);
 
-struct autoload_function_t : public lru_node_t {
-    explicit autoload_function_t(const wcstring &key)
-        : lru_node_t(key),
-          access(),
-          is_loaded(false),
-          is_placeholder(false),
-          is_internalized(false) {}
+struct autoload_function_t {
+    explicit autoload_function_t(bool placeholder)
+        : access(), is_loaded(false), is_placeholder(placeholder), is_internalized(false) {}
 
     /// The last access attempt recorded
     file_access_attempt_t access;
@@ -44,24 +40,15 @@ struct autoload_function_t : public lru_node_t {
     bool is_internalized;
 };
 
-struct builtin_script_t {
-    const wchar_t *name;
-    const char *def;
-};
-
 class env_vars_snapshot_t;
 
 /// Class representing a path from which we can autoload and the autoloaded contents.
-class autoload_t : private lru_cache_t {
+class autoload_t : public lru_cache_t {
    private:
     /// Lock for thread safety.
     pthread_mutex_t lock;
     /// The environment variable name.
     const wcstring env_var_name;
-    /// Builtin script array.
-    const struct builtin_script_t *const builtin_scripts;
-    /// Builtin script count.
-    const size_t builtin_script_count;
     /// The path from which we most recently autoloaded.
     wcstring last_path;
     /// the most reecently autoloaded path, tokenized (split on separators).
@@ -69,27 +56,27 @@ class autoload_t : private lru_cache_t {
     /// A table containing all the files that are currently being loaded.
     /// This is here to help prevent recursion.
     std::set is_loading_set;
+    // Function invoked when a command is removed
+    typedef void (*command_removed_function_t)(const wcstring &);
+    const command_removed_function_t command_removed;
 
-    void remove_all_functions(void) { this->evict_all_nodes(); }
+    void remove_all_functions() { this->evict_all_nodes(); }
 
     bool locate_file_and_maybe_load_it(const wcstring &cmd, bool really_load, bool reload,
                                        const wcstring_list_t &path_list);
 
-    virtual void node_was_evicted(autoload_function_t *node);
-
     autoload_function_t *get_autoloaded_function_with_creation(const wcstring &cmd,
                                                                bool allow_eviction);
 
-   protected:
-    /// Overridable callback for when a command is removed.
-    virtual void command_removed(const wcstring &cmd) { UNUSED(cmd); }
-
    public:
-    /// Create an autoload_t for the given environment variable name.
-    autoload_t(const wcstring &env_var_name_var, const builtin_script_t *scripts,
-               size_t script_count);
+    // CRTP override
+    void entry_was_evicted(wcstring key, autoload_function_t node);
 
-    virtual ~autoload_t();
+    // Create an autoload_t for the given environment variable name.
+    autoload_t(const wcstring &env_var_name_var,
+               command_removed_function_t callback);
+
+    ~autoload_t();
 
     /// Autoload the specified file, if it exists in the specified path. Do not load it multiple
     /// times unless its timestamp changes or parse_util_unload is called.
diff --git a/src/builtin.cpp b/src/builtin.cpp
index 6172222a1..b66759e97 100644
--- a/src/builtin.cpp
+++ b/src/builtin.cpp
@@ -21,17 +21,18 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -79,6 +80,27 @@ bool builtin_data_t::operator<(const builtin_data_t *other) const {
     return wcscmp(this->name, other->name) < 0;
 }
 
+static void builtin_append_format(wcstring &str, const wchar_t *fmt, ...) {
+    va_list ap;
+    va_start(ap, fmt);
+    append_formatv(str, fmt, ap);
+    va_end(ap);
+}
+
+bool builtin_is_valid_varname(const wchar_t *varname, wcstring &errstr, const wchar_t *cmd) {
+    const wchar_t *invalid_char = wcsvarname(varname);
+    if (!invalid_char) {
+        return true;
+    }
+
+    if (*invalid_char == L'\0') {
+        builtin_append_format(errstr, BUILTIN_ERR_VARNAME_ZERO, cmd);
+    } else {
+        builtin_append_format(errstr, BUILTIN_ERR_VARCHAR, cmd, *invalid_char);
+    }
+    return false;
+}
+
 /// Counts the number of arguments in the specified null-terminated array
 int builtin_count_args(const wchar_t *const *argv) {
     int argc;
@@ -800,17 +822,20 @@ static int builtin_emit(parser_t &parser, io_streams_t &streams, wchar_t **argv)
 static int builtin_command(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
     wgetopter_t w;
     int argc = builtin_count_args(argv);
-    int print_path = 0;
+    bool find_path = false;
+    bool quiet = false;
 
     w.woptind = 0;
 
-    static const struct woption long_options[] = {
-        {L"search", no_argument, 0, 's'}, {L"help", no_argument, 0, 'h'}, {0, 0, 0, 0}};
+    static const struct woption long_options[] = {{L"quiet", no_argument, NULL, 'q'},
+                                                  {L"search", no_argument, NULL, 's'},
+                                                  {L"help", no_argument, NULL, 'h'},
+                                                  {NULL, 0, NULL, 0}};
 
     while (1) {
         int opt_index = 0;
 
-        int opt = w.wgetopt_long(argc, argv, L"svh", long_options, &opt_index);
+        int opt = w.wgetopt_long(argc, argv, L"qsvh", long_options, &opt_index);
         if (opt == -1) break;
 
         switch (opt) {
@@ -827,7 +852,11 @@ static int builtin_command(parser_t &parser, io_streams_t &streams, wchar_t **ar
             }
             case 's':
             case 'v': {
-                print_path = 1;
+                find_path = true;
+                break;
+            }
+            case 'q': {
+                quiet = true;
                 break;
             }
             case '?': {
@@ -841,7 +870,7 @@ static int builtin_command(parser_t &parser, io_streams_t &streams, wchar_t **ar
         }
     }
 
-    if (!print_path) {
+    if (!find_path) {
         builtin_print_help(parser, streams, argv[0], streams.out);
         return STATUS_BUILTIN_ERROR;
     }
@@ -852,7 +881,7 @@ static int builtin_command(parser_t &parser, io_streams_t &streams, wchar_t **ar
         const wchar_t *command_name = argv[idx];
         wcstring path;
         if (path_get_path(command_name, &path)) {
-            streams.out.append_format(L"%ls\n", path.c_str());
+            if (!quiet) streams.out.append_format(L"%ls\n", path.c_str());
             ++found;
         }
     }
@@ -915,7 +944,7 @@ static wcstring functions_def(const wcstring &name) {
     function_get_definition(name, &def);
     event_t search(EVENT_ANY);
     search.function_name = name;
-    std::vector ev;
+    std::vector> ev;
     event_get(search, &ev);
 
     out.append(L"function ");
@@ -938,7 +967,7 @@ static wcstring functions_def(const wcstring &name) {
     }
 
     for (size_t i = 0; i < ev.size(); i++) {
-        event_t *next = ev.at(i);
+        const event_t *next = ev.at(i).get();
         switch (next->type) {
             case EVENT_SIGNAL: {
                 append_format(out, L" --on-signal %ls", sig2wcs(next->param1.signal));
@@ -1016,6 +1045,41 @@ static wcstring functions_def(const wcstring &name) {
     return out;
 }
 
+static int report_function_metadata(const wchar_t *funcname, bool verbose, io_streams_t &streams,
+                                    bool metadata_as_comments) {
+    const wchar_t *path = L"n/a";
+    const wchar_t *autoloaded = L"n/a";
+    const wchar_t *shadows_scope = L"n/a";
+    int line_number = 0;
+
+    if (function_exists(funcname)) {
+        path = function_get_definition_file(funcname);
+        if (path) {
+            autoloaded = function_is_autoloaded(funcname) ? L"autoloaded" : L"not-autoloaded";
+            line_number = function_get_definition_offset(funcname);
+        } else {
+            path = L"stdin";
+        }
+        shadows_scope =
+            function_get_shadow_scope(funcname) ? L"scope-shadowing" : L"no-scope-shadowing";
+    }
+
+    if (metadata_as_comments) {
+        if (wcscmp(path, L"stdin")) {
+            streams.out.append_format(L"# Defined in %ls @ line %d\n", path, line_number);
+        }
+    } else {
+        streams.out.append_format(L"%ls\n", path);
+        if (verbose) {
+            streams.out.append_format(L"%ls\n", autoloaded);
+            streams.out.append_format(L"%d\n", line_number);
+            streams.out.append_format(L"%ls\n", shadows_scope);
+        }
+    }
+
+    return STATUS_BUILTIN_OK;
+}
+
 /// The functions builtin, used for listing and erasing functions.
 static int builtin_functions(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
     wgetopter_t w;
@@ -1029,17 +1093,20 @@ static int builtin_functions(parser_t &parser, io_streams_t &streams, wchar_t **
     int res = STATUS_BUILTIN_OK;
     int query = 0;
     int copy = 0;
+    bool report_metadata = false;
+    bool verbose = false;
 
     static const struct woption long_options[] = {
-        {L"erase", no_argument, 0, 'e'}, {L"description", required_argument, 0, 'd'},
-        {L"names", no_argument, 0, 'n'}, {L"all", no_argument, 0, 'a'},
-        {L"help", no_argument, 0, 'h'},  {L"query", no_argument, 0, 'q'},
-        {L"copy", no_argument, 0, 'c'},  {0, 0, 0, 0}};
+        {L"erase", no_argument, NULL, 'e'},   {L"description", required_argument, NULL, 'd'},
+        {L"names", no_argument, NULL, 'n'},   {L"all", no_argument, NULL, 'a'},
+        {L"help", no_argument, NULL, 'h'},    {L"query", no_argument, NULL, 'q'},
+        {L"copy", no_argument, NULL, 'c'},    {L"metadata", no_argument, NULL, 'm'},
+        {L"verbose", no_argument, NULL, 'v'}, {NULL, 0, NULL, 0}};
 
     while (1) {
         int opt_index = 0;
 
-        int opt = w.wgetopt_long(argc, argv, L"ed:nahqc", long_options, &opt_index);
+        int opt = w.wgetopt_long(argc, argv, L"ed:mnahqcv", long_options, &opt_index);
         if (opt == -1) break;
 
         switch (opt) {
@@ -1050,10 +1117,18 @@ static int builtin_functions(parser_t &parser, io_streams_t &streams, wchar_t **
                 builtin_print_help(parser, streams, argv[0], streams.err);
                 return STATUS_BUILTIN_ERROR;
             }
+            case 'v': {
+                verbose = true;
+                break;
+            }
             case 'e': {
                 erase = 1;
                 break;
             }
+            case 'm': {
+                report_metadata = true;
+                break;
+            }
             case 'd': {
                 desc = w.woptarg;
                 break;
@@ -1122,8 +1197,16 @@ static int builtin_functions(parser_t &parser, io_streams_t &streams, wchar_t **
         }
 
         function_set_desc(func, desc);
-
         return STATUS_BUILTIN_OK;
+    } else if (report_metadata) {
+        if (argc - w.woptind != 1) {
+            streams.err.append_format(
+                _(L"%ls: Expected exactly one function name for --metadata\n"), argv[0]);
+            return STATUS_BUILTIN_ERROR;
+        }
+
+        const wchar_t *funcname = argv[w.woptind];
+        return report_function_metadata(funcname, verbose, streams, false);
     } else if (list || (argc == w.woptind)) {
         int is_screen = !streams.out_is_redirected && isatty(STDOUT_FILENO);
         size_t i;
@@ -1169,7 +1252,7 @@ static int builtin_functions(parser_t &parser, io_streams_t &streams, wchar_t **
             return STATUS_BUILTIN_ERROR;
         }
 
-        if ((wcsfuncname(new_func) != 0) || parser_keywords_is_reserved(new_func)) {
+        if (!wcsfuncname(new_func) || parser_keywords_is_reserved(new_func)) {
             streams.err.append_format(_(L"%ls: Illegal function name '%ls'\n"), argv[0],
                                       new_func.c_str());
             builtin_print_help(parser, streams, argv[0], streams.err);
@@ -1196,8 +1279,9 @@ static int builtin_functions(parser_t &parser, io_streams_t &streams, wchar_t **
         else {
             if (!query) {
                 if (i != w.woptind) streams.out.append(L"\n");
-
-                streams.out.append(functions_def(argv[i]));
+                const wchar_t *funcname = argv[w.woptind];
+                report_function_metadata(funcname, verbose, streams, true);
+                streams.out.append(functions_def(funcname));
             }
         }
     }
@@ -1403,7 +1487,7 @@ static int builtin_echo(parser_t &parser, io_streams_t &streams, wchar_t **argv)
                         break;
                     }
                     case L'e': {
-                        wc = L'\x1B';
+                        wc = L'\e';
                         break;
                     }
                     case L'f': {
@@ -1486,27 +1570,40 @@ static int builtin_pwd(parser_t &parser, io_streams_t &streams, wchar_t **argv)
     return STATUS_BUILTIN_OK;
 }
 
-/// Defines and adds a function to the function set. Calls into `function.cpp`
-/// to perform all heavy lifting.
-///
-/// @param  c_args
-///    The arguments. Should NOT contain 'function' as the first argument as the
-///    parser treats it as a keyword.
-/// @param  contents
-///    The function definition string
-/// @param  definition_line_offset
-///    The definition line offset
-///
-/// @return
-///    Returns 0 on success.
-///
+static int validate_function_name(int argc, const wchar_t *const *argv, wcstring &function_name,
+                                  const wchar_t *cmd, wcstring *out_err) {
+    if (argc < 2) {
+        // This is currently impossible but let's be paranoid.
+        append_format(*out_err, _(L"%ls: Expected function name"), cmd);
+        return STATUS_BUILTIN_ERROR;
+    }
+
+    function_name = argv[1];
+    if (!wcsfuncname(function_name)) {
+        append_format(*out_err, _(L"%ls: Illegal function name '%ls'"), cmd, function_name.c_str());
+        return STATUS_BUILTIN_ERROR;
+    }
+
+    if (parser_keywords_is_reserved(function_name)) {
+        append_format(
+            *out_err,
+            _(L"%ls: The name '%ls' is reserved,\nand can not be used as a function name"), cmd,
+            function_name.c_str());
+        return STATUS_BUILTIN_ERROR;
+    }
+
+    return STATUS_BUILTIN_OK;
+}
+
+/// Define a function. Calls into `function.cpp` to perform the heavy lifting of defining a
+/// function.
 int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_list_t &c_args,
                      const wcstring &contents, int definition_line_offset, wcstring *out_err) {
-    wgetopter_t w;
     assert(out_err != NULL);
 
-    // wgetopt expects 'function' as the first argument. Make a new wcstring_list with that
-    // property.
+    // The wgetopt function expects 'function' as the first argument. Make a new wcstring_list with
+    // that property. This is needed because this builtin has a different signature than the other
+    // builtins.
     wcstring_list_t args;
     args.push_back(L"function");
     args.insert(args.end(), c_args.begin(), c_args.end());
@@ -1514,70 +1611,61 @@ int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_lis
     // Hackish const_cast matches the one in builtin_run.
     const null_terminated_array_t argv_array(args);
     wchar_t **argv = const_cast(argv_array.get());
+    wchar_t *cmd = argv[0];
     int argc = builtin_count_args(argv);
-    int res = STATUS_BUILTIN_OK;
-    wchar_t *desc = 0;
+    wchar_t *desc = NULL;
+    bool shadow_scope = true;
+    wcstring function_name;
     std::vector events;
-    bool has_named_arguments = false;
     wcstring_list_t named_arguments;
     wcstring_list_t inherit_vars;
-    bool shadow_scope = true;
-
     wcstring_list_t wrap_targets;
 
-    // If -a/--argument-names is specified before the function name, then the function name is the
-    // last positional, e.g. `function -a arg1 arg2 name`. If it is specified after the function
-    // name (or not specified at all) then the function name is the first positional. This is the
-    // common case.
-    bool name_is_first_positional = true;
-    wcstring_list_t positionals;
+    // This command is atypical in using the "+" (REQUIRE_ORDER) option for flag parsing.
+    // This is needed due to the semantics of the -a/--argument-names flag.
+    const wchar_t *short_options = L"+:a:d:e:hj:p:s:v:w:SV:";
+    const struct woption long_options[] = {{L"description", required_argument, NULL, 'd'},
+                                           {L"on-signal", required_argument, NULL, 's'},
+                                           {L"on-job-exit", required_argument, NULL, 'j'},
+                                           {L"on-process-exit", required_argument, NULL, 'p'},
+                                           {L"on-variable", required_argument, NULL, 'v'},
+                                           {L"on-event", required_argument, NULL, 'e'},
+                                           {L"wraps", required_argument, NULL, 'w'},
+                                           {L"help", no_argument, NULL, 'h'},
+                                           {L"argument-names", required_argument, NULL, 'a'},
+                                           {L"no-scope-shadowing", no_argument, NULL, 'S'},
+                                           {L"inherit-variable", required_argument, NULL, 'V'},
+                                           {NULL, 0, NULL, 0}};
 
-    const struct woption long_options[] = {{L"description", required_argument, 0, 'd'},
-                                           {L"on-signal", required_argument, 0, 's'},
-                                           {L"on-job-exit", required_argument, 0, 'j'},
-                                           {L"on-process-exit", required_argument, 0, 'p'},
-                                           {L"on-variable", required_argument, 0, 'v'},
-                                           {L"on-event", required_argument, 0, 'e'},
-                                           {L"wraps", required_argument, 0, 'w'},
-                                           {L"help", no_argument, 0, 'h'},
-                                           {L"argument-names", no_argument, 0, 'a'},
-                                           {L"no-scope-shadowing", no_argument, 0, 'S'},
-                                           {L"inherit-variable", required_argument, 0, 'V'},
-                                           {0, 0, 0, 0}};
+    // A valid function name has to be the first argument.
+    if (validate_function_name(argc, argv, function_name, cmd, out_err) == STATUS_BUILTIN_OK) {
+        argv++;
+        argc--;
+    } else {
+        return STATUS_BUILTIN_ERROR;
+    }
 
-    while (res == STATUS_BUILTIN_OK) {
-        int opt_index = 0;
-
-        // The leading - here specifies RETURN_IN_ORDER.
-        int opt = w.wgetopt_long(argc, argv, L"-d:s:j:p:v:e:w:haSV:", long_options, &opt_index);
-        if (opt == -1) break;
+    int opt;
+    wgetopter_t w;
+    while ((opt = w.wgetopt_long(argc, argv, short_options, long_options, NULL)) != -1) {
         switch (opt) {
-            case 0: {
-                if (long_options[opt_index].flag != 0) break;
-                append_format(*out_err, BUILTIN_ERR_UNKNOWN, argv[0], long_options[opt_index].name);
-                res = STATUS_BUILTIN_ERROR;
-                break;
-            }
             case 'd': {
                 desc = w.woptarg;
                 break;
             }
             case 's': {
                 int sig = wcs2sig(w.woptarg);
-                if (sig < 0) {
-                    append_format(*out_err, _(L"%ls: Unknown signal '%ls'"), argv[0], w.woptarg);
-                    res = STATUS_BUILTIN_ERROR;
-                    break;
+                if (sig == -1) {
+                    append_format(*out_err, _(L"%ls: Unknown signal '%ls'"), cmd, w.woptarg);
+                    return STATUS_BUILTIN_ERROR;
                 }
                 events.push_back(event_t::signal_event(sig));
                 break;
             }
             case 'v': {
                 if (wcsvarname(w.woptarg)) {
-                    append_format(*out_err, _(L"%ls: Invalid variable name '%ls'"), argv[0],
-                                  w.woptarg);
-                    res = STATUS_BUILTIN_ERROR;
-                    break;
+                    append_format(*out_err, _(L"%ls: Invalid variable name '%ls'"), cmd, w.woptarg);
+                    return STATUS_BUILTIN_ERROR;
                 }
 
                 events.push_back(event_t::variable_event(w.woptarg));
@@ -1590,11 +1678,10 @@ int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_lis
             case 'j':
             case 'p': {
                 pid_t pid;
-                wchar_t *end;
                 event_t e(EVENT_ANY);
 
                 if ((opt == 'j') && (wcscasecmp(w.woptarg, L"caller") == 0)) {
-                    int job_id = -1;
+                    job_id_t job_id = -1;
 
                     if (is_subshell) {
                         size_t block_idx = 0;
@@ -1614,35 +1701,27 @@ int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_lis
 
                     if (job_id == -1) {
                         append_format(*out_err,
-                                      _(L"%ls: Cannot find calling job for event handler"),
-                                      argv[0]);
-                        res = STATUS_BUILTIN_ERROR;
-                    } else {
-                        e.type = EVENT_JOB_ID;
-                        e.param1.job_id = job_id;
+                                      _(L"%ls: Cannot find calling job for event handler"), cmd);
+                        return STATUS_BUILTIN_ERROR;
                     }
+                    e.type = EVENT_JOB_ID;
+                    e.param1.job_id = job_id;
                 } else {
-                    errno = 0;
-                    pid = fish_wcstoi(w.woptarg, &end, 10);
-                    if (errno || !end || *end) {
-                        append_format(*out_err, _(L"%ls: Invalid process id %ls"), argv[0],
+                    pid = fish_wcstoi(w.woptarg);
+                    if (errno || pid < 0) {
+                        append_format(*out_err, _(L"%ls: Invalid process id '%ls'"), cmd,
                                       w.woptarg);
-                        res = STATUS_BUILTIN_ERROR;
-                        break;
+                        return STATUS_BUILTIN_ERROR;
                     }
 
                     e.type = EVENT_EXIT;
                     e.param1.pid = (opt == 'j' ? -1 : 1) * abs(pid);
                 }
-                if (res == STATUS_BUILTIN_OK) {
-                    events.push_back(e);
-                }
+                events.push_back(e);
                 break;
             }
             case 'a': {
-                has_named_arguments = true;
-                // The function name is the first positional unless -a comes before all positionals.
-                name_is_first_positional = !positionals.empty();
+                named_arguments.push_back(w.woptarg);
                 break;
             }
             case 'S': {
@@ -1655,98 +1734,46 @@ int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_lis
             }
             case 'V': {
                 if (wcsvarname(w.woptarg)) {
-                    append_format(*out_err, _(L"%ls: Invalid variable name '%ls'"), argv[0],
-                                  w.woptarg);
-                    res = STATUS_BUILTIN_ERROR;
-                    break;
+                    append_format(*out_err, _(L"%ls: Invalid variable name '%ls'"), cmd, w.woptarg);
+                    return STATUS_BUILTIN_ERROR;
                 }
 
                 inherit_vars.push_back(w.woptarg);
                 break;
             }
             case 'h': {
-                builtin_print_help(parser, streams, argv[0], streams.out);
+                builtin_print_help(parser, streams, cmd, streams.out);
                 return STATUS_BUILTIN_OK;
             }
-            case 1: {
-                assert(w.woptarg != NULL);
-                positionals.push_back(w.woptarg);
-                break;
+            case ':': {
+                streams.err.append_format(BUILTIN_ERR_MISSING, cmd, argv[w.woptind - 1]);
+                return STATUS_BUILTIN_ERROR;
             }
             case '?': {
-                builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
-                res = STATUS_BUILTIN_ERROR;
-                break;
+                builtin_unknown_option(parser, streams, cmd, argv[w.woptind - 1]);
+                return STATUS_BUILTIN_ERROR;
             }
             default: {
-                DIE("unexpected opt");
+                DIE("unexpected retval from wgetopt_long");
                 break;
             }
         }
     }
 
-    if (res != STATUS_BUILTIN_OK) {
-        return STATUS_BUILTIN_ERROR;
-    }
-
-    // Determine the function name, and remove it from the list of positionals.
-    wcstring function_name;
-    bool name_is_missing = positionals.empty();
-    if (!name_is_missing) {
-        if (name_is_first_positional) {
-            function_name = positionals.front();
-            positionals.erase(positionals.begin());
-        } else {
-            function_name = positionals.back();
-            positionals.erase(positionals.end() - 1);
-        }
-    }
-
-    if (name_is_missing) {
-        append_format(*out_err, _(L"%ls: Expected function name"), argv[0]);
-        res = STATUS_BUILTIN_ERROR;
-    } else if (wcsfuncname(function_name)) {
-        append_format(*out_err, _(L"%ls: Illegal function name '%ls'"), argv[0],
-                      function_name.c_str());
-
-        res = STATUS_BUILTIN_ERROR;
-    } else if (parser_keywords_is_reserved(function_name)) {
-        append_format(
-            *out_err,
-            _(L"%ls: The name '%ls' is reserved,\nand can not be used as a function name"), argv[0],
-            function_name.c_str());
-
-        res = STATUS_BUILTIN_ERROR;
-    } else if (function_name.empty()) {
-        append_format(*out_err, _(L"%ls: No function name given"), argv[0]);
-        res = STATUS_BUILTIN_ERROR;
-    } else {
-        if (has_named_arguments) {
-            // All remaining positionals are named arguments.
-            named_arguments.swap(positionals);
-            for (size_t i = 0; i < named_arguments.size(); i++) {
-                if (wcsvarname(named_arguments.at(i))) {
-                    append_format(*out_err, _(L"%ls: Invalid variable name '%ls'"), argv[0],
-                                  named_arguments.at(i).c_str());
-                    res = STATUS_BUILTIN_ERROR;
-                    break;
-                }
+    if (argc != w.woptind) {
+        if (named_arguments.size()) {
+            for (int i = w.woptind; i < argc; i++) {
+                named_arguments.push_back(argv[i]);
             }
-        } else if (!positionals.empty()) {
-            // +1 because we already got the function name.
-            append_format(*out_err, _(L"%ls: Expected one argument, got %lu"), argv[0],
-                          (unsigned long)(positionals.size() + 1));
-            res = STATUS_BUILTIN_ERROR;
+        } else {
+            append_format(*out_err, _(L"%ls: Unexpected positional argument '%ls'"), cmd,
+                          argv[w.woptind]);
+            return STATUS_BUILTIN_ERROR;
         }
     }
 
-    if (res != STATUS_BUILTIN_OK) {
-        return res;
-    }
-
-    // Here we actually define the function!
+    // We have what we need to actually define the function.
     function_data_t d;
-
     d.name = function_name;
     if (desc) d.description = desc;
     d.events.swap(events);
@@ -1762,25 +1789,31 @@ int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_lis
     d.definition = contents.c_str();
     function_add(d, parser, definition_line_offset);
 
-    // Handle wrap targets.
+    // Handle wrap targets by creating the appropriate completions.
     for (size_t w = 0; w < wrap_targets.size(); w++) {
         complete_add_wrapper(function_name, wrap_targets.at(w));
     }
 
-    return res;
+    return STATUS_BUILTIN_OK;
 }
 
 /// The random builtin generates random numbers.
 static int builtin_random(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
-    static int seeded = 0;
-    static struct drand48_data seed_buffer;
-
-    int argc = builtin_count_args(argv);
+    static bool seeded = false;
+    static std::minstd_rand engine;
+    if (!seeded) {
+        // seed engine with 2*32 bits of random data
+        // for the 64 bits of internal state of minstd_rand
+        std::random_device rd;
+        std::seed_seq seed{rd(), rd()};
+        engine.seed(seed);
+        seeded = true;
+    }
 
     wgetopter_t w;
-
-    static const struct woption long_options[] = {{L"help", no_argument, 0, 'h'}, {0, 0, 0, 0}};
-
+    int argc = builtin_count_args(argv);
+    static const struct woption long_options[] = {{L"help", no_argument, NULL, 'h'},
+                                                  {NULL, 0, NULL, 0}};
     while (1) {
         int opt_index = 0;
 
@@ -1797,7 +1830,7 @@ static int builtin_random(parser_t &parser, io_streams_t &streams, wchar_t **arg
             }
             case 'h': {
                 builtin_print_help(parser, streams, argv[0], streams.out);
-                break;
+                return STATUS_BUILTIN_OK;
             }
             case '?': {
                 builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
@@ -1811,41 +1844,260 @@ static int builtin_random(parser_t &parser, io_streams_t &streams, wchar_t **arg
     }
 
     int arg_count = argc - w.woptind;
-    if (arg_count == 0) {
-        long res;
-        if (!seeded) {
-            seeded = 1;
-            srand48_r(time(0), &seed_buffer);
-        }
-        lrand48_r(&seed_buffer, &res);
-        streams.out.append_format(L"%ld\n", res % 32768);
-    } else if (arg_count == 1) {
-        long foo;
-        wchar_t *end = 0;
-
-        errno = 0;
-        foo = wcstol(argv[w.woptind], &end, 10);
-        if (errno || *end) {
-            streams.err.append_format(_(L"%ls: Seed value '%ls' is not a valid number\n"), argv[0],
-                                      argv[w.woptind]);
+    long long start, end;
+    unsigned long long step;
+    bool choice = false;
+    if (arg_count >= 1 && !wcscmp(argv[w.woptind], L"choice")) {
+        if (arg_count == 1) {
+            streams.err.append_format(L"%ls: nothing to choose from\n", argv[0]);
             return STATUS_BUILTIN_ERROR;
         }
-        seeded = 1;
-        srand48_r(foo, &seed_buffer);
+        choice = true;
+        start = 1;
+        step = 1;
+        end = arg_count - 1;
     } else {
-        streams.err.append_format(_(L"%ls: Expected zero or one argument, got %d\n"), argv[0],
-                                  argc - w.woptind);
-        builtin_print_help(parser, streams, argv[0], streams.err);
+        bool parse_error = false;
+        auto parse_ll = [&](const wchar_t *str) {
+            long long ll = fish_wcstoll(str);
+            if (errno) {
+                streams.err.append_format(L"%ls: %ls is not a valid integer\n", argv[0], str);
+                parse_error = true;
+            }
+            return ll;
+        };
+        auto parse_ull = [&](const wchar_t *str) {
+            unsigned long long ull = fish_wcstoull(str);
+            if (errno) {
+                streams.err.append_format(L"%ls: %ls is not a valid integer\n", argv[0], str);
+                parse_error = true;
+            }
+            return ull;
+        };
+        if (arg_count == 0) {
+            start = 0;
+            end = 32767;
+            step = 1;
+        } else if (arg_count == 1) {
+            long long seed = parse_ll(argv[w.woptind]);
+            if (parse_error) return STATUS_BUILTIN_ERROR;
+            engine.seed(static_cast(seed));
+            return STATUS_BUILTIN_OK;
+        } else if (arg_count == 2) {
+            start = parse_ll(argv[w.woptind]);
+            step = 1;
+            end = parse_ll(argv[w.woptind + 1]);
+        } else if (arg_count == 3) {
+            start = parse_ll(argv[w.woptind]);
+            step = parse_ull(argv[w.woptind + 1]);
+            end = parse_ll(argv[w.woptind + 2]);
+        } else {
+            streams.err.append_format(BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]);
+            return STATUS_BUILTIN_ERROR;
+        }
+
+        if (parse_error) {
+            return STATUS_BUILTIN_ERROR;
+        } else if (start >= end) {
+            streams.err.append_format(L"%ls: END must be greater than START\n", argv[0]);
+            return STATUS_BUILTIN_ERROR;
+        } else if (step == 0) {
+            streams.err.append_format(L"%ls: STEP must be a positive integer\n", argv[0]);
+            return STATUS_BUILTIN_ERROR;
+        }
+    }
+
+    // only for negative argument
+    auto safe_abs = [](long long ll) -> unsigned long long {
+        return -static_cast(ll);
+    };
+    long long real_end;
+    if (start >= 0 || end < 0) {
+        // 0 <= start <= end
+        long long diff = end - start;
+        // 0 <= diff <= LL_MAX
+        real_end = start + static_cast(diff / step);
+    } else {
+        // start < 0 <= end
+        unsigned long long abs_start = safe_abs(start);
+        unsigned long long diff = (end + abs_start);
+        real_end = diff / step - abs_start;
+    }
+
+    if (!choice && start == real_end) {
+        streams.err.append_format(L"%ls: range contains only one possible value\n", argv[0]);
         return STATUS_BUILTIN_ERROR;
     }
+
+    std::uniform_int_distribution dist(start, real_end);
+    long long random = dist(engine);
+    long long result;
+    if (start >= 0) {
+        // 0 <= start <= random <= end
+        long long diff = random - start;
+        // 0 < step * diff <= end - start <= LL_MAX
+        result = start + static_cast(diff * step);
+    } else if (random < 0) {
+        // start <= random < 0
+        long long diff = random - start;
+        result = diff * step - safe_abs(start);
+    } else {
+        // start < 0 <= random
+        unsigned long long abs_start = safe_abs(start);
+        unsigned long long diff = (random + abs_start);
+        result = diff * step - abs_start;
+    }
+
+    if (choice) {
+        streams.out.append_format(L"%ls\n", argv[w.woptind + result]);
+    } else {
+        streams.out.append_format(L"%lld\n", result);
+    }
     return STATUS_BUILTIN_OK;
 }
 
+/// Read from the tty. This is only valid when the stream is stdin and it is attached to a tty and
+/// we weren't asked to split on null characters.
+static int read_interactive(wcstring &buff, int nchars, bool shell, const wchar_t *mode_name,
+                            const wchar_t *prompt, const wchar_t *right_prompt,
+                            const wchar_t *commandline) {
+    int exit_res = STATUS_BUILTIN_OK;
+    const wchar_t *line;
+
+    reader_push(mode_name);
+    reader_set_left_prompt(prompt);
+    reader_set_right_prompt(right_prompt);
+    if (shell) {
+        reader_set_complete_function(&complete);
+        reader_set_highlight_function(&highlight_shell);
+        reader_set_test_function(&reader_shell_test);
+    }
+    // No autosuggestions or abbreviations in builtin_read.
+    reader_set_allow_autosuggesting(false);
+    reader_set_expand_abbreviations(false);
+    reader_set_exit_on_interrupt(true);
+
+    reader_set_buffer(commandline, wcslen(commandline));
+    proc_push_interactive(1);
+
+    event_fire_generic(L"fish_prompt");
+    line = reader_readline(nchars);
+    proc_pop_interactive();
+    if (line) {
+        if (0 < nchars && (size_t)nchars < wcslen(line)) {
+            // Line may be longer than nchars if a keybinding used `commandline -i`
+            // note: we're deliberately throwing away the tail of the commandline.
+            // It shouldn't be unread because it was produced with `commandline -i`,
+            // not typed.
+            buff = wcstring(line, nchars);
+        } else {
+            buff = wcstring(line);
+        }
+    } else {
+        exit_res = STATUS_BUILTIN_ERROR;
+    }
+    reader_pop();
+    return exit_res;
+}
+
+/// Bash uses 128 bytes for its chunk size. Very informal testing I did suggested that a smaller
+/// chunk size performed better. However, we're going to use the bash value under the assumption
+/// they've done more extensive testing.
+#define READ_CHUNK_SIZE 128
+
+/// Read from the fd in chunks until we see newline or null, as appropriate, is seen. This is only
+/// used when the fd is seekable (so not from a tty or pipe) and we're not reading a specific number
+/// of chars.
+/// Returns an exit status
+static int read_in_chunks(int fd, wcstring &buff, bool split_null) {
+    int exit_res = STATUS_BUILTIN_OK;
+    std::string str;
+    bool eof = false;
+    bool finished = false;
+
+    while (!finished) {
+        char inbuf[READ_CHUNK_SIZE];
+        long bytes_read = read_blocked(fd, inbuf, READ_CHUNK_SIZE);
+
+        if (bytes_read <= 0) {
+            eof = true;
+            break;
+        }
+
+        const char *end = std::find(inbuf, inbuf + bytes_read, split_null ? L'\0' : L'\n');
+        long bytes_consumed = end - inbuf;  // note: must be signed for use in lseek
+        assert(bytes_consumed <= bytes_read);
+        str.append(inbuf, bytes_consumed);
+        if (bytes_consumed < bytes_read) {
+            // We found a splitter
+            // +1 because we need to treat the splitter as consumed, but not append it to the string
+            CHECK(lseek(fd, bytes_consumed - bytes_read + 1, SEEK_CUR) != -1, STATUS_BUILTIN_ERROR)
+            finished = true;
+        }
+    }
+
+    buff = str2wcstring(str);
+    if (buff.empty() && eof) {
+        exit_res = STATUS_BUILTIN_ERROR;
+    }
+
+    return exit_res;
+}
+
+/// Read from the fd on char at a time until we've read the requested number of characters or a
+/// newline or null, as appropriate, is seen. This is inefficient so should only be used when the
+/// fd is not seekable.
+static int read_one_char_at_a_time(int fd, wcstring &buff, int nchars, bool split_null) {
+    int exit_res = STATUS_BUILTIN_OK;
+    bool eof = false;
+
+    while (true) {
+        bool finished = false;
+        wchar_t res = 0;
+        mbstate_t state = {};
+
+        while (!finished) {
+            char b;
+            if (read_blocked(fd, &b, 1) <= 0) {
+                eof = true;
+                break;
+            }
+
+            if (MB_CUR_MAX == 1) {
+                res = (unsigned char)b;
+                finished = true;
+            } else {
+                size_t sz = mbrtowc(&res, &b, 1, &state);
+                if (sz == (size_t)-1) {
+                    memset(&state, 0, sizeof(state));
+                } else if (sz != (size_t)-2) {
+                    finished = true;
+                }
+            }
+        }
+
+        if (eof) break;
+        if (!split_null && res == L'\n') break;
+        if (split_null && res == L'\0') break;
+
+        buff.push_back(res);
+        if (0 < nchars && (size_t)nchars <= buff.size()) {
+            break;
+        }
+    }
+
+    if (buff.empty() && eof) {
+        exit_res = STATUS_BUILTIN_ERROR;
+    }
+
+    return exit_res;
+}
+
 /// The read builtin. Reads from stdin and stores the values in environment variables.
 static int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
     wgetopter_t w;
     wcstring buff;
-    int i, argc = builtin_count_args(argv);
+    int argc = builtin_count_args(argv);
     int place = ENV_USER;
     const wchar_t *prompt = DEFAULT_READ_PROMPT;
     const wchar_t *right_prompt = L"";
@@ -1853,9 +2105,8 @@ static int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv)
     int exit_res = STATUS_BUILTIN_OK;
     const wchar_t *mode_name = READ_MODE_NAME;
     int nchars = 0;
-    wchar_t *end;
-    int shell = 0;
-    int array = 0;
+    bool shell = false;
+    bool array = false;
     bool split_null = false;
 
     while (1) {
@@ -1925,9 +2176,8 @@ static int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv)
                 break;
             }
             case L'n': {
-                errno = 0;
-                nchars = fish_wcstoi(w.woptarg, &end, 10);
-                if (errno || *end != 0) {
+                nchars = fish_wcstoi(w.woptarg);
+                if (errno) {
                     if (errno == ERANGE) {
                         streams.err.append_format(_(L"%ls: Argument '%ls' is out of range\n"),
                                                   argv[0], w.woptarg);
@@ -1943,11 +2193,11 @@ static int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv)
                 break;
             }
             case 's': {
-                shell = 1;
+                shell = true;
                 break;
             }
             case 'a': {
-                array = 1;
+                array = true;
                 break;
             }
             case L'z': {
@@ -1994,113 +2244,32 @@ static int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv)
     }
 
     // Verify all variable names.
-    for (i = w.woptind; i < argc; i++) {
-        wchar_t *src;
-
-        if (!wcslen(argv[i])) {
-            streams.err.append_format(BUILTIN_ERR_VARNAME_ZERO, argv[0]);
+    wcstring errstr;
+    for (int i = w.woptind; i < argc; i++) {
+        if (!builtin_is_valid_varname(argv[i], errstr, argv[0])) {
+            streams.err.append(errstr);
+            builtin_print_help(parser, streams, argv[0], streams.err);
             return STATUS_BUILTIN_ERROR;
         }
-
-        for (src = argv[i]; *src; src++) {
-            if ((!iswalnum(*src)) && (*src != L'_')) {
-                streams.err.append_format(BUILTIN_ERR_VARCHAR, argv[0], *src);
-                builtin_print_help(parser, streams, argv[0], streams.err);
-                return STATUS_BUILTIN_ERROR;
-            }
-        }
     }
 
-    // The call to reader_readline may change woptind, so we save it away here.
-    i = w.woptind;
-
-    // Check if we should read interactively using \c reader_readline().
-    if (isatty(0) && streams.stdin_fd == STDIN_FILENO && !split_null) {
-        const wchar_t *line;
-
-        reader_push(mode_name);
-        reader_set_left_prompt(prompt);
-        reader_set_right_prompt(right_prompt);
-        if (shell) {
-            reader_set_complete_function(&complete);
-            reader_set_highlight_function(&highlight_shell);
-            reader_set_test_function(&reader_shell_test);
-        }
-        // No autosuggestions or abbreviations in builtin_read.
-        reader_set_allow_autosuggesting(false);
-        reader_set_expand_abbreviations(false);
-        reader_set_exit_on_interrupt(true);
-
-        reader_set_buffer(commandline, wcslen(commandline));
-        proc_push_interactive(1);
-
-        event_fire_generic(L"fish_prompt");
-        line = reader_readline(nchars);
-        proc_pop_interactive();
-        if (line) {
-            if (0 < nchars && (size_t)nchars < wcslen(line)) {
-                // Line may be longer than nchars if a keybinding used `commandline -i`
-                // note: we're deliberately throwing away the tail of the commandline.
-                // It shouldn't be unread because it was produced with `commandline -i`,
-                // not typed.
-                buff = wcstring(line, nchars);
-            } else {
-                buff = wcstring(line);
-            }
-        } else {
-            exit_res = STATUS_BUILTIN_ERROR;
-        }
-        reader_pop();
+    // TODO: Determine if the original set of conditions for interactive reads should be reinstated:
+    // if (isatty(0) && streams.stdin_fd == STDIN_FILENO && !split_null) {
+    int stream_stdin_is_a_tty = isatty(streams.stdin_fd);
+    if (stream_stdin_is_a_tty && !split_null) {
+        // We should read interactively using reader_readline(). This does not support splitting on
+        // null. The call to reader_readline may change woptind, so we save and restore it.
+        int saved_woptind = w.woptind;
+        exit_res =
+            read_interactive(buff, nchars, shell, mode_name, prompt, right_prompt, commandline);
+        w.woptind = saved_woptind;
+    } else if (!nchars && !stream_stdin_is_a_tty && lseek(streams.stdin_fd, 0, SEEK_CUR) != -1) {
+        exit_res = read_in_chunks(streams.stdin_fd, buff, split_null);
     } else {
-        int eof = 0;
-
-        buff.clear();
-
-        while (1) {
-            int finished = 0;
-            wchar_t res = 0;
-            mbstate_t state = {};
-
-            while (!finished) {
-                char b;
-                if (read_blocked(streams.stdin_fd, &b, 1) <= 0) {
-                    eof = 1;
-                    break;
-                }
-
-                if (MB_CUR_MAX == 1)  // single-byte locale
-                {
-                    res = (unsigned char)b;
-                    finished = 1;
-                } else {
-                    size_t sz = mbrtowc(&res, &b, 1, &state);
-                    if (sz == (size_t)-1) {
-                        memset(&state, 0, sizeof(state));
-                    } else if (sz != (size_t)-2) {
-                        finished = 1;
-                    }
-                }
-            }
-
-            if (eof) break;
-
-            if (!split_null && res == L'\n') break;
-
-            if (split_null && res == L'\0') break;
-
-            buff.push_back(res);
-
-            if (0 < nchars && (size_t)nchars <= buff.size()) {
-                break;
-            }
-        }
-
-        if (buff.empty() && eof) {
-            exit_res = STATUS_BUILTIN_ERROR;
-        }
+        exit_res = read_one_char_at_a_time(streams.stdin_fd, buff, nchars, split_null);
     }
 
-    if (i == argc || exit_res != STATUS_BUILTIN_OK) {
+    if (w.woptind == argc || exit_res != STATUS_BUILTIN_OK) {
         return exit_res;
     }
 
@@ -2117,21 +2286,21 @@ static int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv)
                     *out = *it;
                     out += 2;
                 }
-                env_set(argv[i], chars.c_str(), place);
+                env_set(argv[w.woptind], chars.c_str(), place);
             } else {
-                env_set(argv[i], NULL, place);
+                env_set(argv[w.woptind], NULL, place);
             }
         } else {  // not array
             size_t j = 0;
-            for (; i + 1 < argc; ++i) {
+            for (; w.woptind + 1 < argc; ++w.woptind) {
                 if (j < bufflen) {
                     wchar_t buffer[2] = {buff[j++], 0};
-                    env_set(argv[i], buffer, place);
+                    env_set(argv[w.woptind], buffer, place);
                 } else {
-                    env_set(argv[i], L"", place);
+                    env_set(argv[w.woptind], L"", place);
                 }
             }
-            if (i < argc) env_set(argv[i], &buff[j], place);
+            if (w.woptind < argc) env_set(argv[w.woptind], &buff[j], place);
         }
     } else if (array) {
         wcstring tokens;
@@ -2144,14 +2313,15 @@ static int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv)
             tokens.append(buff, loc.first, loc.second);
             empty = false;
         }
-        env_set(argv[i], empty ? NULL : tokens.c_str(), place);
+        env_set(argv[w.woptind], empty ? NULL : tokens.c_str(), place);
     } else {  // not array
         wcstring_range loc = wcstring_range(0, 0);
 
-        while (i < argc) {
-            loc = wcstring_tok(buff, (i + 1 < argc) ? ifs : wcstring(), loc);
-            env_set(argv[i], loc.first == wcstring::npos ? L"" : &buff.c_str()[loc.first], place);
-            ++i;
+        while (w.woptind < argc) {
+            loc = wcstring_tok(buff, (w.woptind + 1 < argc) ? ifs : wcstring(), loc);
+            env_set(argv[w.woptind], loc.first == wcstring::npos ? L"" : &buff.c_str()[loc.first],
+                    place);
+            ++w.woptind;
         }
     }
 
@@ -2159,8 +2329,7 @@ static int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv)
 }
 
 enum status_cmd_t {
-    STATUS_NOOP,
-    STATUS_IS_LOGIN,
+    STATUS_IS_LOGIN = 1,
     STATUS_IS_INTERACTIVE,
     STATUS_IS_BLOCK,
     STATUS_IS_COMMAND_SUB,
@@ -2170,73 +2339,35 @@ enum status_cmd_t {
     STATUS_CURRENT_FILENAME,
     STATUS_CURRENT_LINE_NUMBER,
     STATUS_SET_JOB_CONTROL,
-    STATUS_PRINT_STACK_TRACE
+    STATUS_PRINT_STACK_TRACE,
+    STATUS_UNDEF
 };
-
-static status_cmd_t status_string_to_cmd(const wchar_t *status_command) {
-    if (wcscmp(status_command, L"is-login") == 0) {
-        return STATUS_IS_LOGIN;
-    } else if (wcscmp(status_command, L"is-interactive") == 0) {
-        return STATUS_IS_INTERACTIVE;
-    } else if (wcscmp(status_command, L"is-block") == 0) {
-        return STATUS_IS_BLOCK;
-    } else if (wcscmp(status_command, L"is-command-sub") == 0) {
-        return STATUS_IS_COMMAND_SUB;
-    } else if (wcscmp(status_command, L"is-full-job-control") == 0) {
-        return STATUS_IS_FULL_JOB_CTRL;
-    } else if (wcscmp(status_command, L"is-interactive-job-control") == 0) {
-        return STATUS_IS_INTERACTIVE_JOB_CTRL;
-    } else if (wcscmp(status_command, L"is-no-job-control") == 0) {
-        return STATUS_IS_NO_JOB_CTRL;
-    } else if (wcscmp(status_command, L"current-filename") == 0) {
-        return STATUS_CURRENT_FILENAME;
-    } else if (wcscmp(status_command, L"current-line-number") == 0) {
-        return STATUS_CURRENT_LINE_NUMBER;
-    } else if (wcscmp(status_command, L"job-control") == 0) {
-        return STATUS_SET_JOB_CONTROL;
-    } else if (wcscmp(status_command, L"print-stack-trace") == 0) {
-        return STATUS_PRINT_STACK_TRACE;
-    }
-    return STATUS_NOOP;
-}
-
-static const wcstring status_cmd_to_string(status_cmd_t status_cmd) {
-    switch (status_cmd) {
-        case STATUS_NOOP:
-            return L"no-op";
-        case STATUS_IS_LOGIN:
-            return L"is-login";
-        case STATUS_IS_INTERACTIVE:
-            return L"is-interactive";
-        case STATUS_IS_BLOCK:
-            return L"is-block";
-        case STATUS_IS_COMMAND_SUB:
-            return L"is-command-sub";
-        case STATUS_IS_FULL_JOB_CTRL:
-            return L"is-full-job-control";
-        case STATUS_IS_INTERACTIVE_JOB_CTRL:
-            return L"is-interactive-job-control";
-        case STATUS_IS_NO_JOB_CTRL:
-            return L"is-no-job-control";
-        case STATUS_CURRENT_FILENAME:
-            return L"current-filename";
-        case STATUS_CURRENT_LINE_NUMBER:
-            return L"current-line-number";
-        case STATUS_SET_JOB_CONTROL:
-            return L"job-control";
-        case STATUS_PRINT_STACK_TRACE:
-            return L"print-stack-trace";
-    }
-}
+// Must be sorted by string, not enum or random.
+const enum_map status_enum_map[] = {
+    {STATUS_CURRENT_FILENAME, L"current-filename"},
+    {STATUS_CURRENT_LINE_NUMBER, L"current-line-number"},
+    {STATUS_IS_BLOCK, L"is-block"},
+    {STATUS_IS_COMMAND_SUB, L"is-command-substitution"},
+    {STATUS_IS_FULL_JOB_CTRL, L"is-full-job-control"},
+    {STATUS_IS_INTERACTIVE, L"is-interactive"},
+    {STATUS_IS_INTERACTIVE_JOB_CTRL, L"is-interactive-job-control"},
+    {STATUS_IS_LOGIN, L"is-login"},
+    {STATUS_IS_NO_JOB_CTRL, L"is-no-job-control"},
+    {STATUS_SET_JOB_CONTROL, L"job-control"},
+    {STATUS_PRINT_STACK_TRACE, L"print-stack-trace"},
+    {STATUS_UNDEF, NULL}};
+#define status_enum_map_len (sizeof status_enum_map / sizeof *status_enum_map)
 
 /// Remember the status subcommand and disallow selecting more than one status subcommand.
 static bool set_status_cmd(wchar_t *const cmd, status_cmd_t *status_cmd, status_cmd_t sub_cmd,
                            io_streams_t &streams) {
-    if (*status_cmd != STATUS_NOOP) {
+    if (*status_cmd != STATUS_UNDEF) {
         wchar_t err_text[1024];
+        const wchar_t *subcmd_str1 = enum_to_str(*status_cmd, status_enum_map);
+        const wchar_t *subcmd_str2 = enum_to_str(sub_cmd, status_enum_map);
         swprintf(err_text, sizeof(err_text) / sizeof(wchar_t),
-                 _(L"you cannot do both '%ls' and '%ls' in the same invocation"),
-                 status_cmd_to_string(*status_cmd).c_str(), status_cmd_to_string(sub_cmd).c_str());
+                 _(L"you cannot do both '%ls' and '%ls' in the same invocation"), subcmd_str1,
+                 subcmd_str2);
         streams.err.append_format(BUILTIN_ERR_COMBO2, cmd, err_text);
         return false;
     }
@@ -2245,12 +2376,13 @@ static bool set_status_cmd(wchar_t *const cmd, status_cmd_t *status_cmd, status_
     return true;
 }
 
-#define CHECK_FOR_UNEXPECTED_STATUS_ARGS(status_cmd)                                         \
-    if (args.size() != 0) {                                                                  \
-        streams.err.append_format(BUILTIN_ERR_ARG_COUNT2, cmd,                               \
-                                  status_cmd_to_string(status_cmd).c_str(), 0, args.size()); \
-        status = STATUS_BUILTIN_ERROR;                                                       \
-        break;                                                                               \
+#define CHECK_FOR_UNEXPECTED_STATUS_ARGS(status_cmd)                                        \
+    if (args.size() != 0) {                                                                 \
+        const wchar_t *subcmd_str = enum_to_str(status_cmd, status_enum_map);               \
+        if (!subcmd_str) subcmd_str = L"default";                                           \
+        streams.err.append_format(BUILTIN_ERR_ARG_COUNT2, cmd, subcmd_str, 0, args.size()); \
+        status = STATUS_BUILTIN_ERROR;                                                      \
+        break;                                                                              \
     }
 
 int job_control_str_to_mode(const wchar_t *mode, wchar_t *cmd, io_streams_t &streams) {
@@ -2269,7 +2401,7 @@ int job_control_str_to_mode(const wchar_t *mode, wchar_t *cmd, io_streams_t &str
 static int builtin_status(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
     wchar_t *cmd = argv[0];
     int argc = builtin_count_args(argv);
-    status_cmd_t status_cmd = STATUS_NOOP;
+    status_cmd_t status_cmd = STATUS_UNDEF;
     int status = STATUS_BUILTIN_OK;
     int new_job_control_mode = -1;
 
@@ -2388,8 +2520,8 @@ static int builtin_status(parser_t &parser, io_streams_t &streams, wchar_t **arg
     // If a status command hasn't already been specified via a flag check the first word.
     // Note that this can be simplified after we eliminate allowing subcommands as flags.
     if (w.woptind < argc) {
-        status_cmd_t subcmd = status_string_to_cmd(argv[w.woptind]);
-        if (subcmd != STATUS_NOOP) {
+        status_cmd_t subcmd = str_to_enum(argv[w.woptind], status_enum_map, status_enum_map_len);
+        if (subcmd != STATUS_UNDEF) {
             if (!set_status_cmd(cmd, &status_cmd, subcmd, streams)) {
                 return STATUS_BUILTIN_ERROR;
             }
@@ -2401,7 +2533,7 @@ static int builtin_status(parser_t &parser, io_streams_t &streams, wchar_t **arg
     const wcstring_list_t args(argv + w.woptind, argv + argc);
 
     switch (status_cmd) {
-        case STATUS_NOOP: {
+        case STATUS_UNDEF: {
             CHECK_FOR_UNEXPECTED_STATUS_ARGS(status_cmd)
             if (is_login) {
                 streams.out.append_format(_(L"This is a login shell\n"));
@@ -2423,8 +2555,8 @@ static int builtin_status(parser_t &parser, io_streams_t &streams, wchar_t **arg
                 CHECK_FOR_UNEXPECTED_STATUS_ARGS(status_cmd)
             } else {
                 if (args.size() != 1) {
-                    streams.err.append_format(BUILTIN_ERR_ARG_COUNT2, cmd,
-                                              status_cmd_to_string(status_cmd).c_str(), 1,
+                    const wchar_t *subcmd_str = enum_to_str(status_cmd, status_enum_map);
+                    streams.err.append_format(BUILTIN_ERR_ARG_COUNT2, cmd, subcmd_str, 1,
                                               args.size());
                     status = STATUS_BUILTIN_ERROR;
                     break;
@@ -2500,7 +2632,7 @@ static int builtin_exit(parser_t &parser, io_streams_t &streams, wchar_t **argv)
     int argc = builtin_count_args(argv);
 
     if (argc > 2) {
-        streams.err.append_format(BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]);
+        streams.err.append_format(_(L"%ls: Too many arguments\n"), argv[0]);
         builtin_print_help(parser, streams, argv[0], streams.err);
         return STATUS_BUILTIN_ERROR;
     }
@@ -2509,10 +2641,8 @@ static int builtin_exit(parser_t &parser, io_streams_t &streams, wchar_t **argv)
     if (argc == 1) {
         ec = proc_get_last_status();
     } else {
-        wchar_t *end;
-        errno = 0;
-        ec = wcstol(argv[1], &end, 10);
-        if (errno || *end != 0) {
+        ec = fish_wcstol(argv[1]);
+        if (errno) {
             streams.err.append_format(_(L"%ls: Argument '%ls' must be an integer\n"), argv[0],
                                       argv[1]);
             builtin_print_help(parser, streams, argv[0], streams.err);
@@ -2530,12 +2660,12 @@ static int builtin_exit(parser_t &parser, io_streams_t &streams, wchar_t **argv)
 static int builtin_cd(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
     env_var_t dir_in;
     wcstring dir;
-    int res = STATUS_BUILTIN_OK;
 
     if (argv[1] == NULL) {
         dir_in = env_get_string(L"HOME");
         if (dir_in.missing_or_empty()) {
             streams.err.append_format(_(L"%ls: Could not find home directory\n"), argv[0]);
+            return STATUS_BUILTIN_ERROR;
         }
     } else {
         dir_in = env_var_t(argv[1]);
@@ -2556,18 +2686,17 @@ static int builtin_cd(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
         } else if (errno == EROTTEN) {
             streams.err.append_format(_(L"%ls: '%ls' is a rotten symlink\n"), argv[0],
                                       dir_in.c_str());
-
         } else {
             streams.err.append_format(_(L"%ls: Unknown error trying to locate directory '%ls'\n"),
                                       argv[0], dir_in.c_str());
         }
 
-        if (!shell_is_interactive()) {
-            streams.err.append(parser.current_line());
-        }
+        if (!shell_is_interactive()) streams.err.append(parser.current_line());
 
-        res = 1;
-    } else if (wchdir(dir) != 0) {
+        return STATUS_BUILTIN_ERROR;
+    }
+
+    if (wchdir(dir) != 0) {
         struct stat buffer;
         int status;
 
@@ -2583,13 +2712,15 @@ static int builtin_cd(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
             streams.err.append(parser.current_line());
         }
 
-        res = 1;
-    } else if (!env_set_pwd()) {
-        res = 1;
-        streams.err.append_format(_(L"%ls: Could not set PWD variable\n"), argv[0]);
+        return STATUS_BUILTIN_ERROR;
     }
 
-    return res;
+    if (!env_set_pwd()) {
+        streams.err.append_format(_(L"%ls: Could not set PWD variable\n"), argv[0]);
+        return STATUS_BUILTIN_ERROR;
+    }
+
+    return STATUS_BUILTIN_OK;
 }
 
 /// Implementation of the builtin count command, used to count the number of arguments sent to it.
@@ -2707,14 +2838,14 @@ static int builtin_source(parser_t &parser, io_streams_t &streams, wchar_t **arg
         fn_intern = intern(argv[1]);
     }
 
-    parser.push_block(new source_block_t(fn_intern));
+    const source_block_t *sb = parser.push_block(fn_intern);
     reader_push_current_filename(fn_intern);
 
     env_set_argv(argc > 1 ? argv + 2 : argv + 1);
 
     res = reader_read(fd, streams.io_chain ? *streams.io_chain : io_chain_t());
 
-    parser.pop_block();
+    parser.pop_block(sb);
 
     if (res) {
         streams.err.append_format(_(L"%ls: Error while reading file '%ls'\n"), argv[0],
@@ -2730,10 +2861,6 @@ static int builtin_source(parser_t &parser, io_streams_t &streams, wchar_t **arg
     return res;
 }
 
-/// Make the specified job the first job of the job list. Moving jobs around in the list makes the
-/// list reflect the order in which the jobs were used.
-static void make_first(job_t *j) { job_promote(j); }
-
 /// Builtin for putting a job in the foreground.
 static int builtin_fg(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
     job_t *j = NULL;
@@ -2743,9 +2870,9 @@ static int builtin_fg(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
         // the foreground.
         job_iterator_t jobs;
         while ((j = jobs.next())) {
-            if (job_get_flag(j, JOB_CONSTRUCTED) && (!job_is_completed(j)) &&
-                ((job_is_stopped(j) || (!job_get_flag(j, JOB_FOREGROUND))) &&
-                 job_get_flag(j, JOB_CONTROL))) {
+            if (j->get_flag(JOB_CONSTRUCTED) && (!job_is_completed(j)) &&
+                ((job_is_stopped(j) || (!j->get_flag(JOB_FOREGROUND))) &&
+                 j->get_flag(JOB_CONTROL))) {
                 break;
             }
         }
@@ -2756,13 +2883,11 @@ static int builtin_fg(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
         // Specifying more than one job to put to the foreground is a syntax error, we still
         // try to locate the job argv[1], since we want to know if this is an ambigous job
         // specification or if this is an malformed job id.
-        wchar_t *endptr;
         int pid;
         int found_job = 0;
 
-        errno = 0;
-        pid = fish_wcstoi(argv[1], &endptr, 10);
-        if (!(*endptr || errno)) {
+        pid = fish_wcstoi(argv[1]);
+        if (!(errno || pid < 0)) {
             j = job_get_from_pid(pid);
             if (j) found_job = 1;
         }
@@ -2778,20 +2903,16 @@ static int builtin_fg(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
         j = 0;
 
     } else {
-        wchar_t *end;
-        int pid;
-        errno = 0;
-        pid = abs(fish_wcstoi(argv[1], &end, 10));
-
-        if (*end || errno) {
+        int pid = abs(fish_wcstoi(argv[1]));
+        if (errno) {
             streams.err.append_format(BUILTIN_ERR_NOT_NUMBER, argv[0], argv[1]);
             builtin_print_help(parser, streams, argv[0], streams.err);
         } else {
             j = job_get_from_pid(pid);
-            if (!j || !job_get_flag(j, JOB_CONSTRUCTED) || job_is_completed(j)) {
+            if (!j || !j->get_flag(JOB_CONSTRUCTED) || job_is_completed(j)) {
                 streams.err.append_format(_(L"%ls: No suitable job: %d\n"), argv[0], pid);
                 j = 0;
-            } else if (!job_get_flag(j, JOB_CONTROL)) {
+            } else if (!j->get_flag(JOB_CONTROL)) {
                 streams.err.append_format(_(L"%ls: Can't put job %d, '%ls' to foreground because "
                                             L"it is not under job control\n"),
                                           argv[0], pid, j->command_wcstr());
@@ -2816,8 +2937,8 @@ static int builtin_fg(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
     if (!ft.empty()) env_set(L"_", ft.c_str(), ENV_EXPORT);
     reader_write_title(j->command());
 
-    make_first(j);
-    job_set_flag(j, JOB_FOREGROUND, 1);
+    job_promote(j);
+    j->set_flag(JOB_FOREGROUND, true);
 
     job_continue(j, job_is_stopped(j));
     return STATUS_BUILTIN_OK;
@@ -2829,7 +2950,7 @@ static int send_to_bg(parser_t &parser, io_streams_t &streams, job_t *j, const w
         streams.err.append_format(_(L"%ls: Unknown job '%ls'\n"), L"bg", name);
         builtin_print_help(parser, streams, L"bg", streams.err);
         return STATUS_BUILTIN_ERROR;
-    } else if (!job_get_flag(j, JOB_CONTROL)) {
+    } else if (!j->get_flag(JOB_CONTROL)) {
         streams.err.append_format(
             _(L"%ls: Can't put job %d, '%ls' to background because it is not under job control\n"),
             L"bg", j->job_id, j->command_wcstr());
@@ -2839,8 +2960,8 @@ static int send_to_bg(parser_t &parser, io_streams_t &streams, job_t *j, const w
 
     streams.err.append_format(_(L"Send job %d '%ls' to background\n"), j->job_id,
                               j->command_wcstr());
-    make_first(j);
-    job_set_flag(j, JOB_FOREGROUND, 0);
+    job_promote(j);
+    j->set_flag(JOB_FOREGROUND, false);
     job_continue(j, job_is_stopped(j));
     return STATUS_BUILTIN_OK;
 }
@@ -2853,7 +2974,7 @@ static int builtin_bg(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
         job_t *j;
         job_iterator_t jobs;
         while ((j = jobs.next())) {
-            if (job_is_stopped(j) && job_get_flag(j, JOB_CONTROL) && (!job_is_completed(j))) {
+            if (job_is_stopped(j) && j->get_flag(JOB_CONTROL) && (!job_is_completed(j))) {
                 break;
             }
         }
@@ -2865,14 +2986,12 @@ static int builtin_bg(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
             res = send_to_bg(parser, streams, j, _(L"(default)"));
         }
     } else {
-        wchar_t *end;
         int i;
         int pid;
 
         for (i = 1; argv[i]; i++) {
-            errno = 0;
-            pid = fish_wcstoi(argv[i], &end, 10);
-            if (errno || pid < 0 || *end || !job_get_from_pid(pid)) {
+            pid = fish_wcstoi(argv[i]);
+            if (errno || pid < 0 || !job_get_from_pid(pid)) {
                 streams.err.append_format(_(L"%ls: '%ls' is not a job\n"), argv[0], argv[i]);
                 return STATUS_BUILTIN_ERROR;
             }
@@ -2910,15 +3029,14 @@ static int builtin_break_continue(parser_t &parser, io_streams_t &streams, wchar
         return STATUS_BUILTIN_ERROR;
     }
 
-    // Skip blocks interior to the loop.
+    // Skip blocks interior to the loop (but not the loop itself)
     size_t block_idx = loop_idx;
     while (block_idx--) {
         parser.block_at_index(block_idx)->skip = true;
     }
 
-    /* Skip the loop itself */
+    // Mark the loop's status
     block_t *loop_block = parser.block_at_index(loop_idx);
-    loop_block->skip = true;
     loop_block->loop_status = is_break ? LOOP_BREAK : LOOP_CONTINUE;
     return STATUS_BUILTIN_OK;
 }
@@ -2930,11 +3048,11 @@ static int builtin_breakpoint(parser_t &parser, io_streams_t &streams, wchar_t *
         return STATUS_BUILTIN_ERROR;
     }
 
-    parser.push_block(new breakpoint_block_t());
+    const breakpoint_block_t *bpb = parser.push_block();
 
     reader_read(STDIN_FILENO, streams.io_chain ? *streams.io_chain : io_chain_t());
 
-    parser.pop_block();
+    parser.pop_block(bpb);
 
     return proc_get_last_status();
 }
@@ -2944,17 +3062,15 @@ static int builtin_return(parser_t &parser, io_streams_t &streams, wchar_t **arg
     int argc = builtin_count_args(argv);
 
     if (argc > 2) {
-        streams.err.append_format(_(L"%ls: Too many arguments\n"), argv[0]);
+        streams.err.append_format(BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]);
         builtin_print_help(parser, streams, argv[0], streams.err);
         return STATUS_BUILTIN_ERROR;
     }
 
     int status;
     if (argc == 2) {
-        wchar_t *end;
-        errno = 0;
-        status = fish_wcstoi(argv[1], &end, 10);
-        if (errno || *end != 0) {
+        status = fish_wcstoi(argv[1]);
+        if (errno) {
             streams.err.append_format(_(L"%ls: Argument '%ls' must be an integer\n"), argv[0],
                                       argv[1]);
             builtin_print_help(parser, streams, argv[0], streams.err);
@@ -2977,59 +3093,31 @@ static int builtin_return(parser_t &parser, io_streams_t &streams, wchar_t **arg
         return STATUS_BUILTIN_ERROR;
     }
 
-    // Skip everything up to (and then including) the function block.
-    for (size_t i = 0; i < function_block_idx; i++) {
+    // Skip everything up to and including the function block.
+    for (size_t i = 0; i <= function_block_idx; i++) {
         block_t *b = parser.block_at_index(i);
         b->skip = true;
     }
-    parser.block_at_index(function_block_idx)->skip = true;
     return status;
 }
 
-enum hist_cmd_t { HIST_NOOP, HIST_SEARCH, HIST_DELETE, HIST_CLEAR, HIST_MERGE, HIST_SAVE };
-
-static hist_cmd_t hist_string_to_cmd(const wchar_t *hist_command) {
-    if (wcscmp(hist_command, L"search") == 0) {
-        return HIST_SEARCH;
-    } else if (wcscmp(hist_command, L"delete") == 0) {
-        return HIST_DELETE;
-    } else if (wcscmp(hist_command, L"merge") == 0) {
-        return HIST_MERGE;
-    } else if (wcscmp(hist_command, L"save") == 0) {
-        return HIST_SAVE;
-    } else if (wcscmp(hist_command, L"clear") == 0) {
-        return HIST_CLEAR;
-    }
-    return HIST_NOOP;
-}
-
-static const wcstring hist_cmd_to_string(hist_cmd_t hist_cmd) {
-    switch (hist_cmd) {
-        case HIST_NOOP:
-            return L"no-op";
-        case HIST_SEARCH:
-            return L"search";
-        case HIST_DELETE:
-            return L"delete";
-        case HIST_CLEAR:
-            return L"clear";
-        case HIST_MERGE:
-            return L"merge";
-        case HIST_SAVE:
-            return L"save";
-    }
-
-    DIE("should not reach this statement");  // silence some compiler errors about not returning
-}
+enum hist_cmd_t { HIST_SEARCH = 1, HIST_DELETE, HIST_CLEAR, HIST_MERGE, HIST_SAVE, HIST_UNDEF };
+// Must be sorted by string, not enum or random.
+const enum_map hist_enum_map[] = {{HIST_CLEAR, L"clear"},   {HIST_DELETE, L"delete"},
+                                              {HIST_MERGE, L"merge"},   {HIST_SAVE, L"save"},
+                                              {HIST_SEARCH, L"search"}, {HIST_UNDEF, NULL}};
+#define hist_enum_map_len (sizeof hist_enum_map / sizeof *hist_enum_map)
 
 /// Remember the history subcommand and disallow selecting more than one history subcommand.
 static bool set_hist_cmd(wchar_t *const cmd, hist_cmd_t *hist_cmd, hist_cmd_t sub_cmd,
                          io_streams_t &streams) {
-    if (*hist_cmd != HIST_NOOP) {
+    if (*hist_cmd != HIST_UNDEF) {
         wchar_t err_text[1024];
+        const wchar_t *subcmd_str1 = enum_to_str(*hist_cmd, hist_enum_map);
+        const wchar_t *subcmd_str2 = enum_to_str(sub_cmd, hist_enum_map);
         swprintf(err_text, sizeof(err_text) / sizeof(wchar_t),
-                 _(L"you cannot do both '%ls' and '%ls' in the same invocation"),
-                 hist_cmd_to_string(*hist_cmd).c_str(), hist_cmd_to_string(sub_cmd).c_str());
+                 _(L"you cannot do both '%ls' and '%ls' in the same invocation"), subcmd_str1,
+                 subcmd_str2);
         streams.err.append_format(BUILTIN_ERR_COMBO2, cmd, err_text);
         return false;
     }
@@ -3040,14 +3128,15 @@ static bool set_hist_cmd(wchar_t *const cmd, hist_cmd_t *hist_cmd, hist_cmd_t su
 
 #define CHECK_FOR_UNEXPECTED_HIST_ARGS(hist_cmd)                                                \
     if (history_search_type_defined || show_time_format || null_terminate) {                    \
+        const wchar_t *subcmd_str = enum_to_str(hist_cmd, hist_enum_map);                       \
         streams.err.append_format(_(L"%ls: you cannot use any options with the %ls command\n"), \
-                                  cmd, hist_cmd_to_string(hist_cmd).c_str());                   \
+                                  cmd, subcmd_str);                                             \
         status = STATUS_BUILTIN_ERROR;                                                          \
         break;                                                                                  \
     }                                                                                           \
     if (args.size() != 0) {                                                                     \
-        streams.err.append_format(BUILTIN_ERR_ARG_COUNT2, cmd,                                  \
-                                  hist_cmd_to_string(hist_cmd).c_str(), 0, args.size());        \
+        const wchar_t *subcmd_str = enum_to_str(hist_cmd, hist_enum_map);                       \
+        streams.err.append_format(BUILTIN_ERR_ARG_COUNT2, cmd, subcmd_str, 0, args.size());     \
         status = STATUS_BUILTIN_ERROR;                                                          \
         break;                                                                                  \
     }
@@ -3056,7 +3145,7 @@ static bool set_hist_cmd(wchar_t *const cmd, hist_cmd_t *hist_cmd, hist_cmd_t su
 static int builtin_history(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
     wchar_t *cmd = argv[0];
     int argc = builtin_count_args(argv);
-    hist_cmd_t hist_cmd = HIST_NOOP;
+    hist_cmd_t hist_cmd = HIST_UNDEF;
     history_search_type_t search_type = (history_search_type_t)-1;
     long max_items = LONG_MAX;
     bool history_search_type_defined = false;
@@ -3148,9 +3237,8 @@ static int builtin_history(parser_t &parser, io_streams_t &streams, wchar_t **ar
                 break;
             }
             case 'n': {
-                wchar_t *end = 0;
-                max_items = wcstol(w.woptarg, &end, 10);
-                if (!(*w.woptarg != L'\0' && *end == L'\0')) {
+                max_items = fish_wcstol(w.woptarg);
+                if (errno) {
                     streams.err.append_format(_(L"%ls: max value '%ls' is not a valid number\n"),
                                               argv[0], w.woptarg);
                     return STATUS_BUILTIN_ERROR;
@@ -3171,9 +3259,8 @@ static int builtin_history(parser_t &parser, io_streams_t &streams, wchar_t **ar
             }
             case '?': {
                 // Try to parse it as a number; e.g., "-123".
-                wchar_t *end = 0;
-                max_items = wcstol(argv[w.woptind - 1] + 1, &end, 10);
-                if (!(argv[w.woptind - 1][1] != L'\0' && *end == L'\0')) {
+                max_items = fish_wcstol(argv[w.woptind - 1] + 1);
+                if (errno) {
                     streams.err.append_format(BUILTIN_ERR_UNKNOWN, cmd, argv[w.woptind - 1]);
                     return STATUS_BUILTIN_ERROR;
                 }
@@ -3197,8 +3284,8 @@ static int builtin_history(parser_t &parser, io_streams_t &streams, wchar_t **ar
     // Note that this can be simplified after we eliminate allowing subcommands as flags.
     // See the TODO above regarding the `long_options` array.
     if (w.woptind < argc) {
-        hist_cmd_t subcmd = hist_string_to_cmd(argv[w.woptind]);
-        if (subcmd != HIST_NOOP) {
+        hist_cmd_t subcmd = str_to_enum(argv[w.woptind], hist_enum_map, hist_enum_map_len);
+        if (subcmd != HIST_UNDEF) {
             if (!set_hist_cmd(cmd, &hist_cmd, subcmd, streams)) {
                 return STATUS_BUILTIN_ERROR;
             }
@@ -3211,7 +3298,7 @@ static int builtin_history(parser_t &parser, io_streams_t &streams, wchar_t **ar
     const wcstring_list_t args(argv + w.woptind, argv + argc);
 
     // Establish appropriate defaults.
-    if (hist_cmd == HIST_NOOP) hist_cmd = HIST_SEARCH;
+    if (hist_cmd == HIST_UNDEF) hist_cmd = HIST_SEARCH;
     if (!history_search_type_defined) {
         if (hist_cmd == HIST_SEARCH) search_type = HISTORY_SEARCH_TYPE_CONTAINS;
         if (hist_cmd == HIST_DELETE) search_type = HISTORY_SEARCH_TYPE_EXACT;
@@ -3266,8 +3353,8 @@ static int builtin_history(parser_t &parser, io_streams_t &streams, wchar_t **ar
             history->save();
             break;
         }
-        case HIST_NOOP: {
-            DIE("Unexpected HIST_NOOP seen");
+        case HIST_UNDEF: {
+            DIE("Unexpected HIST_UNDEF seen");
             break;
         }
     }
diff --git a/src/builtin.h b/src/builtin.h
index b76f75a35..f27086799 100644
--- a/src/builtin.h
+++ b/src/builtin.h
@@ -109,6 +109,7 @@ int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_lis
 void builtin_print_help(parser_t &parser, io_streams_t &streams, const wchar_t *cmd,
                         output_stream_t &b);
 int builtin_count_args(const wchar_t *const *argv);
+bool builtin_is_valid_varname(const wchar_t *varname, wcstring &errstr, const wchar_t *cmd);
 
 void builtin_unknown_option(parser_t &parser, io_streams_t &streams, const wchar_t *cmd,
                             const wchar_t *opt);
diff --git a/src/builtin_commandline.cpp b/src/builtin_commandline.cpp
index 9941a62cc..d47d6f534 100644
--- a/src/builtin_commandline.cpp
+++ b/src/builtin_commandline.cpp
@@ -50,46 +50,37 @@ 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; }
 
-static pthread_mutex_t transient_commandline_lock = PTHREAD_MUTEX_INITIALIZER;
-static wcstring_list_t *get_transient_stack() {
+static owning_lock &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.
-    static wcstring_list_t *result = NULL;
-    if (!result) {
-        result = new wcstring_list_t();
-    }
-    return result;
+    static owning_lock s_transient_stack;
+    return s_transient_stack;
 }
 
 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()) {
-        out_result->assign(stack->back());
-        result = true;
+    auto locked = get_transient_stack().acquire();
+    wcstring_list_t &stack = locked.value;
+    if (stack.empty()) {
+        return false;
     }
-    return result;
+    out_result->assign(stack.back());
+    return true;
 }
 
 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();
-    stack->push_back(cmd);
-    this->token = stack->size();
+    auto locked = get_transient_stack().acquire();
+    wcstring_list_t &stack = locked.value;
+    stack.push_back(cmd);
+    this->token = stack.size();
 }
 
 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();
-    assert(this->token == stack->size());
-    stack->pop_back();
+    auto locked = get_transient_stack().acquire();
+    wcstring_list_t &stack = locked.value;
+    assert(this->token == stack.size());
+    stack.pop_back();
 }
 
 /// Replace/append/insert the selection with/at/after the specified string.
@@ -363,7 +354,7 @@ int builtin_commandline(parser_t &parser, io_streams_t &streams, wchar_t **argv)
                 // the queue of unused keypresses.
                 input_queue_ch(c);
             } else {
-                streams.err.append_format(_(L"%ls: Unknown input function '%ls'\n"), argv[0],
+                streams.err.append_format(_(L"%ls: Unknown input function '%ls'"), argv[0],
                                           argv[i]);
                 builtin_print_help(parser, streams, argv[0], streams.err);
                 return 1;
@@ -384,7 +375,7 @@ int builtin_commandline(parser_t &parser, io_streams_t &streams, wchar_t **argv)
 
     // 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);
+        streams.err.append_format(L"%ls: Too many arguments", argv[0]);
         builtin_print_help(parser, streams, argv[0], streams.err);
         return 1;
     }
@@ -426,12 +417,8 @@ int builtin_commandline(parser_t &parser, io_streams_t &streams, wchar_t **argv)
 
     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) {
+            long new_pos = fish_wcstol(argv[w.woptind]);
+            if (errno) {
                 streams.err.append_format(BUILTIN_ERR_NOT_NUMBER, argv[0], argv[w.woptind]);
                 builtin_print_help(parser, streams, argv[0], streams.err);
             }
diff --git a/src/builtin_complete.cpp b/src/builtin_complete.cpp
index 25c60ffbc..30fe087be 100644
--- a/src/builtin_complete.cpp
+++ b/src/builtin_complete.cpp
@@ -58,25 +58,17 @@ static void builtin_complete_add2(const wchar_t *cmd, int cmd_type, const wchar_
 /// 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,
+                                 wcstring_list_t &old_opt, int result_mode,
                                  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);
-        }
     }
 }
 
@@ -122,64 +114,45 @@ static void builtin_complete_remove(const wcstring_list_t &cmd, const wcstring_l
 // 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;
+    static int recursion_level = 0;
+
+    wchar_t *cmd = argv[0];
+    int argc = builtin_count_args(argv);
     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"";
-
     bool do_complete = false;
     wcstring do_complete_param;
-
-    wcstring_list_t cmd;
+    wcstring_list_t cmd_to_complete;
     wcstring_list_t path;
     wcstring_list_t wrap_targets;
 
-    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}};
-
-        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;
+    const wchar_t *short_options = L":a:c:p:s:l:o:d:frxeuAn:C::w:h";
+    const struct woption long_options[] = {{L"exclusive", no_argument, NULL, 'x'},
+                                           {L"no-files", no_argument, NULL, 'f'},
+                                           {L"require-parameter", no_argument, NULL, 'r'},
+                                           {L"path", required_argument, NULL, 'p'},
+                                           {L"command", required_argument, NULL, 'c'},
+                                           {L"short-option", required_argument, NULL, 's'},
+                                           {L"long-option", required_argument, NULL, 'l'},
+                                           {L"old-option", required_argument, NULL, 'o'},
+                                           {L"description", required_argument, NULL, 'd'},
+                                           {L"arguments", required_argument, NULL, 'a'},
+                                           {L"erase", no_argument, NULL, 'e'},
+                                           {L"unauthoritative", no_argument, NULL, 'u'},
+                                           {L"authoritative", no_argument, NULL, 'A'},
+                                           {L"condition", required_argument, NULL, 'n'},
+                                           {L"wraps", required_argument, NULL, 'w'},
+                                           {L"do-complete", optional_argument, NULL, 'C'},
+                                           {L"help", no_argument, NULL, 'h'},
+                                           {NULL, 0, NULL, 0}};
 
+    int opt;
+    wgetopter_t w;
+    while ((opt = w.wgetopt_long(argc, argv, short_options, long_options, NULL)) != -1) {
         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': {
                 result_mode |= EXCLUSIVE;
                 break;
@@ -199,50 +172,46 @@ int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
                     if (opt == 'p')
                         path.push_back(tmp);
                     else
-                        cmd.push_back(tmp);
+                        cmd_to_complete.push_back(tmp);
                 } else {
-                    streams.err.append_format(L"%ls: Invalid token '%ls'\n", argv[0], w.woptarg);
-                    res = true;
+                    streams.err.append_format(_(L"%ls: Invalid token '%ls'\n"), cmd, w.woptarg);
+                    return STATUS_BUILTIN_ERROR;
                 }
                 break;
             }
             case 'd': {
                 desc = w.woptarg;
-                if (w.woptarg[0] == '\0') {
-                    streams.err.append_format(L"%ls: -d requires a non-empty string\n", argv[0]);
-                    res = true;
-                }
                 break;
             }
             case 'u': {
-                authoritative = 0;
+                // This option was removed in commit 1911298 and is now a no-op.
                 break;
             }
             case 'A': {
-                authoritative = 1;
+                // This option was removed in commit 1911298 and is now a no-op.
                 break;
             }
             case 's': {
                 short_opt.append(w.woptarg);
                 if (w.woptarg[0] == '\0') {
-                    streams.err.append_format(L"%ls: -s requires a non-empty string\n", argv[0]);
-                    res = true;
+                    streams.err.append_format(_(L"%ls: -s requires a non-empty string\n"), cmd);
+                    return STATUS_BUILTIN_ERROR;
                 }
                 break;
             }
             case 'l': {
                 gnu_opt.push_back(w.woptarg);
                 if (w.woptarg[0] == '\0') {
-                    streams.err.append_format(L"%ls: -l requires a non-empty string\n", argv[0]);
-                    res = true;
+                    streams.err.append_format(_(L"%ls: -l requires a non-empty string\n"), cmd);
+                    return STATUS_BUILTIN_ERROR;
                 }
                 break;
             }
             case 'o': {
                 old_opt.push_back(w.woptarg);
                 if (w.woptarg[0] == '\0') {
-                    streams.err.append_format(L"%ls: -o requires a non-empty string\n", argv[0]);
-                    res = true;
+                    streams.err.append_format(_(L"%ls: -o requires a non-empty string\n"), cmd);
+                    return STATUS_BUILTIN_ERROR;
                 }
                 break;
             }
@@ -268,69 +237,72 @@ int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
                 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]);
+                    builtin_missing_argument(parser, streams, cmd, argv[w.woptind - 1]);
                     return STATUS_BUILTIN_ERROR;
                 }
                 do_complete_param = arg;
                 break;
             }
             case 'h': {
-                builtin_print_help(parser, streams, argv[0], streams.out);
-                return 0;
+                builtin_print_help(parser, streams, cmd, streams.out);
+                return STATUS_BUILTIN_OK;
+            }
+            case ':': {
+                builtin_missing_argument(parser, streams, cmd, argv[w.woptind - 1]);
+                return STATUS_BUILTIN_ERROR;
             }
             case '?': {
-                builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
-                res = true;
-                break;
+                builtin_unknown_option(parser, streams, cmd, argv[w.woptind - 1]);
+                return STATUS_BUILTIN_ERROR;
             }
             default: {
-                DIE("unexpected opt");
+                DIE("unexpected retval from wgetopt_long");
                 break;
             }
         }
     }
 
-    if (!res && condition && wcslen(condition)) {
+    if (w.woptind != argc) {
+        streams.err.append_format(BUILTIN_ERR_TOO_MANY_ARGUMENTS, cmd);
+        builtin_print_help(parser, streams, cmd, streams.err);
+        return STATUS_BUILTIN_ERROR;
+    }
+
+    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],
+            streams.err.append_format(L"%ls: Condition '%ls' contained a syntax error", cmd,
                                       condition);
             for (size_t i = 0; i < errors.size(); i++) {
-                streams.err.append_format(L"\n%s: ", argv[0]);
+                streams.err.append_format(L"\n%s: ", cmd);
                 streams.err.append(errors.at(i).describe(condition_string));
             }
-            res = true;
+            return STATUS_BUILTIN_ERROR;
         }
     }
 
-    if (!res && comp && wcslen(comp)) {
+    if (comp && wcslen(comp)) {
         wcstring prefix;
-        if (argv[0]) {
-            prefix.append(argv[0]);
-            prefix.append(L": ");
-        }
+        prefix.append(cmd);
+        prefix.append(L": ");
 
         wcstring err_text;
         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],
+            streams.err.append_format(L"%ls: Completion '%ls' contained a syntax error\n", cmd,
                                       comp);
             streams.err.append(err_text);
             streams.err.push_back(L'\n');
-            res = true;
+            return STATUS_BUILTIN_ERROR;
         }
     }
 
-    if (res) {
-        return 1;
-    }
-
     if (do_complete) {
         const wchar_t *token;
 
-        parse_util_token_extent(do_complete_param.c_str(), do_complete_param.size(), &token, 0,
-                                0, 0);
+        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.
@@ -341,7 +313,7 @@ int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
 
             std::vector comp;
             complete(do_complete_param, &comp, COMPLETION_REQUEST_DEFAULT,
-                        env_vars_snapshot_t::current());
+                     env_vars_snapshot_t::current());
 
             for (size_t i = 0; i < comp.size(); i++) {
                 const completion_t &next = comp.at(i);
@@ -358,8 +330,7 @@ int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
                 // 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);
+                    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
@@ -378,12 +349,7 @@ int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
 
             recursion_level--;
         }
-    } 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()) {
+    } else if (cmd_to_complete.empty() && path.empty()) {
         // No arguments specified, meaning we print the definitions of all specified completions
         // to stdout.
         streams.out.append(complete_print());
@@ -391,22 +357,21 @@ int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
         int flags = COMPLETE_AUTO_SPACE;
 
         if (remove) {
-            builtin_complete_remove(cmd, path, short_opt.c_str(), gnu_opt, old_opt);
-
+            builtin_complete_remove(cmd_to_complete, 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);
+            builtin_complete_add(cmd_to_complete, path, short_opt.c_str(), gnu_opt, old_opt,
+                                 result_mode, 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++) {
             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_to_complete.size(); i++) {
+                (remove ? complete_remove_wrapper : complete_add_wrapper)(cmd_to_complete.at(i),
+                                                                          wrap_target);
             }
         }
     }
 
-    return res ? 1 : 0;
+    return STATUS_BUILTIN_OK;
 }
diff --git a/src/builtin_jobs.cpp b/src/builtin_jobs.cpp
index 7a92e6b9e..8e8c8679c 100644
--- a/src/builtin_jobs.cpp
+++ b/src/builtin_jobs.cpp
@@ -28,13 +28,12 @@ enum {
 /// 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 (const process_ptr_t &p : j->processes) {
         struct timeval t;
         int jiffies;
         gettimeofday(&t, 0);
-        jiffies = proc_get_jiffies(p);
+        jiffies = proc_get_jiffies(p.get());
 
         double t1 = 1000000.0 * p->last_time.tv_sec + p->last_time.tv_usec;
         double t2 = 1000000.0 * t.tv_sec + t.tv_usec;
@@ -48,7 +47,6 @@ static int cpu_use(const job_t *j) {
 
 /// 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) {
@@ -85,7 +83,7 @@ static void builtin_jobs_print(const job_t *j, int mode, int header, io_streams_
                 streams.out.append(_(L"Process\n"));
             }
 
-            for (p = j->first_process; p; p = p->next) {
+            for (const process_ptr_t &p : j->processes) {
                 streams.out.append_format(L"%d\n", p->pid);
             }
             break;
@@ -96,7 +94,7 @@ static void builtin_jobs_print(const job_t *j, int mode, int header, io_streams_
                 streams.out.append(_(L"Command\n"));
             }
 
-            for (p = j->first_process; p; p = p->next) {
+            for (const process_ptr_t &p : j->processes) {
                 streams.out.append_format(L"%ls\n", p->argv0());
             }
             break;
@@ -186,11 +184,8 @@ int builtin_jobs(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
             int 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) {
+                int pid = fish_wcstoi(argv[i]);
+                if (errno || pid < 0) {
                     streams.err.append_format(_(L"%ls: '%ls' is not a job\n"), argv[0], argv[i]);
                     return 1;
                 }
diff --git a/src/builtin_printf.cpp b/src/builtin_printf.cpp
index 645dd982b..b26ecf49f 100644
--- a/src/builtin_printf.cpp
+++ b/src/builtin_printf.cpp
@@ -54,7 +54,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -312,7 +312,7 @@ void builtin_printf_state_t::print_esc_char(wchar_t c) {
             break;
         }
         case L'e': {  // escape
-            this->append_output(L'\x1B');
+            this->append_output(L'\e');
             break;
         }
         case L'f': {  // form feed
diff --git a/src/builtin_set.cpp b/src/builtin_set.cpp
index a210cbb75..b89c12e23 100644
--- a/src/builtin_set.cpp
+++ b/src/builtin_set.cpp
@@ -3,7 +3,9 @@
 
 #include 
 #include 
+#include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -190,12 +192,9 @@ static int parse_index(std::vector &indexes, const wchar_t *src, const wch
     while (iswspace(*src)) src++;
 
     while (*src != L']') {
-        wchar_t *end;
-        long l_ind;
-
-        errno = 0;
-        l_ind = wcstol(src, &end, 10);
-        if (end == src || errno) {
+        const wchar_t *end;
+        long l_ind = fish_wcstol(src, &end);
+        if (errno > 0) {  // ignore errno == -1 meaning the int did not end with a '\0'
             streams.err.append_format(_(L"%ls: Invalid index starting at '%ls'\n"), L"set", src);
             return 0;
         }
@@ -205,8 +204,8 @@ static int parse_index(std::vector &indexes, const wchar_t *src, const wch
         src = end;  //!OCLINT(parameter reassignment)
         if (*src == L'.' && *(src + 1) == L'.') {
             src += 2;
-            long l_ind2 = wcstol(src, &end, 10);
-            if (end == src || errno) {
+            long l_ind2 = fish_wcstol(src, &end);
+            if (errno > 0) {  // ignore errno == -1 meaning the int did not end with a '\0'
                 return 1;
             }
             src = end;  //!OCLINT(parameter reassignment)
@@ -345,8 +344,6 @@ int builtin_set(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
     int scope;
     int slice = 0;
 
-    const wchar_t *bad_char = NULL;
-
     // Parse options to obtain the requested operation and the modifiers.
     w.woptind = 0;
     while (1) {
@@ -522,18 +519,11 @@ int builtin_set(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
         *wcschr(dest, L'[') = 0;
     }
 
-    if (!wcslen(dest)) {
-        free(dest);
-        streams.err.append_format(BUILTIN_ERR_VARNAME_ZERO, argv[0]);
+    wcstring errstr;
+    if (!builtin_is_valid_varname(dest, errstr, argv[0])) {
+        streams.err.append(errstr);
         builtin_print_help(parser, streams, argv[0], streams.err);
-        return 1;
-    }
-
-    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;
+        return STATUS_BUILTIN_ERROR;
     }
 
     // Set assignment can work in two modes, either using slices or using the whole array. We detect
diff --git a/src/builtin_set_color.cpp b/src/builtin_set_color.cpp
index b05bf016d..40390ffff 100644
--- a/src/builtin_set_color.cpp
+++ b/src/builtin_set_color.cpp
@@ -56,11 +56,14 @@ int builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
                                            {L"help", no_argument, 0, 'h'},
                                            {L"bold", no_argument, 0, 'o'},
                                            {L"underline", no_argument, 0, 'u'},
+                                           {L"italics", no_argument, 0, 'i'},
+                                           {L"dim", no_argument, 0, 'd'},
+                                           {L"reverse", no_argument, 0, 'r'},
                                            {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";
+    const wchar_t *short_options = L"b:hvoidrcu";
 
     int argc = builtin_count_args(argv);
 
@@ -71,7 +74,7 @@ int builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
     }
 
     const wchar_t *bgcolor = NULL;
-    bool bold = false, underline = false;
+    bool bold = false, underline = false, italics = false, dim = false, reverse = false;
     int errret;
 
     // Parse options to obtain the requested operation and the modifiers.
@@ -99,6 +102,18 @@ int builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
                 bold = true;
                 break;
             }
+            case 'i': {
+                italics = true;
+                break;
+            }
+            case 'd': {
+                dim = true;
+                break;
+            }
+            case 'r': {
+                reverse = true;
+                break;
+            }
             case 'u': {
                 underline = true;
                 break;
@@ -128,7 +143,8 @@ int builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
         fgcolors.push_back(fg);
     }
 
-    if (fgcolors.empty() && bgcolor == NULL && !bold && !underline) {
+    if (fgcolors.empty() && bgcolor == NULL && !bold && !underline && !italics && !dim &&
+        !reverse) {
         streams.err.append_format(_(L"%ls: Expected an argument\n"), argv[0]);
         return STATUS_BUILTIN_ERROR;
     }
@@ -171,6 +187,20 @@ int builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
         writembs(enter_underline_mode);
     }
 
+    if (italics && enter_italics_mode) {
+        writembs(enter_italics_mode);
+    }
+
+    if (dim && enter_dim_mode) {
+        writembs(enter_dim_mode);
+    }
+
+    if (reverse && enter_reverse_mode) {
+        writembs(enter_reverse_mode);
+    } else if (reverse && enter_standout_mode) {
+        writembs(enter_standout_mode);
+    }
+
     if (bgcolor != NULL && bg.is_normal()) {
         write_color(rgb_color_t::black(), false /* not is_fg */);
         writembs(tparm(exit_attribute_mode));
diff --git a/src/builtin_string.cpp b/src/builtin_string.cpp
index b19ad38e8..fc27df8fa 100644
--- a/src/builtin_string.cpp
+++ b/src/builtin_string.cpp
@@ -570,24 +570,22 @@ static int string_match(parser_t &parser, io_streams_t &streams, int argc, wchar
         return BUILTIN_STRING_ERROR;
     }
 
-    string_matcher_t *matcher;
+    std::unique_ptr matcher;
     if (regex) {
-        matcher = new pcre2_matcher_t(argv[0], pattern, opts, streams);
+        matcher = make_unique(argv[0], pattern, opts, streams);
     } else {
-        matcher = new wildcard_matcher_t(argv[0], pattern, opts, streams);
+        matcher = make_unique(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)) {
-            delete matcher;
             return BUILTIN_STRING_ERROR;
         }
     }
 
     int rc = matcher->match_count() > 0 ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
-    delete matcher;
     return rc;
 }
 
@@ -720,8 +718,8 @@ bool regex_replacer_t::replace_matches(const wchar_t *arg) {
             done = true;
         } else {
             bufsize = outlen;
-            // cppcheck-suppress memleakOnRealloc
-            output = (wchar_t *)realloc(output, sizeof(wchar_t) * bufsize);
+            wchar_t *new_output = (wchar_t *)realloc(output, sizeof(wchar_t) * bufsize);
+            if (new_output) output = new_output;
         }
     }
 
@@ -806,24 +804,22 @@ static int string_replace(parser_t &parser, io_streams_t &streams, int argc, wch
         return BUILTIN_STRING_ERROR;
     }
 
-    string_replacer_t *replacer;
+    std::unique_ptr replacer;
     if (regex) {
-        replacer = new regex_replacer_t(argv[0], pattern, replacement, opts, streams);
+        replacer = make_unique(argv[0], pattern, replacement, opts, streams);
     } else {
-        replacer = new literal_replacer_t(argv[0], pattern, replacement, opts, streams);
+        replacer = make_unique(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)) {
-            delete replacer;
             return BUILTIN_STRING_ERROR;
         }
     }
 
     int rc = replacer->replace_count() > 0 ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
-    delete replacer;
     return rc;
 }
 
@@ -878,10 +874,8 @@ static int string_split(parser_t &parser, io_streams_t &streams, int argc, wchar
                 break;
             }
             case 'm': {
-                errno = 0;
-                wchar_t *endptr = 0;
-                max = wcstol(w.woptarg, &endptr, 10);
-                if (*endptr != L'\0' || errno != 0) {
+                max = fish_wcstol(w.woptarg);
+                if (errno) {
                     string_error(streams, BUILTIN_ERR_NOT_NUMBER, argv[0], w.woptarg);
                     return BUILTIN_STRING_ERROR;
                 }
@@ -969,7 +963,7 @@ static int string_sub(parser_t &parser, io_streams_t &streams, int argc, wchar_t
     long length = -1;
     bool quiet = false;
     wgetopter_t w;
-    wchar_t *endptr = NULL;
+
     for (;;) {
         int c = w.wgetopt_long(argc, argv, short_options, long_options, 0);
 
@@ -981,16 +975,14 @@ static int string_sub(parser_t &parser, io_streams_t &streams, int argc, wchar_t
                 break;
             }
             case 'l': {
-                errno = 0;
-                length = wcstol(w.woptarg, &endptr, 10);
-                if (*endptr != L'\0' || (errno != 0 && errno != ERANGE)) {
-                    string_error(streams, BUILTIN_ERR_NOT_NUMBER, argv[0], w.woptarg);
-                    return BUILTIN_STRING_ERROR;
-                }
+                length = fish_wcstol(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;
+                } else if (errno) {
+                    string_error(streams, BUILTIN_ERR_NOT_NUMBER, argv[0], w.woptarg);
+                    return BUILTIN_STRING_ERROR;
                 }
                 break;
             }
@@ -999,16 +991,14 @@ static int string_sub(parser_t &parser, io_streams_t &streams, int argc, wchar_t
                 break;
             }
             case 's': {
-                errno = 0;
-                start = wcstol(w.woptarg, &endptr, 10);
-                if (*endptr != L'\0' || (errno != 0 && errno != ERANGE)) {
-                    string_error(streams, BUILTIN_ERR_NOT_NUMBER, argv[0], w.woptarg);
-                    return BUILTIN_STRING_ERROR;
-                }
+                start = fish_wcstol(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;
+                } else if (errno) {
+                    string_error(streams, BUILTIN_ERR_NOT_NUMBER, argv[0], w.woptarg);
+                    return BUILTIN_STRING_ERROR;
                 }
                 break;
             }
diff --git a/src/builtin_test.cpp b/src/builtin_test.cpp
index cc2fcea23..9e5352dcd 100644
--- a/src/builtin_test.cpp
+++ b/src/builtin_test.cpp
@@ -4,6 +4,7 @@
 #include "config.h"  // IWYU pragma: keep
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -19,6 +20,9 @@
 #include "proc.h"
 #include "wutil.h"  // IWYU pragma: keep
 
+using std::unique_ptr;
+using std::move;
+
 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);
@@ -146,7 +150,7 @@ class test_parser {
     wcstring_list_t strings;
     wcstring_list_t errors;
 
-    expression *error(const wchar_t *fmt, ...);
+    unique_ptr error(const wchar_t *fmt, ...);
     void add_error(const wchar_t *fmt, ...);
 
     const wcstring &arg(unsigned int idx) { return strings.at(idx); }
@@ -154,19 +158,20 @@ class test_parser {
    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);
-    expression *parse_4_arg_expression(unsigned int start, unsigned int end);
-    expression *parse_combining_expression(unsigned int start, unsigned int end);
-    expression *parse_unary_expression(unsigned int start, unsigned int end);
+    unique_ptr parse_expression(unsigned int start, unsigned int end);
+    unique_ptr parse_3_arg_expression(unsigned int start, unsigned int end);
+    unique_ptr parse_4_arg_expression(unsigned int start, unsigned int end);
+    unique_ptr parse_combining_expression(unsigned int start, unsigned int end);
+    unique_ptr parse_unary_expression(unsigned int start, unsigned int end);
 
-    expression *parse_primary(unsigned int start, unsigned int end);
-    expression *parse_parenthentical(unsigned int start, unsigned int end);
-    expression *parse_unary_primary(unsigned int start, unsigned int end);
-    expression *parse_binary_primary(unsigned int start, unsigned int end);
-    expression *parse_just_a_string(unsigned int start, unsigned int end);
+    unique_ptr parse_primary(unsigned int start, unsigned int end);
+    unique_ptr parse_parenthentical(unsigned int start, unsigned int end);
+    unique_ptr parse_unary_primary(unsigned int start, unsigned int end);
+    unique_ptr parse_binary_primary(unsigned int start, unsigned int end);
+    unique_ptr parse_just_a_string(unsigned int start, unsigned int end);
 
-    static expression *parse_args(const wcstring_list_t &args, wcstring &err);
+    static unique_ptr parse_args(const wcstring_list_t &args, wcstring &err,
+                                             wchar_t *program_name);
 };
 
 struct range_t {
@@ -191,8 +196,6 @@ class expression {
     virtual bool evaluate(wcstring_list_t &errors) = 0;
 };
 
-typedef std::auto_ptr expr_ref_t;
-
 /// Single argument like -n foo or "just a string".
 class unary_primary : public expression {
    public:
@@ -216,9 +219,9 @@ class binary_primary : public expression {
 /// 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) {}
+    unique_ptr subject;
+    unary_operator(token_t tok, range_t where, unique_ptr exp)
+        : expression(tok, where), subject(move(exp)) {}
     bool evaluate(wcstring_list_t &errors);
 };
 
@@ -226,22 +229,17 @@ class unary_operator : public expression {
 /// we don't have to worry about precedence in the parser.
 class combining_expression : public expression {
    public:
-    const std::vector subjects;
+    const std::vector> subjects;
     const std::vector combiners;
 
-    combining_expression(token_t tok, range_t where, const std::vector &exprs,
-                         const std::vector &combs)
-        : expression(tok, where), subjects(exprs), combiners(combs) {
+    combining_expression(token_t tok, range_t where, std::vector> exprs,
+                         std::vector combs)
+        : expression(tok, where), subjects(move(exprs)), combiners(move(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++) {
-            delete subjects[i];
-        }
-    }
+    virtual ~combining_expression() {}
 
     bool evaluate(wcstring_list_t &errors);
 };
@@ -249,9 +247,9 @@ class combining_expression : public expression {
 /// 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) {}
+    unique_ptr contents;
+    parenthetical_expression(token_t tok, range_t where, unique_ptr expr)
+        : expression(tok, where), contents(move(expr)) {}
 
     virtual bool evaluate(wcstring_list_t &errors);
 };
@@ -264,7 +262,7 @@ void test_parser::add_error(const wchar_t *fmt, ...) {
     va_end(va);
 }
 
-expression *test_parser::error(const wchar_t *fmt, ...) {
+unique_ptr test_parser::error(const wchar_t *fmt, ...) {
     assert(fmt != NULL);
     va_list va;
     va_start(va, fmt);
@@ -273,15 +271,16 @@ expression *test_parser::error(const wchar_t *fmt, ...) {
     return NULL;
 }
 
-expression *test_parser::parse_unary_expression(unsigned int start, unsigned int end) {
+unique_ptr 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) {
-        expr_ref_t subject(parse_unary_expression(start + 1, end));
+        unique_ptr subject(parse_unary_expression(start + 1, end));
         if (subject.get()) {
-            return new unary_operator(tok, range_t(start, subject->range.end), subject);
+            return make_unique(tok, range_t(start, subject->range.end),
+                                               move(subject));
         }
         return NULL;
     }
@@ -289,10 +288,11 @@ expression *test_parser::parse_unary_expression(unsigned int start, unsigned int
 }
 
 /// Parse a combining expression (AND, OR).
-expression *test_parser::parse_combining_expression(unsigned int start, unsigned int end) {
+unique_ptr test_parser::parse_combining_expression(unsigned int start,
+                                                               unsigned int end) {
     if (start >= end) return NULL;
 
-    std::vector subjects;
+    std::vector> subjects;
     std::vector combiners;
     unsigned int idx = start;
     bool first = true;
@@ -313,7 +313,7 @@ expression *test_parser::parse_combining_expression(unsigned int start, unsigned
         }
 
         // Parse another expression.
-        expression *expr = parse_unary_expression(idx, end);
+        unique_ptr expr = parse_unary_expression(idx, end);
         if (!expr) {
             add_error(L"Missing argument at index %u", idx);
             if (!first) {
@@ -325,7 +325,7 @@ expression *test_parser::parse_combining_expression(unsigned int start, unsigned
 
         // Go to the end of this expression.
         idx = expr->range.end;
-        subjects.push_back(expr);
+        subjects.push_back(move(expr));
         first = false;
     }
 
@@ -334,10 +334,11 @@ expression *test_parser::parse_combining_expression(unsigned int start, unsigned
     }
     // 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);
+    return make_unique(test_combine_and, range_t(start, idx), move(subjects),
+                                             move(combiners));
 }
 
-expression *test_parser::parse_unary_primary(unsigned int start, unsigned int end) {
+unique_ptr 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);
@@ -350,10 +351,10 @@ expression *test_parser::parse_unary_primary(unsigned int start, unsigned int en
     const token_info_t *info = token_for_string(arg(start));
     if (!(info->flags & UNARY_PRIMARY)) return NULL;
 
-    return new unary_primary(info->tok, range_t(start, start + 2), arg(start + 1));
+    return make_unique(info->tok, range_t(start, start + 2), arg(start + 1));
 }
 
-expression *test_parser::parse_just_a_string(unsigned int start, unsigned int end) {
+unique_ptr 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.
 
@@ -369,48 +370,10 @@ expression *test_parser::parse_just_a_string(unsigned int start, unsigned int en
 
     // 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));
+    return make_unique(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) {
-        return error(L"Missing argument at index %u", start);
-    }
-
-    // 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.
-    const token_info_t *info = token_for_string(arg(start));
-    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.
-        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.
-        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) {
-        return error(L"Missing argument at index %u", arg_idx);
-    }
-
-    return new unary_primary(info->tok, range_t(start, arg_idx + 1), arg(arg_idx));
-}
-#endif
-
-expression *test_parser::parse_binary_primary(unsigned int start, unsigned int end) {
+unique_ptr 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) {
@@ -422,10 +385,11 @@ expression *test_parser::parse_binary_primary(unsigned int start, unsigned int e
     const token_info_t *info = token_for_string(arg(start + 1));
     if (!(info->flags & BINARY_PRIMARY)) return NULL;
 
-    return new binary_primary(info->tok, range_t(start, start + 3), arg(start), arg(start + 2));
+    return make_unique(info->tok, range_t(start, start + 3), arg(start),
+                                       arg(start + 2));
 }
 
-expression *test_parser::parse_parenthentical(unsigned int start, unsigned int end) {
+unique_ptr 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;
 
@@ -434,9 +398,8 @@ expression *test_parser::parse_parenthentical(unsigned int start, unsigned int e
     if (open_paren->tok != test_paren_open) return NULL;
 
     // Parse a subexpression.
-    expression *subexr_ptr = parse_expression(start + 1, end);
-    if (!subexr_ptr) return NULL;
-    expr_ref_t subexpr(subexr_ptr);
+    unique_ptr subexpr = parse_expression(start + 1, end);
+    if (!subexpr) return NULL;
 
     // Parse a close paren.
     unsigned close_index = subexpr->range.end;
@@ -450,15 +413,16 @@ expression *test_parser::parse_parenthentical(unsigned int start, unsigned int e
     }
 
     // Success.
-    return new parenthetical_expression(test_paren_open, range_t(start, close_index + 1), subexpr);
+    return make_unique(test_paren_open, range_t(start, close_index + 1),
+                                                 move(subexpr));
 }
 
-expression *test_parser::parse_primary(unsigned int start, unsigned int end) {
+unique_ptr 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;
+    unique_ptr 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);
@@ -467,24 +431,24 @@ expression *test_parser::parse_primary(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) {
+unique_ptr test_parser::parse_3_arg_expression(unsigned int start, unsigned int end) {
     assert(end - start == 3);
-    expression *result = NULL;
+    unique_ptr result = NULL;
 
     const token_info_t *center_token = token_for_string(arg(start + 1));
     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) {
-        expr_ref_t left(parse_unary_expression(start, start + 1));
-        expr_ref_t right(parse_unary_expression(start + 2, start + 3));
+        unique_ptr left(parse_unary_expression(start, start + 1));
+        unique_ptr right(parse_unary_expression(start + 2, start + 3));
         if (left.get() && right.get()) {
             // Transfer ownership to the vector of subjects.
-            std::vector combiners(1, center_token->tok);
-            std::vector subjects;
-            subjects.push_back(left.release());
-            subjects.push_back(right.release());
-            result = new combining_expression(center_token->tok, range_t(start, end), subjects,
-                                              combiners);
+            std::vector combiners = {center_token->tok};
+            std::vector> subjects;
+            subjects.push_back(move(left));
+            subjects.push_back(move(right));
+            result = make_unique(center_token->tok, range_t(start, end),
+                                                       move(subjects), move(combiners));
         }
     } else {
         result = parse_unary_expression(start, end);
@@ -492,15 +456,16 @@ expression *test_parser::parse_3_arg_expression(unsigned int start, unsigned int
     return result;
 }
 
-expression *test_parser::parse_4_arg_expression(unsigned int start, unsigned int end) {
+unique_ptr test_parser::parse_4_arg_expression(unsigned int start, unsigned int end) {
     assert(end - start == 4);
-    expression *result = NULL;
+    unique_ptr result = NULL;
 
     token_t first_token = token_for_string(arg(start))->tok;
     if (first_token == test_bang) {
-        expr_ref_t subject(parse_3_arg_expression(start + 1, end));
+        unique_ptr subject(parse_3_arg_expression(start + 1, end));
         if (subject.get()) {
-            result = new unary_operator(first_token, range_t(start, subject->range.end), subject);
+            result = make_unique(first_token, range_t(start, subject->range.end),
+                                                 move(subject));
         }
     } else if (first_token == test_paren_open) {
         result = parse_parenthentical(start, end);
@@ -510,7 +475,7 @@ expression *test_parser::parse_4_arg_expression(unsigned int start, unsigned int
     return result;
 }
 
-expression *test_parser::parse_expression(unsigned int start, unsigned int end) {
+unique_ptr test_parser::parse_expression(unsigned int start, unsigned int end) {
     if (start >= end) {
         return error(L"Missing argument at index %u", start);
     }
@@ -537,17 +502,19 @@ expression *test_parser::parse_expression(unsigned int start, unsigned int end)
     }
 }
 
-expression *test_parser::parse_args(const wcstring_list_t &args, wcstring &err) {
+unique_ptr test_parser::parse_args(const wcstring_list_t &args, wcstring &err,
+                                               wchar_t *program_name) {
     // 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());
+    unique_ptr result = parser.parse_expression(0, (unsigned int)args.size());
 
     // Handle errors.
     // For now we only show the first error.
     if (!parser.errors.empty()) {
-        err.append(L"test: ");
+        err.append(program_name);
+        err.append(L": ");
         err.append(parser.errors.at(0));
         err.push_back(L'\n');
     }
@@ -558,12 +525,10 @@ expression *test_parser::parse_args(const wcstring_list_t &args, wcstring &err)
         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",
+                append_format(err, L"%ls: unexpected argument at index %lu: '%ls'\n", program_name,
                               (unsigned long)result->range.end, args.at(result->range.end).c_str());
             }
-
-            delete result;
-            result = NULL;
+            result.reset(NULL);
         }
     }
 
@@ -636,12 +601,14 @@ bool parenthetical_expression::evaluate(wcstring_list_t &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) {
-    const wchar_t *str = arg.c_str();
-    wchar_t *endptr = NULL;
-    *out = wcstoll(str, &endptr, 10);
-    return endptr && *endptr == L'\0';
+// which allows for leading + and -, and whitespace. This is consistent, albeit a bit more lenient
+// since we allow trailing whitespace, with other implementations such as bash.
+static bool parse_number(const wcstring &arg, long long *out, wcstring_list_t &errors) {
+    *out = fish_wcstoll(arg.c_str());
+    if (errno) {
+        errors.push_back(format_string(_(L"invalid integer '%ls'"), arg.c_str()));
+    }
+    return !errno;
 }
 
 static bool binary_primary_evaluate(test_expressions::token_t token, const wcstring &left,
@@ -656,28 +623,28 @@ static bool binary_primary_evaluate(test_expressions::token_t token, const wcstr
             return left != right;
         }
         case test_number_equal: {
-            return parse_number(left, &left_num) && parse_number(right, &right_num) &&
-                   left_num == right_num;
+            return parse_number(left, &left_num, errors) &&
+                   parse_number(right, &right_num, errors) && left_num == right_num;
         }
         case test_number_not_equal: {
-            return parse_number(left, &left_num) && parse_number(right, &right_num) &&
-                   left_num != right_num;
+            return parse_number(left, &left_num, errors) &&
+                   parse_number(right, &right_num, errors) && left_num != right_num;
         }
         case test_number_greater: {
-            return parse_number(left, &left_num) && parse_number(right, &right_num) &&
-                   left_num > right_num;
+            return parse_number(left, &left_num, errors) &&
+                   parse_number(right, &right_num, errors) && left_num > right_num;
         }
         case test_number_greater_equal: {
-            return parse_number(left, &left_num) && parse_number(right, &right_num) &&
-                   left_num >= right_num;
+            return parse_number(left, &left_num, errors) &&
+                   parse_number(right, &right_num, errors) && left_num >= right_num;
         }
         case test_number_lesser: {
-            return parse_number(left, &left_num) && parse_number(right, &right_num) &&
-                   left_num < right_num;
+            return parse_number(left, &left_num, errors) &&
+                   parse_number(right, &right_num, errors) && left_num < right_num;
         }
         case test_number_lesser_equal: {
-            return parse_number(left, &left_num) && parse_number(right, &right_num) &&
-                   left_num <= right_num;
+            return parse_number(left, &left_num, errors) &&
+                   parse_number(right, &right_num, errors) && left_num <= right_num;
         }
         default: {
             errors.push_back(format_string(L"Unknown token type in %s", __func__));
@@ -730,7 +697,7 @@ static bool unary_primary_evaluate(test_expressions::token_t token, const wcstri
             return !wstat(arg, &buf) && buf.st_size > 0;
         }
         case test_filedesc_t: {  // "-t", whether the fd is associated with a terminal
-            return parse_number(arg, &num) && num == (int)num && isatty((int)num);
+            return parse_number(arg, &num, errors) && num == (int)num && isatty((int)num);
         }
         case test_fileperm_r: {  // "-r", read permission
             return !waccess(arg, R_OK);
@@ -771,7 +738,8 @@ int builtin_test(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
     if (!argv[0]) return BUILTIN_TEST_FAIL;
 
     // Whether we are invoked with bracket '[' or not.
-    const bool is_bracket = !wcscmp(argv[0], L"[");
+    wchar_t *program_name = argv[0];
+    const bool is_bracket = !wcscmp(program_name, L"[");
 
     size_t argc = 0;
     while (argv[argc + 1]) argc++;
@@ -780,7 +748,7 @@ int builtin_test(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
     // 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.
+            // Ignore the closing bracket from now on.
             argc--;
         } else {
             streams.err.append(L"[: the last argument must be ']'\n");
@@ -798,16 +766,16 @@ int builtin_test(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
         return args.at(0).empty() ? BUILTIN_TEST_FAIL : BUILTIN_TEST_SUCCESS;
     }
 
-    // Try parsing. If expr is not nil, we are responsible for deleting it.
+    // Try parsing
     wcstring err;
-    expression *expr = test_parser::parse_args(args, err);
+    unique_ptr expr = test_parser::parse_args(args, err, program_name);
     if (!expr) {
 #if 0
-        printf("Oops! test was given args:\n");
+        streams.err.append(L"Oops! test was given args:\n");
         for (size_t i=0; i < argc; i++) {
-            printf("\t%ls\n", args.at(i).c_str());
+            streams.err.append_format(L"\t%ls\n", args.at(i).c_str());
         }
-        printf("and returned parse error: %ls\n", err.c_str());
+        streams.err.append_format(L"and returned parse error: %ls\n", err.c_str());
 #endif
         streams.err.append(err);
         return BUILTIN_TEST_FAIL;
@@ -815,12 +783,11 @@ int builtin_test(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
 
     wcstring_list_t eval_errors;
     bool result = expr->evaluate(eval_errors);
-    if (!eval_errors.empty()) {
-        printf("test returned eval errors:\n");
+    if (!eval_errors.empty() && !should_suppress_stderr_for_tests()) {
+        streams.err.append(L"test returned eval errors:\n");
         for (size_t i = 0; i < eval_errors.size(); i++) {
-            printf("\t%ls\n", eval_errors.at(i).c_str());
+            streams.err.append_format(L"\t%ls\n", eval_errors.at(i).c_str());
         }
     }
-    delete expr;
     return result ? BUILTIN_TEST_SUCCESS : BUILTIN_TEST_FAIL;
 }
diff --git a/src/builtin_ulimit.cpp b/src/builtin_ulimit.cpp
index 5cc752982..85636ba3f 100644
--- a/src/builtin_ulimit.cpp
+++ b/src/builtin_ulimit.cpp
@@ -2,13 +2,14 @@
 #include "config.h"  // IWYU pragma: keep
 
 #include 
+#include 
 #include 
-#include 
 
 #include "builtin.h"
 #include "common.h"
 #include "fallback.h"  // IWYU pragma: keep
 #include "io.h"
+#include "proc.h"
 #include "util.h"
 #include "wgetopt.h"
 #include "wutil.h"  // IWYU pragma: keep
@@ -120,14 +121,11 @@ static const wchar_t *get_desc(int what) {
 
 /// 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) {
+static int set_limit(int resource, int hard, int soft, rlim_t value, io_streams_t &streams) {
     struct rlimit ls;
+
     getrlimit(resource, &ls);
-
-    if (hard) {
-        ls.rlim_max = value;
-    }
-
+    if (hard) ls.rlim_max = value;
     if (soft) {
         ls.rlim_cur = value;
 
@@ -139,185 +137,169 @@ static int set(int resource, int hard, int soft, rlim_t value, io_streams_t &str
     }
 
     if (setrlimit(resource, &ls)) {
-        if (errno == EPERM)
+        if (errno == EPERM) {
             streams.err.append_format(
                 L"ulimit: Permission denied when changing resource of type '%ls'\n",
                 get_desc(resource));
-        else
+        } else {
             builtin_wperror(L"ulimit", streams);
-        return 1;
+        }
+        return STATUS_BUILTIN_ERROR;
     }
-    return 0;
+    return STATUS_BUILTIN_OK;
 }
 
 /// 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 what = RLIMIT_FSIZE;
-    int report_all = 0;
-
+    wchar_t *cmd = argv[0];
     int argc = builtin_count_args(argv);
+    bool report_all = false;
+    bool hard = false;
+    bool soft = false;
+    int what = RLIMIT_FSIZE;
 
-    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;
+    const wchar_t *short_options = L":HSacdflmnstuvh";
+    const struct woption long_options[] = {{L"all", no_argument, NULL, 'a'},
+                                           {L"hard", no_argument, NULL, 'H'},
+                                           {L"soft", no_argument, NULL, 'S'},
+                                           {L"core-size", no_argument, NULL, 'c'},
+                                           {L"data-size", no_argument, NULL, 'd'},
+                                           {L"file-size", no_argument, NULL, 'f'},
+                                           {L"lock-size", no_argument, NULL, 'l'},
+                                           {L"resident-set-size", no_argument, NULL, 'm'},
+                                           {L"file-descriptor-count", no_argument, NULL, 'n'},
+                                           {L"stack-size", no_argument, NULL, 's'},
+                                           {L"cpu-time", no_argument, NULL, 't'},
+                                           {L"process-count", no_argument, NULL, 'u'},
+                                           {L"virtual-memory-size", no_argument, NULL, 'v'},
+                                           {L"help", no_argument, NULL, 'h'},
+                                           {NULL, 0, NULL, 0}};
 
+    int opt;
+    wgetopter_t w;
+    while ((opt = w.wgetopt_long(argc, argv, short_options, long_options, NULL)) != -1) {
         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 'a': {
+                report_all = true;
                 break;
             }
-            case L'H': {
-                hard = 1;
+            case 'H': {
+                hard = true;
                 break;
             }
-            case L'S': {
-                soft = 1;
+            case 'S': {
+                soft = true;
                 break;
             }
-            case L'c': {
+            case 'c': {
                 what = RLIMIT_CORE;
                 break;
             }
-            case L'd': {
+            case 'd': {
                 what = RLIMIT_DATA;
                 break;
             }
-            case L'f': {
+            case 'f': {
                 what = RLIMIT_FSIZE;
                 break;
             }
 #ifdef RLIMIT_MEMLOCK
-            case L'l': {
+            case 'l': {
                 what = RLIMIT_MEMLOCK;
                 break;
             }
 #endif
 #ifdef RLIMIT_RSS
-            case L'm': {
+            case 'm': {
                 what = RLIMIT_RSS;
                 break;
             }
 #endif
-            case L'n': {
+            case 'n': {
                 what = RLIMIT_NOFILE;
                 break;
             }
-            case L's': {
+            case 's': {
                 what = RLIMIT_STACK;
                 break;
             }
-            case L't': {
+            case 't': {
                 what = RLIMIT_CPU;
                 break;
             }
 #ifdef RLIMIT_NPROC
-            case L'u': {
+            case 'u': {
                 what = RLIMIT_NPROC;
                 break;
             }
 #endif
 #ifdef RLIMIT_AS
-            case L'v': {
+            case 'v': {
                 what = RLIMIT_AS;
                 break;
             }
 #endif
-            case L'h': {
-                builtin_print_help(parser, streams, argv[0], streams.out);
+            case 'h': {
+                builtin_print_help(parser, streams, cmd, streams.out);
                 return 0;
             }
-            case L'?': {
-                builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
-                return 1;
+            case ':': {
+                streams.err.append_format(BUILTIN_ERR_MISSING, cmd, argv[w.woptind - 1]);
+                return STATUS_BUILTIN_ERROR;
+            }
+            case '?': {
+                builtin_unknown_option(parser, streams, cmd, argv[w.woptind - 1]);
+                return STATUS_BUILTIN_ERROR;
             }
             default: {
-                DIE("unexpected opt");
+                DIE("unexpected retval from wgetopt_long");
                 break;
             }
         }
     }
 
     if (report_all) {
-        if (argc - w.woptind == 0) {
-            print_all(hard, streams);
-        } else {
-            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;
+        print_all(hard, streams);
+        return STATUS_BUILTIN_OK;
     }
 
     int arg_count = argc - w.woptind;
     if (arg_count == 0) {
         // Show current limit value.
         print(what, hard, streams);
-    } else if (arg_count == 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;
-        }
-
-        if (wcscasecmp(argv[w.woptind], L"unlimited") == 0) {
-            new_limit = RLIM_INFINITY;
-        } else if (wcscasecmp(argv[w.woptind], L"hard") == 0) {
-            new_limit = get(what, 1);
-        } else if (wcscasecmp(argv[w.woptind], L"soft") == 0) {
-            new_limit = get(what, soft);
-        } 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]);
-                builtin_print_help(parser, streams, argv[0], streams.err);
-                return 1;
-            }
-            new_limit *= get_multiplier(what);
-        }
-
-        return set(what, hard, soft, new_limit, streams);
+        return STATUS_BUILTIN_OK;
+    } else if (arg_count != 1) {
+        streams.err.append_format(BUILTIN_ERR_TOO_MANY_ARGUMENTS, cmd);
+        builtin_print_help(parser, streams, cmd, streams.err);
+        return STATUS_BUILTIN_ERROR;
     }
 
-    streams.err.append(argv[0]);
-    streams.err.append(L": Too many arguments\n");
-    builtin_print_help(parser, streams, argv[0], streams.err);
-    return 1;
+    // Change current limit value.
+    if (!hard && !soft) {
+        // Set both hard and soft limits if neither was specified.
+        hard = soft = true;
+    }
+
+    rlim_t new_limit;
+    if (*argv[w.woptind] == L'\0') {
+        streams.err.append_format(_(L"%ls: New limit cannot be an empty string\n"), cmd);
+        builtin_print_help(parser, streams, cmd, streams.err);
+        return STATUS_BUILTIN_ERROR;
+    } else if (wcscasecmp(argv[w.woptind], L"unlimited") == 0) {
+        new_limit = RLIM_INFINITY;
+    } else if (wcscasecmp(argv[w.woptind], L"hard") == 0) {
+        new_limit = get(what, 1);
+    } else if (wcscasecmp(argv[w.woptind], L"soft") == 0) {
+        new_limit = get(what, soft);
+    } else {
+        new_limit = fish_wcstol(argv[w.woptind]);
+        if (errno) {
+            streams.err.append_format(_(L"%ls: Invalid limit '%ls'\n"), cmd, argv[w.woptind]);
+            builtin_print_help(parser, streams, cmd, streams.err);
+            return STATUS_BUILTIN_ERROR;
+        }
+        new_limit *= get_multiplier(what);
+    }
+
+    return set_limit(what, hard, soft, new_limit, streams);
 }
diff --git a/src/color.h b/src/color.h
index 05f1fa930..592fdc30b 100644
--- a/src/color.h
+++ b/src/color.h
@@ -19,8 +19,14 @@ class rgb_color_t {
     unsigned char type : 4;
 
     // Flags
-    enum { flag_bold = 1 << 0, flag_underline = 1 << 1 };
-    unsigned char flags : 4;
+    enum {
+        flag_bold = 1 << 0,
+        flag_underline = 1 << 1,
+        flag_italics = 1 << 2,
+        flag_dim = 1 << 3,
+        flag_reverse = 1 << 4
+    };
+    unsigned char flags : 5;
 
     union {
         unsigned char name_idx;  // 0-10
@@ -117,6 +123,39 @@ class rgb_color_t {
             flags &= ~flag_underline;
     }
 
+    /// Returns whether the color is italics.
+    bool is_italics() const { return static_cast(flags & flag_italics); }
+
+    /// Set whether the color is italics.
+    void set_italics(bool x) {
+        if (x)
+            flags |= flag_italics;
+        else
+            flags &= ~flag_italics;
+    }
+
+    /// Returns whether the color is dim.
+    bool is_dim() const { return static_cast(flags & flag_dim); }
+
+    /// Set whether the color is dim.
+    void set_dim(bool x) {
+        if (x)
+            flags |= flag_dim;
+        else
+            flags &= ~flag_dim;
+    }
+
+    /// Returns whether the color is reverse.
+    bool is_reverse() const { return static_cast(flags & flag_reverse); }
+
+    /// Set whether the color is reverse.
+    void set_reverse(bool x) {
+        if (x)
+            flags |= flag_reverse;
+        else
+            flags &= ~flag_reverse;
+    }
+
     /// Compare two colors for equality.
     bool operator==(const rgb_color_t &other) const {
         return type == other.type && !memcmp(&data, &other.data, sizeof data);
diff --git a/src/common.cpp b/src/common.cpp
index 76d2b752a..2a858c01f 100644
--- a/src/common.cpp
+++ b/src/common.cpp
@@ -5,8 +5,8 @@
 #include 
 #include 
 #include 
+#include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -32,12 +32,14 @@
 #include   // IWYU pragma: keep
 
 #include "common.h"
+#include "env.h"
 #include "expand.h"
 #include "fallback.h"  // IWYU pragma: keep
+#include "proc.h"
 #include "wildcard.h"
 #include "wutil.h"  // IWYU pragma: keep
 
-#define NOT_A_WCHAR (static_cast(WEOF))
+constexpr wint_t NOT_A_WCHAR = static_cast(WEOF);
 
 struct termios shell_modes;
 
@@ -61,9 +63,9 @@ static pid_t initial_fg_process_group = -1;
 /// This struct maintains the current state of the terminal size. It is updated on demand after
 /// receiving a SIGWINCH. Do not touch this struct directly, it's managed with a rwlock. Use
 /// common_get_width()/common_get_height().
-static struct winsize termsize;
-static volatile bool termsize_valid;
-static rwlock_t termsize_rwlock;
+static pthread_mutex_t termsize_lock = PTHREAD_MUTEX_INITIALIZER;
+static struct winsize termsize = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
+static volatile bool termsize_valid = false;
 
 static char *wcs2str_internal(const wchar_t *in, char *out);
 static void debug_shared(const wchar_t msg_level, const wcstring &msg);
@@ -499,17 +501,27 @@ __sentinel bool contains_internal(const wcstring &needle, int vararg_handle, ...
 }
 
 long read_blocked(int fd, void *buf, size_t count) {
-    ssize_t res;
-    sigset_t chldset, oldset;
+    long bytes_read = 0;
 
-    sigemptyset(&chldset);
-    sigaddset(&chldset, SIGCHLD);
-    VOMIT_ON_FAILURE(pthread_sigmask(SIG_BLOCK, &chldset, &oldset));
-    res = read(fd, buf, count);
-    VOMIT_ON_FAILURE(pthread_sigmask(SIG_SETMASK, &oldset, NULL));
-    return res;
+    while (count) {
+        ssize_t res = read(fd, (char *)buf + bytes_read, count);
+        if (res == 0) {
+            break;
+        } else if (res == -1) {
+            if (errno == EINTR) continue;
+            if (errno == EAGAIN) return bytes_read ? bytes_read : -1;
+            return -1;
+        } else {
+            bytes_read += res;
+            count -= res;
+        }
+    }
+
+    return bytes_read;
 }
 
+/// Loop a write request while failure is non-critical. Return -1 and set errno in case of critical
+/// error.
 ssize_t write_loop(int fd, const char *buff, size_t count) {
     size_t out_cum = 0;
     while (out_cum < count) {
@@ -533,12 +545,14 @@ ssize_t read_loop(int fd, void *buff, size_t count) {
     return result;
 }
 
+bool should_suppress_stderr_for_tests() {
+    // Hack to not print error messages in the tests.
+    return program_name && !wcscmp(program_name, TESTS_PROGRAM_NAME);
+}
+
 static bool should_debug(int level) {
     if (level > debug_level) return false;
-
-    // Hack to not print error messages in the tests.
-    if (program_name && !wcscmp(program_name, L"(ignore)")) return false;
-
+    if (should_suppress_stderr_for_tests()) return false;
     return true;
 }
 
@@ -603,7 +617,7 @@ void debug_safe(int level, const char *msg, const char *param1, const char *para
                                   param7, param8, param9, param10, param11, param12};
     if (!msg) return;
 
-    // Can't call printf, that may allocate memory Just call write() over and over.
+    // Can't call fwprintf, that may allocate memory Just call write() over and over.
     if (level > debug_level) return;
     int errno_old = errno;
 
@@ -828,7 +842,7 @@ static void escape_string_internal(const wchar_t *orig_in, size_t in_len, wcstri
                     need_escape = need_complex_escape = 1;
                     break;
                 }
-                case L'\x1b': {
+                case L'\e': {
                     out += L'\\';
                     out += L'e';
                     need_escape = need_complex_escape = 1;
@@ -936,8 +950,7 @@ wcstring escape_string(const wcstring &in, escape_flags_t flags) {
 
 /// Helper to return the last character in a string, or NOT_A_WCHAR.
 static wint_t string_last_char(const wcstring &str) {
-    size_t len = str.size();
-    return len == 0 ? NOT_A_WCHAR : str.at(len - 1);
+    return str.empty() ? NOT_A_WCHAR : str.back();
 }
 
 /// Given a null terminated string starting with a backslash, read the escape as if it is unquoted,
@@ -1061,9 +1074,9 @@ size_t read_unquoted_escape(const wchar_t *input, wcstring *result, bool allow_i
             }
             break;
         }
-        // \x1b means escape.
+        // \e means escape.
         case L'e': {
-            result_char_or_none = L'\x1b';
+            result_char_or_none = L'\e';
             break;
         }
         // \f means form feed.
@@ -1215,12 +1228,12 @@ static bool unescape_string_internal(const wchar_t *const input, const size_t in
                 }
                 case L'\'': {
                     mode = mode_single_quotes;
-                    to_append_or_none = unescape_special ? INTERNAL_SEPARATOR : NOT_A_WCHAR;
+                    to_append_or_none = unescape_special ? wint_t(INTERNAL_SEPARATOR) : NOT_A_WCHAR;
                     break;
                 }
                 case L'\"': {
                     mode = mode_double_quotes;
-                    to_append_or_none = unescape_special ? INTERNAL_SEPARATOR : NOT_A_WCHAR;
+                    to_append_or_none = unescape_special ? wint_t(INTERNAL_SEPARATOR) : NOT_A_WCHAR;
                     break;
                 }
                 default: { break; }
@@ -1254,14 +1267,14 @@ static bool unescape_string_internal(const wchar_t *const input, const size_t in
                     }
                 }
             } else if (c == L'\'') {
-                to_append_or_none = unescape_special ? INTERNAL_SEPARATOR : NOT_A_WCHAR;
+                to_append_or_none = unescape_special ? wint_t(INTERNAL_SEPARATOR) : NOT_A_WCHAR;
                 mode = mode_unquoted;
             }
         } else if (mode == mode_double_quotes) {
             switch (c) {
                 case L'"': {
                     mode = mode_unquoted;
-                    to_append_or_none = unescape_special ? INTERNAL_SEPARATOR : NOT_A_WCHAR;
+                    to_append_or_none = unescape_special ? wint_t(INTERNAL_SEPARATOR) : NOT_A_WCHAR;
                     break;
                 }
                 case '\\': {
@@ -1316,7 +1329,7 @@ static bool unescape_string_internal(const wchar_t *const input, const size_t in
 
     // Return the string by reference, and then success.
     if (!errored) {
-        output_str->swap(result);
+        *output_str = std::move(result);
     }
     return !errored;
 }
@@ -1326,7 +1339,7 @@ bool unescape_string_in_place(wcstring *str, unescape_flags_t escape_special) {
     wcstring output;
     bool success = unescape_string_internal(str->c_str(), str->size(), &output, escape_special);
     if (success) {
-        str->swap(output);
+        *str = std::move(output);
     }
     return success;
 }
@@ -1343,32 +1356,97 @@ bool unescape_string(const wcstring &input, wcstring *output, unescape_flags_t e
     return success;
 }
 
-void common_handle_winch(int signal) {
-    // Don't run ioctl() here, it's not safe to use in signals.
-    UNUSED(signal);
+/// Used to invalidate our idea of having a valid window size. This can occur when either the
+/// COLUMNS or LINES variables are changed. This is also invoked when the shell regains control of
+/// the tty since it is possible the terminal size changed while an external command was running.
+void invalidate_termsize(bool invalidate_vars) {
     termsize_valid = false;
+    if (invalidate_vars) {
+        termsize.ws_col = termsize.ws_row = USHRT_MAX;
+    }
+}
+
+/// Handle SIGWINCH. This is also invoked when the shell regains control of the tty since it is
+/// possible the terminal size changed while an external command was running.
+void common_handle_winch(int signal) {
+    // Don't run ioctl() here. Technically it's not safe to use in signals although in practice it
+    // is safe on every platform I've used. But we want to be conservative on such matters.
+    UNUSED(signal);
+    invalidate_termsize(false);
+}
+
+/// Validate the new terminal size. Fallback to the env vars if necessary. Ensure the values are
+/// sane and if not fallback to a default of 80x24.
+static void validate_new_termsize(struct winsize *new_termsize) {
+    if (new_termsize->ws_col == 0 || new_termsize->ws_row == 0) {
+#ifdef HAVE_WINSIZE
+        if (shell_is_interactive()) {
+            debug(1, _(L"Current terminal parameters have rows and/or columns set to zero."));
+            debug(1, _(L"The stty command can be used to correct this "
+                       L"(e.g., stty rows 80 columns 24)."));
+        }
+#endif
+        // Fallback to the environment vars.
+        env_var_t col_var = env_get_string(L"COLUMNS");
+        env_var_t row_var = env_get_string(L"LINES");
+        if (!col_var.missing_or_empty() && !row_var.missing_or_empty()) {
+            // Both vars have to have valid values.
+            int col = fish_wcstoi(col_var.c_str());
+            bool col_ok = errno == 0 && col > 0 && col <= USHRT_MAX;
+            int row = fish_wcstoi(row_var.c_str());
+            bool row_ok = errno == 0 && row > 0 && row <= USHRT_MAX;
+            if (col_ok && row_ok) {
+                new_termsize->ws_col = col;
+                new_termsize->ws_row = row;
+            }
+        }
+    }
+
+    if (new_termsize->ws_col < MIN_TERM_COL || new_termsize->ws_row < MIN_TERM_ROW) {
+        if (shell_is_interactive()) {
+            debug(1, _(L"Current terminal parameters set terminal size to unreasonable value."));
+            debug(1, _(L"Defaulting terminal size to 80x24."));
+        }
+        new_termsize->ws_col = DFLT_TERM_COL;
+        new_termsize->ws_row = DFLT_TERM_ROW;
+    }
+}
+
+/// Export the new terminal size as env vars and to the kernel if possible.
+static void export_new_termsize(struct winsize *new_termsize) {
+    wchar_t buf[64];
+    swprintf(buf, 64, L"%d", (int)new_termsize->ws_col);
+    env_set(L"COLUMNS", buf, ENV_EXPORT | ENV_GLOBAL);
+    swprintf(buf, 64, L"%d", (int)new_termsize->ws_row);
+    env_set(L"LINES", buf, ENV_EXPORT | ENV_GLOBAL);
+
+#ifdef HAVE_WINSIZE
+    ioctl(STDOUT_FILENO, TIOCSWINSZ, new_termsize);
+#endif
 }
 
 /// Updates termsize as needed, and returns a copy of the winsize.
-static struct winsize get_current_winsize() {
-#ifndef HAVE_WINSIZE
-    struct winsize retval = {0};
-    retval.ws_col = 80;
-    retval.ws_row = 24;
-    return retval;
-#endif
-    scoped_rwlock guard(termsize_rwlock, true);
-    struct winsize retval = termsize;
-    if (!termsize_valid) {
-        struct winsize size;
-        if (ioctl(1, TIOCGWINSZ, &size) == 0) {
-            retval = size;
-            guard.upgrade();
-            termsize = retval;
-        }
+struct winsize get_current_winsize() {
+    scoped_lock guard(termsize_lock);
+
+    if (termsize_valid) return termsize;
+
+    struct winsize new_termsize = {0, 0, 0, 0};
+#ifdef HAVE_WINSIZE
+    errno = 0;
+    if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &new_termsize) != -1 &&
+        new_termsize.ws_col == termsize.ws_col && new_termsize.ws_row == termsize.ws_row) {
         termsize_valid = true;
+        return termsize;
     }
-    return retval;
+#endif
+
+    validate_new_termsize(&new_termsize);
+    export_new_termsize(&new_termsize);
+    termsize.ws_col = new_termsize.ws_col;
+    termsize.ws_row = new_termsize.ws_row;
+    termsize_valid = true;
+    return termsize;
 }
 
 int common_get_width() { return get_current_winsize().ws_col; }
@@ -1529,9 +1607,8 @@ int create_directory(const wcstring &d) {
 }
 
 __attribute__((noinline)) void bugreport() {
-    debug(1, _(L"This is a bug. Break on bugreport to debug. "
-               L"If you can reproduce it, please send a bug report to %s."),
-          PACKAGE_BUGREPORT);
+    debug(0, _(L"This is a bug. Break on bugreport to debug."));
+    debug(0, _(L"If you can reproduce it, please send a bug report to %s."), PACKAGE_BUGREPORT);
 }
 
 wcstring format_size(long long sz) {
@@ -1687,7 +1764,7 @@ bool is_forked_child(void) {
 
     bool is_child_of_fork = (getpid() != initial_pid);
     if (is_child_of_fork) {
-        printf("Uh-oh: %d\n", getpid());
+        debug(0, L"Uh-oh: getpid() != initial_pid: %d != %d\n", getpid(), initial_pid);
         while (1) sleep(10000);
     }
     return is_child_of_fork;
@@ -1706,7 +1783,9 @@ void restore_term_foreground_process_group(void) {
     if (initial_fg_process_group != -1) {
         // This is called during shutdown and from a signal handler. We don't bother to complain on
         // failure.
-        tcsetpgrp(STDIN_FILENO, initial_fg_process_group);
+        if (tcsetpgrp(STDIN_FILENO, initial_fg_process_group) == -1 && errno == ENOTTY) {
+            redirect_tty_output();
+        }
     }
 }
 
@@ -1717,28 +1796,24 @@ bool is_main_thread() {
 
 void assert_is_main_thread(const char *who) {
     if (!is_main_thread() && !thread_asserts_cfg_for_testing) {
-        fprintf(stderr,
-                "Warning: %s called off of main thread. Break on debug_thread_error to debug.\n",
-                who);
+        debug(0, "%s called off of main thread.", who);
+        debug(0, "Break on debug_thread_error to debug.");
         debug_thread_error();
     }
 }
 
 void assert_is_not_forked_child(const char *who) {
     if (is_forked_child()) {
-        fprintf(stderr,
-                "Warning: %s called in a forked child. Break on debug_thread_error to debug.\n",
-                who);
+        debug(0, "%s called in a forked child.", who);
+        debug(0, "Break on debug_thread_error to debug.");
         debug_thread_error();
     }
 }
 
 void assert_is_background_thread(const char *who) {
     if (is_main_thread() && !thread_asserts_cfg_for_testing) {
-        fprintf(stderr,
-                "Warning: %s called on the main thread (may block!). Break on debug_thread_error "
-                "to debug.\n",
-                who);
+        debug(0, "%s called on the main thread (may block!).", who);
+        debug(0, "Break on debug_thread_error to debug.");
         debug_thread_error();
     }
 }
@@ -1746,10 +1821,8 @@ void assert_is_background_thread(const char *who) {
 void assert_is_locked(void *vmutex, const char *who, const char *caller) {
     pthread_mutex_t *mutex = static_cast(vmutex);
     if (0 == pthread_mutex_trylock(mutex)) {
-        fprintf(stderr,
-                "Warning: %s is not locked when it should be in '%s'. Break on debug_thread_error "
-                "to debug.\n",
-                who, caller);
+        debug(0, "%s is not locked when it should be in '%s'", who, caller);
+        debug(0, "Break on debug_thread_error to debug.");
         debug_thread_error();
         pthread_mutex_unlock(mutex);
     }
@@ -1931,12 +2004,12 @@ long convert_digit(wchar_t d, int base) {
     return res;
 }
 
-// Test if the specified character is in a range that fish uses interally to store special tokens.
-//
-// NOTE: This is used when tokenizing the input. It is also used when reading input, before
-// tokenization, to replace such chars with REPLACEMENT_WCHAR if they're not part of a quoted
-// string. We don't want external input to be able to feed reserved characters into our lexer/parser
-// or code evaluator.
+/// Test if the specified character is in a range that fish uses interally to store special tokens.
+///
+/// NOTE: This is used when tokenizing the input. It is also used when reading input, before
+/// tokenization, to replace such chars with REPLACEMENT_WCHAR if they're not part of a quoted
+/// string. We don't want external input to be able to feed reserved characters into our
+/// lexer/parser or code evaluator.
 //
 // TODO: Actually implement the replacement as documented above.
 bool fish_reserved_codepoint(wchar_t c) {
@@ -1944,3 +2017,14 @@ bool fish_reserved_codepoint(wchar_t c) {
            (c >= ENCODE_DIRECT_BASE && c < ENCODE_DIRECT_END) ||
            (c >= INPUT_COMMON_BASE && c < INPUT_COMMON_END);
 }
+
+/// Reopen stdin, stdout and/or stderr on /dev/null. This is invoked when we find that our tty has
+/// become invalid.
+void redirect_tty_output() {
+    struct termios t;
+    int fd = open("/dev/null", O_WRONLY);
+    if (tcgetattr(STDIN_FILENO, &t) == -1 && errno == EIO) dup2(fd, STDIN_FILENO);
+    if (tcgetattr(STDOUT_FILENO, &t) == -1 && errno == EIO) dup2(fd, STDOUT_FILENO);
+    if (tcgetattr(STDERR_FILENO, &t) == -1 && errno == EIO) dup2(fd, STDERR_FILENO);
+    close(fd);
+}
diff --git a/src/common.h b/src/common.h
index 33781f680..34edc3079 100644
--- a/src/common.h
+++ b/src/common.h
@@ -143,6 +143,26 @@ inline bool selection_direction_is_cardinal(selection_direction_t dir) {
     }
 }
 
+/// Issue a debug message with printf-style string formating and automatic line breaking. The string
+/// will begin with the string \c program_name, followed by a colon and a whitespace.
+///
+/// Because debug is often called to tell the user about an error, before using wperror to give a
+/// specific error message, debug will never ever modify the value of errno.
+///
+/// \param level the priority of the message. Lower number means higher priority. Messages with a
+/// priority_number higher than \c debug_level will be ignored..
+/// \param msg the message format string.
+///
+/// Example:
+///
+/// debug( 1, L"Pi = %.3f", M_PI );
+///
+/// will print the string 'fish: Pi = 3.141', given that debug_level is 1 or higher, and that
+/// program_name is 'fish'.
+void __attribute__((noinline)) debug(int level, const char *msg, ...)
+    __attribute__((format(printf, 2, 3)));
+void __attribute__((noinline)) debug(int level, const wchar_t *msg, ...);
+
 /// Helper macro for errors.
 #define VOMIT_ON_FAILURE(a)         \
     do {                            \
@@ -157,16 +177,16 @@ inline bool selection_direction_is_cardinal(selection_direction_t dir) {
             VOMIT_ABORT(err, #a);    \
         }                            \
     } while (0)
-#define VOMIT_ABORT(err, str)                                                                  \
-    do {                                                                                       \
-        int code = (err);                                                                      \
-        fprintf(stderr, "%s failed on line %d in file %s: %d (%s)\n", str, __LINE__, __FILE__, \
-                code, strerror(code));                                                         \
-        abort();                                                                               \
+#define VOMIT_ABORT(err, str)                                                               \
+    do {                                                                                    \
+        int code = (err);                                                                   \
+        debug(0, "%s failed on line %d in file %s: %d (%s)", str, __LINE__, __FILE__, code, \
+              strerror(code));                                                              \
+        abort();                                                                            \
     } while (0)
 
 /// Exits without invoking destructors (via _exit), useful for code after fork.
-void exit_without_destructors(int code) __attribute__((noreturn));
+[[noreturn]] void exit_without_destructors(int code);
 
 /// Save the shell mode on startup so we can restore them on exit.
 extern struct termios shell_modes;
@@ -199,21 +219,22 @@ void write_ignore(int fd, const void *buff, size_t count);
 /// the tty.
 extern bool has_working_tty_timestamps;
 
-/// This macro is used to check that an input argument is not null. It is a bit lika a non-fatal
-/// form of assert. Instead of exit-ing on failure, the current function is ended at once. The
-/// second parameter is the return value of the current function on failure.
-#define CHECK(arg, retval)                                                                \
-    if (!(arg)) {                                                                         \
-        debug(0, "function %s called with null value for argument %s. ", __func__, #arg); \
-        bugreport();                                                                      \
-        show_stackframe(L'E');                                                            \
-        return retval;                                                                    \
+/// This macro is used to check that an argument is true. It is a bit like a non-fatal form of
+/// assert. Instead of exiting on failure, the current function is ended at once. The second
+/// parameter is the return value of the current function on failure.
+#define CHECK(arg, retval)                                                               \
+    if (!(arg)) {                                                                        \
+        debug(0, "function %s called with false value for argument %s", __func__, #arg); \
+        bugreport();                                                                     \
+        show_stackframe(L'E');                                                           \
+        return retval;                                                                   \
     }
 
-/// Pause for input, then exit the program. If supported, print a backtrace first.
+// Pause for input, then exit the program. If supported, print a backtrace first.
 // The `return` will never be run  but silences oclint warnings. Especially when this is called
 // from within a `switch` block. As of the time I'm writing this oclint doesn't recognize the
 // `__attribute__((noreturn))` on the exit_without_destructors() function.
+// TODO: we use C++11 [[noreturn]] now, does that change things?
 #define FATAL_EXIT()                        \
     {                                       \
         char exit_read_buff;                \
@@ -223,11 +244,10 @@ extern bool has_working_tty_timestamps;
     }
 
 /// Exit program at once after emitting an error message.
-#define DIE(msg)                                                                      \
-    {                                                                                 \
-        fprintf(stderr, "fish: %s on line %ld of file %s, shutting down fish\n", msg, \
-                (long)__LINE__, __FILE__);                                            \
-        FATAL_EXIT();                                                                 \
+#define DIE(msg)                                                                                  \
+    {                                                                                             \
+        debug(0, "%s on line %ld of file %s, shutting down fish", msg, (long)__LINE__, __FILE__); \
+        FATAL_EXIT();                                                                             \
     }
 
 /// Exit program at once, leaving an error message about running out of memory.
@@ -240,6 +260,8 @@ extern bool has_working_tty_timestamps;
 
 /// Check if signals are blocked. If so, print an error message and return from the function
 /// performing this check.
+#define CHECK_BLOCK(retval)
+#if 0
 #define CHECK_BLOCK(retval)                                                \
     if (signal_is_blocked()) {                                             \
         debug(0, "function %s called while blocking signals. ", __func__); \
@@ -247,6 +269,7 @@ extern bool has_working_tty_timestamps;
         show_stackframe(L'E');                                             \
         return retval;                                                     \
     }
+#endif
 
 /// Shorthand for wgettext call in situations where a C-style string is needed (e.g., fwprintf()).
 #define _(wstr) wgettext(wstr).c_str()
@@ -372,6 +395,10 @@ string_fuzzy_match_t string_fuzzy_match_string(const wcstring &string,
 /// Test if a list contains a string using a linear search.
 bool list_contains_string(const wcstring_list_t &list, const wcstring &str);
 
+// Check if we are running in the test mode, where we should suppress error output
+#define TESTS_PROGRAM_NAME L"(ignore)"
+bool should_suppress_stderr_for_tests();
+
 void assert_is_main_thread(const char *who);
 #define ASSERT_IS_MAIN_THREAD_TRAMPOLINE(x) assert_is_main_thread(x)
 #define ASSERT_IS_MAIN_THREAD() ASSERT_IS_MAIN_THREAD_TRAMPOLINE(__FUNCTION__)
@@ -452,15 +479,6 @@ inline wcstring to_string(const int &x) {
     return to_string(static_cast(x));
 }
 
-// A hackish thing to simulate rvalue references in C++98. The idea is that you can define a
-// constructor to take a moved_ref and then swap() out of it.
-template 
-struct moved_ref {
-    T &val;
-
-    explicit moved_ref(T &v) : val(v) {}
-};
-
 wchar_t **make_null_terminated_array(const wcstring_list_t &lst);
 char **make_null_terminated_array(const std::vector &lst);
 
@@ -526,10 +544,16 @@ class scoped_lock {
     bool locked;
 
     // No copying.
-    scoped_lock &operator=(const scoped_lock &);
-    scoped_lock(const scoped_lock &);
+    scoped_lock &operator=(const scoped_lock &) = delete;
+    scoped_lock(const scoped_lock &)  = delete;
 
    public:
+    scoped_lock(scoped_lock &&rhs) : lock_obj(rhs.lock_obj), locked(rhs.locked) {
+        // we acquire any locked state
+        // ensure the rhs doesn't try to unlock
+        rhs.locked = false;
+    }
+
     void lock(void);
     void unlock(void);
     explicit scoped_lock(pthread_mutex_t &mutex);
@@ -543,6 +567,9 @@ class rwlock_t {
     rwlock_t() { VOMIT_ON_FAILURE_NO_ERRNO(pthread_rwlock_init(&rwlock, NULL)); }
 
     ~rwlock_t() { VOMIT_ON_FAILURE_NO_ERRNO(pthread_rwlock_destroy(&rwlock)); }
+
+    rwlock_t &operator=(const rwlock_t &) = delete;
+    rwlock_t(const rwlock_t &)  = delete;
 };
 
 // Scoped lock class for rwlocks.
@@ -552,8 +579,8 @@ class scoped_rwlock {
     bool locked_shared;
 
     // No copying.
-    scoped_rwlock &operator=(const scoped_lock &);
-    explicit scoped_rwlock(const scoped_lock &);
+    scoped_rwlock &operator=(const scoped_lock &) = delete;
+    explicit scoped_rwlock(const scoped_lock &) = delete;
 
    public:
     void lock(void);
@@ -567,6 +594,57 @@ class scoped_rwlock {
     ~scoped_rwlock();
 };
 
+// An object wrapping a scoped lock and a value
+// This is returned from owning_lock.acquire()
+// Sample usage:
+//   owning_lock locked_name;
+//   acquired_lock name = name.acquire();
+//   name.value = "derp"
+//
+// Or for simple cases:
+//   name.acquire().value = "derp"
+//
+template
+class acquired_lock {
+    scoped_lock lock;
+    acquired_lock(mutex_lock_t &lk, DATA *v) : lock(lk), value(*v)
+    {}
+
+    template
+    friend class owning_lock;
+
+    public:
+    // No copying, move only
+    acquired_lock &operator=(const acquired_lock &) = delete;
+    acquired_lock(const acquired_lock &) = delete;
+    acquired_lock(acquired_lock &&) = default;
+    acquired_lock &operator=(acquired_lock &&) = default;
+
+    DATA &value;
+};
+
+// A lock that owns a piece of data
+// Access to the data is only provided by taking the lock
+template
+class owning_lock {
+    // No copying
+    owning_lock &operator=(const scoped_lock &) = delete;
+    owning_lock(const scoped_lock &) = delete;
+    owning_lock(owning_lock &&) = default;
+    owning_lock &operator=(owning_lock &&) = default;
+
+    mutex_lock_t lock;
+    DATA data;
+
+public:
+    owning_lock(DATA d) : data(std::move(d)) {}
+    owning_lock() : data() {}
+
+    acquired_lock acquire() {
+        return {lock, &data};
+    }
+};
+
 /// A scoped manager to save the current value of some variable, and optionally set it to a new
 /// value. On destruction it restores the variable to its old value.
 ///
@@ -580,15 +658,16 @@ class scoped_push {
    public:
     explicit scoped_push(T *r) : ref(r), saved_value(*r), restored(false) {}
 
-    scoped_push(T *r, const T &new_value) : ref(r), saved_value(*r), restored(false) {
-        *r = new_value;
+    scoped_push(T *r, T new_value) : ref(r), restored(false) {
+        saved_value = std::move(*ref);
+        *ref = std::move(new_value);
     }
 
     ~scoped_push() { restore(); }
 
     void restore() {
         if (!restored) {
-            std::swap(*ref, saved_value);
+            *ref = std::move(saved_value);
             restored = true;
         }
     }
@@ -617,6 +696,16 @@ wcstring vformat_string(const wchar_t *format, va_list va_orig);
 void append_format(wcstring &str, const wchar_t *format, ...);
 void append_formatv(wcstring &str, const wchar_t *format, va_list ap);
 
+#ifdef __cpp_lib_make_unique
+using std::make_unique;
+#else
+/// make_unique implementation
+template 
+std::unique_ptr make_unique(Args &&... args) {
+    return std::unique_ptr(new T(std::forward(args)...));
+}
+#endif
+
 /// This functions returns the end of the quoted substring beginning at \c in. The type of quoting
 /// character is detemrined by examining \c in. Returns 0 on error.
 ///
@@ -654,25 +743,6 @@ ssize_t write_loop(int fd, const char *buff, size_t count);
 /// error.
 ssize_t read_loop(int fd, void *buff, size_t count);
 
-/// Issue a debug message with printf-style string formating and automatic line breaking. The string
-/// will begin with the string \c program_name, followed by a colon and a whitespace.
-///
-/// Because debug is often called to tell the user about an error, before using wperror to give a
-/// specific error message, debug will never ever modify the value of errno.
-///
-/// \param level the priority of the message. Lower number means higher priority. Messages with a
-/// priority_number higher than \c debug_level will be ignored..
-/// \param msg the message format string.
-///
-/// Example:
-///
-/// debug( 1, L"Pi = %.3f", M_PI );
-///
-/// will print the string 'fish: Pi = 3.141', given that debug_level is 1 or higher, and that
-/// program_name is 'fish'.
-void __attribute__((noinline)) debug(int level, const char *msg, ...);
-void __attribute__((noinline)) debug(int level, const wchar_t *msg, ...);
-
 /// Replace special characters with backslash escape sequences. Newline is replaced with \n, etc.
 ///
 /// \param in The string to be escaped
@@ -778,7 +848,73 @@ long convert_digit(wchar_t d, int base);
         (void)(expr); \
     } while (0)
 
-#endif
-
 // Return true if the character is in a range reserved for fish's private use.
 bool fish_reserved_codepoint(wchar_t c);
+
+/// Used for constructing mappings between enums and strings. The resulting array must be sorted
+/// according to the `str` member since str_to_enum() does a binary search. Also the last entry must
+/// have NULL for the `str` member and the default value for `val` to be returned if the string
+/// isn't found.
+template 
+struct enum_map {
+    T val;
+    const wchar_t *const str;
+};
+
+/// Given a string return the matching enum. Return the sentinal enum if no match is made. The map
+/// must be sorted by the `str` member. A binary search is twice as fast as a linear search with 16
+/// elements in the map.
+template 
+static T str_to_enum(const wchar_t *name, const enum_map map[], int len) {
+    // Ignore the sentinel value when searching as it is the "not found" value.
+    size_t left = 0, right = len - 1;
+
+    while (left < right) {
+        size_t mid = left + (right - left) / 2;
+        int cmp = wcscmp(name, map[mid].str);
+        if (cmp < 0) {
+            right = mid;  // name was smaller than mid
+        } else if (cmp > 0) {
+            left = mid + 1;  // name was larger than mid
+        } else {
+            return map[mid].val;  // found it
+        }
+    }
+    return map[len - 1].val;  // return the sentinel value
+}
+
+/// Given an enum return the matching string.
+template 
+static const wchar_t *enum_to_str(T enum_val, const enum_map map[]) {
+    for (const enum_map *entry = map; entry->str; entry++) {
+        if (enum_val == entry->val) {
+            return entry->str;
+        }
+    }
+    return NULL;
+};
+
+#if !defined(HAVE_WCSDUP) && defined(HAVE_STD__WCSDUP)
+using std::wcsdup;
+#endif
+
+#if !defined(HAVE_WCSCASECMP) && defined(HAVE_STD__WCSCASECMP)
+using std::wcscasecmp;
+#endif
+
+#if !defined(HAVE_WCSNCASECMP) && defined(HAVE_STD__WCSNCASECMP)
+using std::wcsncasecmp;
+#endif
+
+void redirect_tty_output();
+
+// Minimum allowed terminal size and default size if the detected size is not reasonable.
+#define MIN_TERM_COL 20
+#define MIN_TERM_ROW 2
+#define DFLT_TERM_COL 80
+#define DFLT_TERM_ROW 24
+#define DFLT_TERM_COL_STR L"80"
+#define DFLT_TERM_ROW_STR L"24"
+void invalidate_termsize(bool invalidate_vars = false);
+struct winsize get_current_winsize();
+#endif
diff --git a/src/complete.cpp b/src/complete.cpp
index 1ed733258..3de8c81b1 100644
--- a/src/complete.cpp
+++ b/src/complete.cpp
@@ -138,8 +138,6 @@ class completion_entry_t {
     const wcstring cmd;
     /// True if command is a path.
     const bool cmd_is_path;
-    /// True if no other options than the ones supplied are possible.
-    bool authoritative;
     /// Order for when this completion was created. This aids in outputting completions sorted by
     /// time.
     const unsigned int order;
@@ -151,8 +149,8 @@ class completion_entry_t {
     void add_option(const complete_entry_opt_t &opt);
     bool remove_option(const wcstring &option, complete_option_type_t type);
 
-    completion_entry_t(const wcstring &c, bool type, bool author)
-        : cmd(c), cmd_is_path(type), authoritative(author), order(++kCompleteOrder) {}
+    completion_entry_t(const wcstring &c, bool type)
+        : cmd(c), cmd_is_path(type), order(++kCompleteOrder) {}
 };
 
 /// Set of all completion entries.
@@ -348,23 +346,14 @@ class completer_t {
     }
 };
 
-/// Autoloader for completions.
-class completion_autoload_t : public autoload_t {
-   public:
-    completion_autoload_t();
-    virtual void command_removed(const wcstring &cmd);
-};
-
-static completion_autoload_t completion_autoloader;
-
-// Constructor
-completion_autoload_t::completion_autoload_t() : autoload_t(L"fish_complete_path", NULL, 0) {}
-
-/// Callback when an autoloaded completion is removed.
-void completion_autoload_t::command_removed(const wcstring &cmd) {
+// Callback when an autoloaded completion is removed.
+static void autoloaded_completion_removed(const wcstring &cmd) {
     complete_remove_all(cmd, false /* not a path */);
 }
 
+// Autoloader for completions
+static autoload_t completion_autoloader(L"fish_complete_path", autoloaded_completion_removed);
+
 /// Create a new completion entry.
 void append_completion(std::vector *completions, const wcstring &comp,
                        const wcstring &desc, complete_flags_t flags, string_fuzzy_match_t match) {
@@ -418,7 +407,7 @@ static completion_entry_t &complete_get_exact_entry(const wcstring &cmd, bool cm
     ASSERT_IS_LOCKED(completion_lock);
 
     std::pair ins =
-        completion_set.insert(completion_entry_t(cmd, cmd_is_path, false));
+        completion_set.insert(completion_entry_t(cmd, cmd_is_path));
 
     // NOTE SET_ELEMENTS_ARE_IMMUTABLE: Exposing mutable access here is only okay as long as callers
     // do not change any field that matters to ordering - affecting order without telling std::set
@@ -426,14 +415,6 @@ static completion_entry_t &complete_get_exact_entry(const wcstring &cmd, bool cm
     return const_cast(*ins.first);
 }
 
-void complete_set_authoritative(const wchar_t *cmd, bool cmd_is_path, bool authoritative) {
-    CHECK(cmd, );
-    scoped_lock lock(completion_lock);
-
-    completion_entry_t &c = complete_get_exact_entry(cmd, cmd_is_path);
-    c.authoritative = authoritative;
-}
-
 void complete_add(const wchar_t *cmd, bool cmd_is_path, const wcstring &option,
                   complete_option_type_t option_type, int result_mode, const wchar_t *condition,
                   const wchar_t *comp, const wchar_t *desc, complete_flags_t flags) {
@@ -481,7 +462,7 @@ void complete_remove(const wcstring &cmd, bool cmd_is_path, const wcstring &opti
                      complete_option_type_t type) {
     scoped_lock lock(completion_lock);
 
-    completion_entry_t tmp_entry(cmd, cmd_is_path, false);
+    completion_entry_t tmp_entry(cmd, cmd_is_path);
     completion_entry_set_t::iterator iter = completion_set.find(tmp_entry);
     if (iter != completion_set.end()) {
         // const_cast: See SET_ELEMENTS_ARE_IMMUTABLE.
@@ -489,7 +470,6 @@ void complete_remove(const wcstring &cmd, bool cmd_is_path, const wcstring &opti
 
         bool delete_it = entry.remove_option(option, type);
         if (delete_it) {
-            // Delete this entry.
             completion_set.erase(iter);
         }
     }
@@ -498,7 +478,7 @@ void complete_remove(const wcstring &cmd, bool cmd_is_path, const wcstring &opti
 void complete_remove_all(const wcstring &cmd, bool cmd_is_path) {
     scoped_lock lock(completion_lock);
 
-    completion_entry_t tmp_entry(cmd, cmd_is_path, false);
+    completion_entry_t tmp_entry(cmd, cmd_is_path);
     completion_set.erase(tmp_entry);
 }
 
@@ -676,14 +656,16 @@ void completer_t::complete_cmd(const wcstring &str_cmd, bool use_function, bool
                                               NULL);
         if (result != EXPAND_ERROR && this->wants_descriptions()) {
             this->complete_cmd_desc(str_cmd);
-            }
+        }
     }
 
     if (use_implicit_cd) {
         // We don't really care if this succeeds or fails. If it succeeds this->completions will be
         // updated with choices for the user.
-        (void)expand_string(str_cmd, &this->completions,
-                            EXPAND_FOR_COMPLETIONS | DIRECTORIES_ONLY | this->expand_flags(), NULL);
+        expand_error_t ignore =
+            expand_string(str_cmd, &this->completions,
+                          EXPAND_FOR_COMPLETIONS | DIRECTORIES_ONLY | this->expand_flags(), NULL);
+        USE(ignore);
     }
 
     if (str_cmd.find(L'/') == wcstring::npos && str_cmd.at(0) != L'~') {
@@ -846,14 +828,6 @@ static void complete_load(const wcstring &name, bool reload) {
     completion_autoloader.load(name, reload);
 }
 
-/// Performed on main thread, from background thread. Return type is ignored.
-static int complete_load_no_reload(wcstring *name) {
-    assert(name != NULL);
-    ASSERT_IS_MAIN_THREAD();
-    complete_load(*name, false);
-    return 0;
-}
-
 /// complete_param: Given a command, find completions for the argument str of command cmd_orig with
 /// previous option popt.
 ///
@@ -879,8 +853,8 @@ bool completer_t::complete_param(const wcstring &scmd_orig, const wcstring &spop
         complete_load(cmd, true);
     } else if (this->type() == COMPLETE_AUTOSUGGEST &&
                !completion_autoloader.has_tried_loading(cmd)) {
-        // Load this command (on the main thread).
-        iothread_perform_on_main(complete_load_no_reload, &cmd);
+        // Load this command (on the main thread)
+        iothread_perform_on_main([&]() { complete_load(cmd, false); });
     }
 
     // Make a list of lists of all options that we care about.
@@ -920,6 +894,8 @@ bool completer_t::complete_param(const wcstring &scmd_orig, const wcstring &spop
                 }
             } else if (popt[0] == L'-') {
                 // Set to true if we found a matching old-style switch.
+                // Here we are testing the previous argument,
+                // to see how we should complete the current argument
                 bool old_style_match = false;
 
                 // If we are using old style long options, check for them first.
@@ -943,6 +919,8 @@ bool completer_t::complete_param(const wcstring &scmd_orig, const wcstring &spop
                         const complete_entry_opt_t *o = &*oiter;
                         // Gnu-style options with _optional_ arguments must be specified as a single
                         // token, so that it can be differed from a regular argument.
+                        // Here we are testing the previous argument for a GNU-style match,
+                        // to see how we should complete the current argument
                         if (o->type == option_type_double_long && !(o->result_mode & NO_COMMON))
                             continue;
 
@@ -960,8 +938,9 @@ bool completer_t::complete_param(const wcstring &scmd_orig, const wcstring &spop
             continue;
         }
 
+        // Now we try to complete an option itself
         for (option_list_t::const_iterator oiter = options.begin(); oiter != options.end();
-                ++oiter) {
+             ++oiter) {
             const complete_entry_opt_t *o = &*oiter;
             // If this entry is for the base command, check if any of the arguments match.
             if (!this->condition_test(o->condition)) continue;
@@ -1240,9 +1219,8 @@ bool completer_t::try_complete_user(const wcstring &str) {
             wcstring name = format_string(L"~%ls", pw_name);
             wcstring desc = format_string(COMPLETE_USER_DESC, pw_name);
 
-            append_completion(&this->completions, name, desc, COMPLETE_REPLACES_TOKEN |
-                                                                    COMPLETE_DONT_ESCAPE |
-                                                                    COMPLETE_NO_SPACE);
+            append_completion(&this->completions, name, desc,
+                              COMPLETE_REPLACES_TOKEN | COMPLETE_DONT_ESCAPE | COMPLETE_NO_SPACE);
             result = true;
         }
     }
@@ -1372,7 +1350,6 @@ void complete(const wcstring &cmd_with_subcmds, std::vector *out_c
                 }
             }
 
-            // cppcheck-suppress nullPointerRedundantCheck
             if (cmd_node && cmd_node->location_in_or_at_end_of_source_range(pos)) {
                 // Complete command filename.
                 completer.complete_cmd(current_token, use_function, use_builtin, use_command,
@@ -1457,7 +1434,7 @@ void complete(const wcstring &cmd_with_subcmds, std::vector *out_c
                             // transient commandline for builtin_commandline. But not for
                             // COMPLETION_REQUEST_AUTOSUGGESTION, which may occur on background
                             // threads.
-                            builtin_commandline_scoped_transient_t *transient_cmd = NULL;
+                            std::unique_ptr transient_cmd;
                             if (i == 0) {
                                 assert(wrap_chain.at(i) == current_command_unescape);
                             } else if (!(flags & COMPLETION_REQUEST_AUTOSUGGESTION)) {
@@ -1465,15 +1442,14 @@ void complete(const wcstring &cmd_with_subcmds, std::vector *out_c
                                 wcstring faux_cmdline = cmd;
                                 faux_cmdline.replace(cmd_node->source_start,
                                                      cmd_node->source_length, wrap_chain.at(i));
-                                transient_cmd =
-                                    new builtin_commandline_scoped_transient_t(faux_cmdline);
+                                transient_cmd = make_unique(
+                                    faux_cmdline);
                             }
                             if (!completer.complete_param(wrap_chain.at(i),
                                                           previous_argument_unescape,
                                                           current_argument_unescape, !had_ddash)) {
                                 do_file = false;
                             }
-                            delete transient_cmd;  // may be null
                         }
                     }
 
@@ -1640,7 +1616,7 @@ wcstring_list_t complete_get_wrap_chain(const wcstring &command) {
     wcstring target;
     while (!to_visit.empty()) {
         // Grab the next command to visit, put it in target.
-        target.swap(to_visit.back());
+        target = std::move(to_visit.back());
         to_visit.pop_back();
 
         // Try inserting into visited. If it was already present, we skip it; this is how we avoid
diff --git a/src/complete.h b/src/complete.h
index e573ad3d6..0820f0dce 100644
--- a/src/complete.h
+++ b/src/complete.h
@@ -143,10 +143,6 @@ void complete_add(const wchar_t *cmd, bool cmd_is_path, const wcstring &option,
                   complete_option_type_t option_type, int result_mode, const wchar_t *condition,
                   const wchar_t *comp, const wchar_t *desc, int flags);
 
-/// Sets whether the completion list for this command is complete. If true, any options not matching
-/// one of the provided options will be flagged as an error by syntax highlighting.
-void complete_set_authoritative(const wchar_t *cmd, bool cmd_type, bool authoritative);
-
 /// Remove a previously defined completion.
 void complete_remove(const wcstring &cmd, bool cmd_is_path, const wcstring &option,
                      complete_option_type_t type);
diff --git a/src/env.cpp b/src/env.cpp
index 0fcee01c5..8a98355d1 100644
--- a/src/env.cpp
+++ b/src/env.cpp
@@ -8,15 +8,19 @@
 #include 
 #include 
 #include 
-#ifdef HAVE__NL_MSG_CAT_CNTR
 #include 
-#endif
 #include 
 #include 
 #include 
 #include 
 #include 
-#include 
+
+#if HAVE_TERM_H
+#include 
+#elif HAVE_NCURSES_TERM_H
+#include 
+#endif
+
 #include 
 #include 
 #include 
@@ -53,8 +57,26 @@ extern char **environ;
 
 bool g_use_posix_spawn = false;  // will usually be set to true
 
-/// Struct representing one level in the function variable stack.
-struct env_node_t {
+/// Does the terminal have the "eat_newline_glitch".
+bool term_has_xn = false;
+
+/// List of all locale environment variable names.
+static const wchar_t *const locale_variable[] = {
+    L"LANG",     L"LANGUAGE",          L"LC_ALL",         L"LC_ADDRESS",   L"LC_COLLATE",
+    L"LC_CTYPE", L"LC_IDENTIFICATION", L"LC_MEASUREMENT", L"LC_MESSAGES",  L"LC_MONETARY",
+    L"LC_NAME",  L"LC_NUMERIC",        L"LC_PAPER",       L"LC_TELEPHONE", L"LC_TIME",
+    NULL};
+
+/// List of all curses environment variable names.
+static const wchar_t *const curses_variable[] = {L"TERM", L"TERMINFO", L"TERMINFO_DIRS", NULL};
+
+// Struct representing one level in the function variable stack.
+// Only our variable stack should create and destroy these
+class env_node_t {
+    friend struct var_stack_t;
+    env_node_t(bool is_new_scope) : new_scope(is_new_scope) {}
+
+   public:
     /// Variable table.
     var_table_t env;
     /// Does this node imply a new variable scope? If yes, all non-global variables below this one
@@ -62,19 +84,12 @@ struct env_node_t {
     /// will explode.
     bool new_scope;
     /// Does this node contain any variables which are exported to subshells.
-    bool exportv;
+    bool exportv = false;
     /// Pointer to next level.
-    struct env_node_t *next;
-
-    env_node_t() : new_scope(false), exportv(false), next(NULL) {}
+    std::unique_ptr next;
 
     /// Returns a pointer to the given entry if present, or NULL.
     const var_entry_t *find_entry(const wcstring &key);
-
-    /// Returns the next scope to search in order, respecting the new_scope flag, or NULL if we're
-    /// done.
-    env_node_t *next_scope_to_search();
-    const env_node_t *next_scope_to_search() const;
 };
 
 class variable_entry_t {
@@ -83,11 +98,132 @@ class variable_entry_t {
 
 static pthread_mutex_t env_lock = PTHREAD_MUTEX_INITIALIZER;
 
-/// Top node on the function stack.
-static env_node_t *top = NULL;
+static bool local_scope_exports(const env_node_t *n);
+static void handle_locale(const wchar_t *env_var_name);
 
-/// Bottom node on the function stack.
-static env_node_t *global_env = NULL;
+// A class wrapping up a variable stack
+// Currently there is only one variable stack in fish,
+// but we can imagine having separate (linked) stacks
+// if we introduce multiple threads of execution
+struct var_stack_t {
+    // Top node on the function stack.
+    std::unique_ptr top = NULL;
+
+    // Bottom node on the function stack
+    // This is an observer pointer
+    env_node_t *global_env = NULL;
+
+    // Exported variable array used by execv.
+    null_terminated_array_t export_array;
+
+    /// Flag for checking if we need to regenerate the exported variable array.
+    bool has_changed_exported = true;
+    void mark_changed_exported() { has_changed_exported = true; }
+    void update_export_array_if_necessary();
+
+    var_stack_t() : top(new env_node_t(false)) { this->global_env = this->top.get(); }
+
+    // Pushes a new node onto our stack
+    // Optionally creates a new scope for the node
+    void push(bool new_scope);
+
+    // Pops the top node if it's not global
+    void pop();
+
+    // Returns the next scope to search for a given node, respecting the new_scope lag
+    // Returns NULL if we're done
+    env_node_t *next_scope_to_search(env_node_t *node);
+    const env_node_t *next_scope_to_search(const env_node_t *node) const;
+
+    // Returns the scope used for unspecified scopes
+    // An unspecified scope is either the topmost shadowing scope, or the global scope if none
+    // This implements the default behavior of 'set'
+    env_node_t *resolve_unspecified_scope();
+};
+
+void var_stack_t::push(bool new_scope) {
+    std::unique_ptr node(new env_node_t(new_scope));
+    node->next = std::move(this->top);
+    this->top = std::move(node);
+    if (new_scope && local_scope_exports(this->top.get())) {
+        this->mark_changed_exported();
+    }
+}
+
+void var_stack_t::pop() {
+    // Don't pop the global
+    if (this->top.get() == this->global_env) {
+        debug(0, _(L"Tried to pop empty environment stack."));
+        sanity_lose();
+        return;
+    }
+
+    const wchar_t *locale_changed = NULL;
+
+    for (int i = 0; locale_variable[i]; i++) {
+        var_table_t::iterator result = top->env.find(locale_variable[i]);
+        if (result != top->env.end()) {
+            locale_changed = locale_variable[i];
+            break;
+        }
+    }
+
+    if (top->new_scope) {  //!OCLINT(collapsible if statements)
+        if (top->exportv || local_scope_exports(top->next.get())) {
+            this->mark_changed_exported();
+        }
+    }
+
+    // Actually do the pop! Move the top pointer into a local variable, then replace the top pointer
+    // with the next pointer afterwards we should have a node with no next pointer, and our top
+    // should be non-null.
+    std::unique_ptr old_top = std::move(this->top);
+    this->top = std::move(old_top->next);
+    old_top->next.reset();
+    assert(this->top && old_top && !old_top->next);
+    assert(this->top != NULL);
+
+    var_table_t::iterator iter;
+    for (const auto &entry_pair : old_top->env) {
+        const var_entry_t &entry = entry_pair.second;
+        if (entry.exportv) {
+            this->mark_changed_exported();
+            break;
+        }
+    }
+    // TODO: Move this to something general.
+    if (locale_changed) handle_locale(locale_changed);
+}
+
+const env_node_t *var_stack_t::next_scope_to_search(const env_node_t *node) const {
+    assert(node != NULL);
+    if (node == this->global_env) {
+        return NULL;
+    }
+    return node->new_scope ? this->global_env : node->next.get();
+}
+
+env_node_t *var_stack_t::next_scope_to_search(env_node_t *node) {
+    assert(node != NULL);
+    if (node == this->global_env) {
+        return NULL;
+    }
+    return node->new_scope ? this->global_env : node->next.get();
+}
+
+env_node_t *var_stack_t::resolve_unspecified_scope() {
+    env_node_t *node = this->top.get();
+    while (node && !node->new_scope) {
+        node = node->next.get();
+    }
+    return node ? node : this->global_env;
+}
+
+// Get the global variable stack
+static var_stack_t &vars_stack() {
+    static var_stack_t global_stack;
+    return global_stack;
+}
 
 /// Universal variables global instance. Initialized in env_init.
 static env_universal_t *s_universal_variables = NULL;
@@ -95,9 +231,6 @@ static env_universal_t *s_universal_variables = NULL;
 /// Getter for universal variables.
 static env_universal_t *uvars() { return s_universal_variables; }
 
-/// Table for global variables.
-static var_table_t *global;
-
 // Helper class for storing constant strings, without needing to wrap them in a wcstring.
 
 // Comparer for const string set.
@@ -120,23 +253,6 @@ static bool is_electric(const wcstring &key) {
     return env_electric.find(key.c_str()) != env_electric.end();
 }
 
-/// Exported variable array used by execv.
-static null_terminated_array_t export_array;
-
-/// Flag for checking if we need to regenerate the exported variable array.
-static bool has_changed_exported = true;
-static void mark_changed_exported() { has_changed_exported = true; }
-
-/// List of all locale environment variable names.
-static const wchar_t *const locale_variable[] = {
-    L"LANG",     L"LANGUAGE",          L"LC_ALL",         L"LC_ADDRESS",   L"LC_COLLATE",
-    L"LC_CTYPE", L"LC_IDENTIFICATION", L"LC_MEASUREMENT", L"LC_MESSAGES",  L"LC_MONETARY",
-    L"LC_NAME",  L"LC_NUMERIC",        L"LC_PAPER",       L"LC_TELEPHONE", L"LC_TIME",
-    NULL};
-
-/// List of all curses environment variable names.
-static const wchar_t *const curses_variable[] = {L"TERM", L"TERMINFO", L"TERMINFO_DIRS", NULL};
-
 const var_entry_t *env_node_t::find_entry(const wcstring &key) {
     const var_entry_t *result = NULL;
     var_table_t::const_iterator where = env.find(key);
@@ -146,12 +262,6 @@ const var_entry_t *env_node_t::find_entry(const wcstring &key) {
     return result;
 }
 
-env_node_t *env_node_t::next_scope_to_search() { return this->new_scope ? global_env : this->next; }
-
-const env_node_t *env_node_t::next_scope_to_search() const {
-    return this->new_scope ? global_env : this->next;
-}
-
 /// Return the current umask value.
 static mode_t get_umask() {
     mode_t res;
@@ -231,6 +341,43 @@ static bool var_is_curses(const wcstring &key) {
     return false;
 }
 
+/// True if we think we can set the terminal title else false.
+static bool can_set_term_title = false;
+
+/// Returns true if we think the terminal supports setting its title.
+bool term_supports_setting_title() { return can_set_term_title; }
+
+/// This is a pretty lame heuristic for detecting terminals that do not support setting the
+/// title. If we recognise the terminal name as that of a virtual terminal, we assume it supports
+/// setting the title. If we recognise it as that of a console, we assume it does not support
+/// setting the title. Otherwise we check the ttyname and see if we believe it is a virtual
+/// terminal.
+///
+/// One situation in which this breaks down is with screen, since screen supports setting the
+/// terminal title if the underlying terminal does so, but will print garbage on terminals that
+/// don't. Since we can't see the underlying terminal below screen there is no way to fix this.
+static bool does_term_support_setting_title() {
+    const env_var_t term_str = env_get_string(L"TERM");
+    if (term_str.missing()) return false;
+
+    const wchar_t *term = term_str.c_str();
+    bool recognized = contains(term, L"xterm", L"screen", L"tmux", L"nxterm", L"rxvt");
+    if (!recognized) recognized = !wcsncmp(term, L"xterm-", wcslen(L"xterm-"));
+    if (!recognized) recognized = !wcsncmp(term, L"screen-", wcslen(L"screen-"));
+    if (!recognized) recognized = !wcsncmp(term, L"tmux-", wcslen(L"tmux-"));
+    if (!recognized) {
+        if (contains(term, L"linux", L"dumb")) return false;
+
+        char *n = ttyname(STDIN_FILENO);
+        if (!n || strstr(n, "tty") || strstr(n, "/vc/")) return false;
+    }
+
+    return true;
+}
+
+/// Handle changes to the TERM env var that do not involves the curses subsystem.
+static void handle_term() { can_set_term_title = does_term_support_setting_title(); }
+
 /// Push all curses/terminfo env vars into the global environment where they can be found by those
 /// libraries.
 static void handle_curses(const wchar_t *env_var_name) {
@@ -248,6 +395,7 @@ static void handle_curses(const wchar_t *env_var_name) {
     // changed. At the present time it can be called just once. Also, we should really only do this
     // if the TERM var is set.
     // input_init();
+    term_has_xn = tgetflag((char *)"xn") == 1;  // does terminal have the eat_newline_glitch
 }
 
 /// React to modifying the given variable.
@@ -256,6 +404,7 @@ static void react_to_variable_change(const wcstring &key) {
         handle_locale(key.c_str());
     } else if (var_is_curses(key)) {
         handle_curses(key.c_str());
+        if (key == L"TERM") handle_term();
     } else if (var_is_timezone(key)) {
         handle_timezone(key.c_str());
     } else if (key == L"fish_term256" || key == L"fish_term24bit") {
@@ -265,6 +414,8 @@ static void react_to_variable_change(const wcstring &key) {
         reader_react_to_color_change();
     } else if (key == L"fish_escape_delay_ms") {
         update_wait_on_escape_ms();
+    } else if (key == L"LINES" || key == L"COLUMNS") {
+        invalidate_termsize(true);  // force fish to update its idea of the terminal size plus vars
     }
 }
 
@@ -286,7 +437,7 @@ static void universal_callback(fish_message_type_t type, const wchar_t *name) {
     }
 
     if (str) {
-        mark_changed_exported();
+        vars_stack().mark_changed_exported();
 
         event_t ev = event_t::variable_event(name);
         ev.arguments.push_back(L"VARIABLE");
@@ -307,15 +458,25 @@ static void setup_path() {
     }
 }
 
-int env_set_pwd() {
+/// Initialize the `COLUMNS` and `LINES` env vars if they don't already exist to reasonable
+/// defaults. They will be updated later by the `get_current_winsize()` function if they need to be
+/// adjusted.
+static void env_set_termsize() {
+    env_var_t cols = env_get_string(L"COLUMNS");
+    if (cols.missing_or_empty()) env_set(L"COLUMNS", DFLT_TERM_COL_STR, ENV_EXPORT | ENV_GLOBAL);
+    env_var_t rows = env_get_string(L"LINES");
+    if (rows.missing_or_empty()) env_set(L"LINES", DFLT_TERM_ROW_STR, ENV_EXPORT | ENV_GLOBAL);
+}
+
+bool env_set_pwd() {
     wcstring res = wgetcwd();
     if (res.empty()) {
         debug(0,
               _(L"Could not determine current working directory. Is your locale set correctly?"));
-        return 0;
+        return false;
     }
     env_set(L"PWD", res.c_str(), ENV_EXPORT | ENV_GLOBAL);
-    return 1;
+    return true;
 }
 
 wcstring env_get_pwd_slash(void) {
@@ -336,10 +497,21 @@ static bool variable_is_colon_delimited_array(const wcstring &str) {
     return contains(str, L"PATH", L"MANPATH", L"CDPATH");
 }
 
+/// Set up the USER variable.
+static void setup_user(bool force) {
+    if (env_get_string(L"USER").missing_or_empty() || force) {
+        const struct passwd *pw = getpwuid(getuid());
+        if (pw && pw->pw_name) {
+            const wcstring uname = str2wcstring(pw->pw_name);
+            env_set(L"USER", uname.c_str(), ENV_GLOBAL | ENV_EXPORT);
+        }
+    }
+}
+
 void env_init(const struct config_paths_t *paths /* or NULL */) {
     // These variables can not be altered directly by the user.
     const wchar_t *const ro_keys[] = {
-        L"status", L"history", L"_", L"LINES", L"COLUMNS", L"PWD", L"FISH_VERSION",
+        L"status", L"history", L"_", L"PWD", L"FISH_VERSION",
         // L"SHLVL" is readonly but will be inserted below after we increment it.
     };
     for (size_t i = 0; i < sizeof ro_keys / sizeof *ro_keys; i++) {
@@ -350,12 +522,6 @@ void env_init(const struct config_paths_t *paths /* or NULL */) {
     env_electric.insert(L"history");
     env_electric.insert(L"status");
     env_electric.insert(L"umask");
-    env_electric.insert(L"COLUMNS");
-    env_electric.insert(L"LINES");
-
-    top = new env_node_t;
-    global_env = top;
-    global = &top->env;
 
     // Now the environment variable handling is set up, the next step is to insert valid data.
 
@@ -394,17 +560,9 @@ void env_init(const struct config_paths_t *paths /* or NULL */) {
         env_set(FISH_BIN_DIR, paths->bin.c_str(), ENV_GLOBAL);
     }
 
-    // Set up the PATH variable.
+    // Set up the USER and PATH variables
     setup_path();
-
-    // Set up the USER variable.
-    if (env_get_string(L"USER").missing_or_empty()) {
-        const struct passwd *pw = getpwuid(getuid());
-        if (pw && pw->pw_name) {
-            const wcstring uname = str2wcstring(pw->pw_name);
-            env_set(L"USER", uname.c_str(), ENV_GLOBAL | ENV_EXPORT);
-        }
-    }
+    setup_user(false);
 
     // Set up the version variable.
     wcstring version = str2wcstring(get_fish_version());
@@ -414,10 +572,10 @@ void env_init(const struct config_paths_t *paths /* or NULL */) {
     const env_var_t shlvl_str = env_get_string(L"SHLVL");
     wcstring nshlvl_str = L"1";
     if (!shlvl_str.missing()) {
-        wchar_t *end;
-        long shlvl_i = wcstol(shlvl_str.c_str(), &end, 10);
-        while (iswspace(*end)) ++end;  // skip trailing whitespace
-        if (shlvl_i >= 0 && *end == '\0') {
+        const wchar_t *end;
+        // TODO: Figure out how to handle invalid numbers better. Shouldn't we issue a diagnostic?
+        long shlvl_i = fish_wcstol(shlvl_str.c_str(), &end);
+        if (!errno && shlvl_i >= 0) {
             nshlvl_str = to_string(shlvl_i + 1);
         }
     }
@@ -429,15 +587,22 @@ void env_init(const struct config_paths_t *paths /* or NULL */) {
         const env_var_t unam = env_get_string(L"USER");
         char *unam_narrow = wcs2str(unam.c_str());
         struct passwd *pw = getpwnam(unam_narrow);
-        if (pw->pw_dir != NULL) {
+        if (pw == NULL) {
+            // Maybe USER is set but it's bogus. Reset USER from the db and try again.
+            setup_user(true);
+            const env_var_t unam = env_get_string(L"USER");
+            unam_narrow = wcs2str(unam.c_str());
+            pw = getpwnam(unam_narrow);
+        }
+        if (pw && pw->pw_dir) {
             const wcstring dir = str2wcstring(pw->pw_dir);
             env_set(L"HOME", dir.c_str(), ENV_GLOBAL | ENV_EXPORT);
         }
         free(unam_narrow);
     }
 
-    // Set PWD.
-    env_set_pwd();
+    env_set_pwd();       // initialize the PWD variable
+    env_set_termsize();  // initialize the terminal size variables
 
     // Set up universal variables. The empty string means to use the deafult path.
     assert(s_universal_variables == NULL);
@@ -461,13 +626,13 @@ void env_init(const struct config_paths_t *paths /* or NULL */) {
 /// Search all visible scopes in order for the specified key. Return the first scope in which it was
 /// found.
 static env_node_t *env_get_node(const wcstring &key) {
-    env_node_t *env = top;
+    env_node_t *env = vars_stack().top.get();
     while (env != NULL) {
         if (env->find_entry(key) != NULL) {
             break;
         }
 
-        env = env->next_scope_to_search();
+        env = vars_stack().next_scope_to_search(env);
     }
     return env;
 }
@@ -493,7 +658,7 @@ static env_node_t *env_get_node(const wcstring &key) {
 /// * ENV_INVALID, the variable value was invalid. This applies only to special variables.
 int env_set(const wcstring &key, const wchar_t *val, env_mode_flags_t var_mode) {
     ASSERT_IS_MAIN_THREAD();
-    bool has_changed_old = has_changed_exported;
+    bool has_changed_old = vars_stack().has_changed_exported;
     int done = 0;
 
     if (val && contains(key, L"PWD", L"HOME")) {
@@ -516,14 +681,10 @@ int env_set(const wcstring &key, const wchar_t *val, env_mode_flags_t var_mode)
     }
 
     if (key == L"umask") {
-        wchar_t *end;
-
         // Set the new umask.
         if (val && wcslen(val)) {
-            errno = 0;
-            long mask = wcstol(val, &end, 8);
-
-            if (!errno && (!*end) && (mask <= 0777) && (mask >= 0)) {
+            long mask = fish_wcstol(val, NULL, 8);
+            if (!errno && mask <= 0777 && mask >= 0) {
                 umask(mask);
                 // Do not actually create a umask variable, on env_get, it will be calculated
                 // dynamically.
@@ -556,7 +717,7 @@ int env_set(const wcstring &key, const wchar_t *val, env_mode_flags_t var_mode)
             uvars()->set(key, val, new_export);
             env_universal_barrier();
             if (old_export || new_export) {
-                mark_changed_exported();
+                vars_stack().mark_changed_exported();
             }
         }
     } else {
@@ -576,9 +737,9 @@ int env_set(const wcstring &key, const wchar_t *val, env_mode_flags_t var_mode)
 
         env_node_t *node = NULL;
         if (var_mode & ENV_GLOBAL) {
-            node = global_env;
+            node = vars_stack().global_env;
         } else if (var_mode & ENV_LOCAL) {
-            node = top;
+            node = vars_stack().top.get();
         } else if (preexisting_node != NULL) {
             node = preexisting_node;
             if ((var_mode & (ENV_EXPORT | ENV_UNEXPORT)) == 0) {
@@ -608,12 +769,8 @@ int env_set(const wcstring &key, const wchar_t *val, env_mode_flags_t var_mode)
                 done = 1;
 
             } else {
-                // New variable with unspecified scope. The default scope is the innermost scope
-                // that is shadowing, which will be either the current function or the global scope.
-                node = top;
-                while (node->next && !node->new_scope) {
-                    node = node->next;
-                }
+                // New variable with unspecified scope
+                node = vars_stack().resolve_unspecified_scope();
             }
         }
 
@@ -635,7 +792,7 @@ int env_set(const wcstring &key, const wchar_t *val, env_mode_flags_t var_mode)
                 entry.exportv = false;
             }
 
-            if (has_changed_old || has_changed_new) mark_changed_exported();
+            if (has_changed_old || has_changed_new) vars_stack().mark_changed_exported();
         }
     }
 
@@ -664,7 +821,7 @@ static bool try_remove(env_node_t *n, const wchar_t *key, int var_mode) {
     var_table_t::iterator result = n->env.find(key);
     if (result != n->env.end()) {
         if (result->second.exportv) {
-            mark_changed_exported();
+            vars_stack().mark_changed_exported();
         }
         n->env.erase(result);
         return true;
@@ -675,9 +832,9 @@ static bool try_remove(env_node_t *n, const wchar_t *key, int var_mode) {
     }
 
     if (n->new_scope) {
-        return try_remove(global_env, key, var_mode);
+        return try_remove(vars_stack().global_env, key, var_mode);
     }
-    return try_remove(n->next, key, var_mode);
+    return try_remove(n->next.get(), key, var_mode);
 }
 
 int env_remove(const wcstring &key, int var_mode) {
@@ -689,11 +846,11 @@ int env_remove(const wcstring &key, int var_mode) {
         return 2;
     }
 
-    first_node = top;
+    first_node = vars_stack().top.get();
 
     if (!(var_mode & ENV_UNIVERSAL)) {
         if (var_mode & ENV_GLOBAL) {
-            first_node = global_env;
+            first_node = vars_stack().global_env;
         }
 
         if (try_remove(first_node, key.c_str(), var_mode)) {
@@ -719,7 +876,7 @@ int env_remove(const wcstring &key, int var_mode) {
             event_fire(&ev);
         }
 
-        if (is_exported) mark_changed_exported();
+        if (is_exported) vars_stack().mark_changed_exported();
     }
 
     react_to_variable_change(key);
@@ -745,9 +902,12 @@ env_var_t env_get_string(const wcstring &key, env_mode_flags_t mode) {
     // that in env_set().
     if (is_electric(key)) {
         if (!search_global) return env_var_t::missing_var();
-        // Big hack. We only allow getting the history on the main thread. Note that history_t may
-        // ask for an environment variable, so don't take the lock here (we don't need it).
-        if (key == L"history" && is_main_thread()) {
+        if (key == L"history") {
+            // Big hack. We only allow getting the history on the main thread. Note that history_t
+            // may ask for an environment variable, so don't take the lock here (we don't need it).
+            if (!is_main_thread()) {
+                return env_var_t::missing_var();
+            }
             env_var_t result;
 
             history_t *history = reader_get_history();
@@ -756,23 +916,20 @@ env_var_t env_get_string(const wcstring &key, env_mode_flags_t mode) {
             }
             if (history) history->get_string_representation(&result, ARRAY_SEP_STR);
             return result;
-        } else if (key == L"COLUMNS") {
-            return to_string(common_get_width());
-        } else if (key == L"LINES") {
-            return to_string(common_get_height());
         } else if (key == L"status") {
             return to_string(proc_get_last_status());
         } else if (key == L"umask") {
             return format_string(L"0%0.3o", get_umask());
         }
-        // We should never get here unless the electric var list is out of sync.
+        // We should never get here unless the electric var list is out of sync with the above code.
+        DIE("unerecognized electric var name");
     }
 
     if (search_local || search_global) {
         /* Lock around a local region */
         scoped_lock locker(env_lock);
 
-        env_node_t *env = search_local ? top : global_env;
+        env_node_t *env = search_local ? vars_stack().top.get() : vars_stack().global_env;
 
         while (env != NULL) {
             const var_entry_t *entry = env->find_entry(key);
@@ -784,10 +941,10 @@ env_var_t env_get_string(const wcstring &key, env_mode_flags_t mode) {
             }
 
             if (has_scope) {
-                if (!search_global || env == global_env) break;
-                env = global_env;
+                if (!search_global || env == vars_stack().global_env) break;
+                env = vars_stack().global_env;
             } else {
-                env = env->next_scope_to_search();
+                env = vars_stack().next_scope_to_search(env);
             }
         }
     }
@@ -833,9 +990,9 @@ bool env_exist(const wchar_t *key, env_mode_flags_t mode) {
     }
 
     if (test_local || test_global) {
-        const env_node_t *env = test_local ? top : global_env;
+        const env_node_t *env = test_local ? vars_stack().top.get() : vars_stack().global_env;
         while (env != NULL) {
-            if (env == global_env && !test_global) {
+            if (env == vars_stack().global_env && !test_global) {
                 break;
             }
 
@@ -844,7 +1001,7 @@ bool env_exist(const wchar_t *key, env_mode_flags_t mode) {
                 const var_entry_t &res = result->second;
                 return res.exportv ? test_exported : test_unexported;
             }
-            env = env->next_scope_to_search();
+            env = vars_stack().next_scope_to_search(env);
         }
     }
 
@@ -864,63 +1021,20 @@ bool env_exist(const wchar_t *key, env_mode_flags_t mode) {
 
 /// Returns true if the specified scope or any non-shadowed non-global subscopes contain an exported
 /// variable.
-static int local_scope_exports(env_node_t *n) {
-    if (n == global_env) return 0;
+static bool local_scope_exports(const env_node_t *n) {
+    assert(n != NULL);
+    if (n == vars_stack().global_env) return false;
 
-    if (n->exportv) return 1;
+    if (n->exportv) return true;
 
-    if (n->new_scope) return 0;
+    if (n->new_scope) return false;
 
-    return local_scope_exports(n->next);
+    return local_scope_exports(n->next.get());
 }
 
-void env_push(bool new_scope) {
-    env_node_t *node = new env_node_t;
-    node->next = top;
-    node->new_scope = new_scope;
+void env_push(bool new_scope) { vars_stack().push(new_scope); }
 
-    if (new_scope && local_scope_exports(top)) mark_changed_exported();
-    top = node;
-}
-
-void env_pop() {
-    if (&top->env != global) {
-        int i;
-        const wchar_t *locale_changed = NULL;
-        env_node_t *killme = top;
-
-        for (i = 0; locale_variable[i]; i++) {
-            var_table_t::iterator result = killme->env.find(locale_variable[i]);
-            if (result != killme->env.end()) {
-                locale_changed = locale_variable[i];
-                break;
-            }
-        }
-
-        if (killme->new_scope) {  //!OCLINT(collapsible if statements)
-            if (killme->exportv || local_scope_exports(killme->next)) mark_changed_exported();
-        }
-
-        top = top->next;
-
-        var_table_t::iterator iter;
-        for (iter = killme->env.begin(); iter != killme->env.end(); ++iter) {
-            const var_entry_t &entry = iter->second;
-            if (entry.exportv) {
-                mark_changed_exported();
-                break;
-            }
-        }
-
-        delete killme;
-
-        if (locale_changed) handle_locale(locale_changed);
-
-    } else {
-        debug(0, _(L"Tried to pop empty environment stack."));
-        sanity_lose();
-    }
-}
+void env_pop() { vars_stack().pop(); }
 
 /// Function used with to insert keys of one table into a set::set.
 static void add_key_to_string_set(const var_table_t &envs, std::set *str_set,
@@ -945,7 +1059,7 @@ wcstring_list_t env_get_names(int flags) {
     int show_global = flags & ENV_GLOBAL;
     int show_universal = flags & ENV_UNIVERSAL;
 
-    env_node_t *n = top;
+    const env_node_t *n = vars_stack().top.get();
     const bool show_exported = (flags & ENV_EXPORT) || !(flags & ENV_UNEXPORT);
     const bool show_unexported = (flags & ENV_UNEXPORT) || !(flags & ENV_EXPORT);
 
@@ -955,18 +1069,18 @@ wcstring_list_t env_get_names(int flags) {
 
     if (show_local) {
         while (n) {
-            if (n == global_env) break;
+            if (n == vars_stack().global_env) break;
 
             add_key_to_string_set(n->env, &names, show_exported, show_unexported);
             if (n->new_scope)
                 break;
             else
-                n = n->next;
+                n = n->next.get();
         }
     }
 
     if (show_global) {
-        add_key_to_string_set(global_env->env, &names, show_exported, show_unexported);
+        add_key_to_string_set(vars_stack().global_env->env, &names, show_exported, show_unexported);
         if (show_unexported) {
             result.insert(result.end(), env_electric.begin(), env_electric.end());
         }
@@ -986,9 +1100,9 @@ static void get_exported(const env_node_t *n, std::map *h) {
     if (!n) return;
 
     if (n->new_scope)
-        get_exported(global_env, h);
+        get_exported(vars_stack().global_env, h);
     else
-        get_exported(n->next, h);
+        get_exported(n->next.get(), h);
 
     var_table_t::const_iterator iter;
     for (iter = n->env.begin(); iter != n->env.end(); ++iter) {
@@ -1035,45 +1149,41 @@ static void export_func(const std::map &envs, std::vectorhas_changed_exported) {
+        return;
     }
+    std::map vals;
 
-    if (has_changed_exported) {
-        std::map vals;
+    debug(4, L"env_export_arr() recalc");
 
-        debug(4, L"env_export_arr() recalc");
+    get_exported(this->top.get(), &vals);
 
-        get_exported(top, &vals);
+    if (uvars()) {
+        const wcstring_list_t uni = uvars()->get_names(true, false);
+        for (size_t i = 0; i < uni.size(); i++) {
+            const wcstring &key = uni.at(i);
+            const env_var_t val = uvars()->get(key);
 
-        if (uvars()) {
-            const wcstring_list_t uni = uvars()->get_names(true, false);
-            for (size_t i = 0; i < uni.size(); i++) {
-                const wcstring &key = uni.at(i);
-                const env_var_t val = uvars()->get(key);
-
-                if (!val.missing() && val != ENV_NULL) {
-                    // Note that std::map::insert does NOT overwrite a value already in the map,
-                    // which we depend on here.
-                    vals.insert(std::pair(key, val));
-                }
+            if (!val.missing() && val != ENV_NULL) {
+                // Note that std::map::insert does NOT overwrite a value already in the map,
+                // which we depend on here.
+                vals.insert(std::pair(key, val));
             }
         }
-
-        std::vector local_export_buffer;
-        export_func(vals, local_export_buffer);
-        export_array.set(local_export_buffer);
-        has_changed_exported = false;
     }
+
+    std::vector local_export_buffer;
+    export_func(vals, local_export_buffer);
+    export_array.set(local_export_buffer);
+    has_changed_exported = false;
 }
 
-const char *const *env_export_arr(bool recalc) {
+const char *const *env_export_arr() {
     ASSERT_IS_MAIN_THREAD();
-    update_export_array_if_necessary(recalc);
-    return export_array.get();
+    ASSERT_IS_NOT_FORKED_CHILD();
+    vars_stack().update_export_array_if_necessary();
+    return vars_stack().export_array.get();
 }
 
 void env_set_argv(const wchar_t *const *argv) {
diff --git a/src/env.h b/src/env.h
index 56a84ffde..74590f1c2 100644
--- a/src/env.h
+++ b/src/env.h
@@ -134,8 +134,8 @@ void env_pop();
 /// Synchronizes all universal variable changes: writes everything out, reads stuff in.
 void env_universal_barrier();
 
-/// Returns an array containing all exported variables in a format suitable for execv.
-const char *const *env_export_arr(bool recalc);
+/// Returns an array containing all exported variables in a format suitable for execv
+const char *const *env_export_arr();
 
 /// Sets up argv as the given null terminated array of strings.
 void env_set_argv(const wchar_t *const *argv);
@@ -144,7 +144,7 @@ void env_set_argv(const wchar_t *const *argv);
 wcstring_list_t env_get_names(int flags);
 
 /// Update the PWD variable directory.
-int env_set_pwd();
+bool env_set_pwd();
 
 /// Returns the PWD with a terminating slash.
 wcstring env_get_pwd_slash();
@@ -153,10 +153,10 @@ class env_vars_snapshot_t {
     std::map vars;
     bool is_current() const;
 
-    env_vars_snapshot_t(const env_vars_snapshot_t &);
-    void operator=(const env_vars_snapshot_t &);
-
    public:
+    env_vars_snapshot_t(const env_vars_snapshot_t &) = default;
+    env_vars_snapshot_t &operator=(const env_vars_snapshot_t &) = default;
+
     env_vars_snapshot_t(const wchar_t *const *keys);
     env_vars_snapshot_t();
 
@@ -184,4 +184,9 @@ struct var_entry_t {
 };
 
 typedef std::map var_table_t;
+
+extern bool term_has_xn;  // does the terminal have the "eat_newline_glitch"
+
+/// Returns true if we think the terminal supports setting its title.
+bool term_supports_setting_title();
 #endif
diff --git a/src/env_universal_common.cpp b/src/env_universal_common.cpp
index d0fcdab3c..e0b5348a9 100644
--- a/src/env_universal_common.cpp
+++ b/src/env_universal_common.cpp
@@ -1,42 +1,42 @@
 // The utility library for universal variables. Used both by the client library and by the daemon.
-#include "config.h"
+#include "config.h"  // IWYU pragma: keep
 
 #include   // IWYU pragma: keep
 #include 
 #include 
 #include 
 #include 
+#include   // IWYU pragma: keep
 #include 
-#include 
 #include 
 #include 
+#ifdef __CYGWIN__
 #include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#ifdef HAVE_SYS_SELECT_H
-#include 
 #endif
-#include 
-#include 
-#include 
+#ifdef HAVE_SYS_SELECT_H
+#include   // IWYU pragma: keep
+#endif
+#include 
+#include   // IWYU pragma: keep
+// We need the sys/file.h for the flock() declaration on Linux but not OS X.
+#include   // IWYU pragma: keep
 // We need the ioctl.h header so we can check if SIOCGIFHWADDR is defined by it so we know if we're
 // on a Linux system.
 #include   // IWYU pragma: keep
-// We need the sys/file.h for the flock() declaration on Linux but not OS X.
-#include   // IWYU pragma: keep
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 
 #include "common.h"
 #include "env.h"
 #include "env_universal_common.h"
 #include "fallback.h"  // IWYU pragma: keep
+#include "path.h"
 #include "utf8.h"
-#include "util.h"
+#include "util.h"  // IWYU pragma: keep
 #include "wutil.h"
 
 #if __APPLE__
@@ -44,6 +44,11 @@
 #include 
 #endif
 
+#ifdef __HAIKU__
+#define _BSD_SOURCE
+#include 
+#endif  // Haiku
+
 // NAME_MAX is not defined on Solaris and suggests the use of pathconf()
 // There is no obvious sensible pathconf() for shared memory and _XPG_NAME_MAX
 // seems a reasonable choice.
@@ -71,7 +76,6 @@
     "# This file is automatically generated by the fish.\n# Do NOT edit it directly, your " \
     "changes will be overwritten.\n"
 
-static wcstring fishd_get_config();
 static wcstring get_machine_identifier();
 static bool get_hostname_identifier(wcstring *result);
 
@@ -84,15 +88,14 @@ static wcstring vars_filename_in_directory(const wcstring &wdir) {
     return result;
 }
 
-static const wcstring &default_vars_path() {
-    // Oclint complains about this being a "redundant local variable"; however it isn't because the
-    // assignment to a static var is needed to keep the object from being deleted when this function
-    // returns.
-    static wcstring cached_result = vars_filename_in_directory(fishd_get_config());  //!OCLINT
-    return cached_result;
+static const wcstring default_vars_path() {
+    wcstring path;
+    path_get_config(path);
+    return vars_filename_in_directory(path);
 }
 
-/// Check, and create if necessary, a secure runtime path Derived from tmux.c in tmux
+#if !defined(__APPLE__) && !defined(__CYGWIN__)
+/// Check, and create if necessary, a secure runtime path. Derived from tmux.c in tmux
 /// (http://tmux.sourceforge.net/).
 static int check_runtime_path(const char *path) {
     // Copyright (c) 2007 Nicholas Marriott 
@@ -140,9 +143,8 @@ static wcstring get_runtime_path() {
         std::string tmpdir = "/tmp/fish.";
         tmpdir.append(uname);
         if (check_runtime_path(tmpdir.c_str()) != 0) {
-            debug(0,
-                  L"Runtime path not available. Try deleting the directory %s and restarting fish.",
-                  tmpdir.c_str());
+            debug(0, L"Runtime path not available.");
+            debug(0, L"Try deleting the directory %s and restarting fish.", tmpdir.c_str());
         } else {
             result = str2wcstring(tmpdir);
         }
@@ -156,6 +158,7 @@ static wcstring default_named_pipe_path() {
     // Note that vars_filename_in_directory returns empty string when passed the empty string.
     return vars_filename_in_directory(get_runtime_path());
 }
+#endif
 
 /// Test if the message msg contains the command cmd.
 static bool match(const wchar_t *msg, const wchar_t *cmd) {
@@ -167,18 +170,6 @@ static bool match(const wchar_t *msg, const wchar_t *cmd) {
     return true;
 }
 
-static void report_error(int err_code, const wchar_t *err_format, ...) {
-    va_list va;
-    va_start(va, err_format);
-    const wcstring err_text = vformat_string(err_format, va);
-    va_end(va);
-
-    if (!err_text.empty()) {
-        fwprintf(stderr, L"%ls: ", err_text.c_str());
-    }
-    fwprintf(stderr, L"%s\n", strerror(err_code));
-}
-
 /// The universal variable format has some funny escaping requirements; here we try to be safe.
 static bool is_universal_safe_to_encode_directly(wchar_t c) {
     if (c < 32 || c > 128) return false;
@@ -231,7 +222,7 @@ static bool append_file_entry(fish_message_type_t type, const wcstring &key_in,
     result->push_back(' ');
 
     // Append variable name like "fish_color_cwd".
-    if (wcsvarname(key_in.c_str())) {
+    if (wcsvarname(key_in)) {
         debug(0, L"Illegal variable name: '%ls'", key_in.c_str());
         success = false;
     }
@@ -399,13 +390,13 @@ void env_universal_t::acquire_variables(var_table_t *vars_to_acquire) {
             // source entry in vars since we are about to get rid of this->vars entirely.
             var_entry_t &src = src_iter->second;
             var_entry_t &dst = (*vars_to_acquire)[key];
-            dst.val.swap(src.val);
+            dst.val = std::move(src.val);
             dst.exportv = src.exportv;
         }
     }
 
     // We have constructed all the callbacks and updated vars_to_acquire. Acquire it!
-    this->vars.swap(*vars_to_acquire);
+    this->vars = std::move(*vars_to_acquire);
 }
 
 void env_universal_t::load_from_fd(int fd, callback_data_list_t *callbacks) {
@@ -480,9 +471,9 @@ bool env_universal_t::write_to_fd(int fd, const wcstring &path) {
         // Flush if this is the last iteration or we exceed a page.
         if (iter == vars.end() || contents.size() >= 4096) {
             if (write_loop(fd, contents.data(), contents.size()) < 0) {
-                int err = errno;
-                report_error(err, L"Unable to write to universal variables file '%ls'",
-                             path.c_str());
+                const char *error = strerror(errno);
+                debug(0, _(L"Unable to write to universal variables file '%ls': %s"), path.c_str(),
+                      error);
                 success = false;
                 break;
             }
@@ -500,45 +491,13 @@ bool env_universal_t::write_to_fd(int fd, const wcstring &path) {
 bool env_universal_t::move_new_vars_file_into_place(const wcstring &src, const wcstring &dst) {
     int ret = wrename(src, dst);
     if (ret != 0) {
-        int err = errno;
-        report_error(err, L"Unable to rename file from '%ls' to '%ls'", src.c_str(), dst.c_str());
+        const char *error = strerror(errno);
+        debug(0, _(L"Unable to rename file from '%ls' to '%ls': %s"), src.c_str(), dst.c_str(),
+              error);
     }
     return ret == 0;
 }
 
-static wcstring fishd_get_config() {
-    bool done = false;
-    wcstring result;
-
-    env_var_t xdg_dir = env_get_string(L"XDG_CONFIG_HOME", ENV_GLOBAL | ENV_EXPORT);
-    if (!xdg_dir.missing_or_empty()) {
-        result = xdg_dir;
-        append_path_component(result, L"/fish");
-        if (!create_directory(result)) {
-            done = true;
-        }
-    } else {
-        env_var_t home = env_get_string(L"HOME", ENV_GLOBAL | ENV_EXPORT);
-        if (!home.missing_or_empty()) {
-            result = home;
-            append_path_component(result, L"/.config/fish");
-            if (!create_directory(result)) {
-                done = 1;
-            }
-        }
-    }
-
-    if (!done) {
-        // Bad juju.
-        debug(0, _(L"Unable to create a configuration directory for fish. Your personal settings "
-                   L"will not be saved. Please set the $XDG_CONFIG_HOME variable to a directory "
-                   L"where the current user has write access."));
-        result.clear();
-    }
-
-    return result;
-}
-
 bool env_universal_t::load() {
     scoped_lock locker(lock);
     callback_data_list_t callbacks;
@@ -567,24 +526,15 @@ bool env_universal_t::open_temporary_file(const wcstring &directory, wcstring *o
     // Create and open a temporary file for writing within the given directory. Try to create a
     // temporary file, up to 10 times. We don't use mkstemps because we want to open it CLO_EXEC.
     // This should almost always succeed on the first try.
-    assert(!string_suffixes_string(L"/", directory));
+    assert(!string_suffixes_string(L"/", directory));  //!OCLINT(multiple unary operator)
 
     bool success = false;
-    int saved_errno = 0;
+    int saved_errno;
     const wcstring tmp_name_template = directory + L"/fishd.tmp.XXXXXX";
-    wcstring tmp_name;
 
     for (size_t attempt = 0; attempt < 10 && !success; attempt++) {
         char *narrow_str = wcs2str(tmp_name_template.c_str());
-#if HAVE_MKOSTEMP
-        int result_fd = mkostemp(narrow_str, O_CLOEXEC);
-#else
-        int result_fd = mkstemp(narrow_str);
-        if (result_fd != -1) {
-            fcntl(result_fd, F_SETFD, FD_CLOEXEC);
-        }
-#endif
-
+        int result_fd = fish_mkstemp_cloexec(narrow_str);
         saved_errno = errno;
         success = result_fd != -1;
         *out_fd = result_fd;
@@ -593,11 +543,34 @@ bool env_universal_t::open_temporary_file(const wcstring &directory, wcstring *o
     }
 
     if (!success) {
-        report_error(saved_errno, L"Unable to open temporary file '%ls'", out_path->c_str());
+        const char *error = strerror(saved_errno);
+        debug(0, _(L"Unable to open temporary file '%ls': %s"), out_path->c_str(), error);
     }
     return success;
 }
 
+/// Check how long the operation took and print a message if it took too long.
+/// Returns false if it took too long else true.
+static bool check_duration(double start_time) {
+    double duration = timef() - start_time;
+    if (duration > 0.25) {
+        debug(1, _(L"Locking the universal var file took too long (%.3f seconds)."), duration);
+        return false;
+    }
+    return true;
+}
+
+/// Try locking the file. Return true if we succeeded else false. This is safe in terms of the
+/// fallback function implemented in terms of fcntl: only ever run on the main thread, and protected
+/// by the universal variable lock.
+static bool lock_uvar_file(int fd) {
+    double start_time = timef();
+    while (flock(fd, LOCK_EX) == -1) {
+        if (errno != EINTR) return false;  // do nothing per issue #2149
+    }
+    return check_duration(start_time);
+}
+
 bool env_universal_t::open_and_acquire_lock(const wcstring &path, int *out_fd) {
     // Attempt to open the file for reading at the given path, atomically acquiring a lock. On BSD,
     // we can use O_EXLOCK. On Linux, we open the file, take a lock, and then compare fstat() to
@@ -605,23 +578,25 @@ bool env_universal_t::open_and_acquire_lock(const wcstring &path, int *out_fd) {
     //
     // We pass O_RDONLY with O_CREAT; this creates a potentially empty file. We do this so that we
     // have something to lock on.
-    int result_fd = -1;
+    static std::atomic do_locking(true);
     bool needs_lock = true;
     int flags = O_RDWR | O_CREAT;
+
 #ifdef O_EXLOCK
-    flags |= O_EXLOCK;
-    needs_lock = false;
+    if (do_locking) {
+        flags |= O_EXLOCK;
+        needs_lock = false;
+    }
 #endif
-    for (;;) {
-        int fd = wopen_cloexec(path, flags, 0644);
-        if (fd < 0) {
-            int err = errno;
-            if (err == EINTR) {
-                /* Signal; try again */
-                continue;
-            }
+
+    int fd = -1;
+    while (fd == -1) {
+        double start_time = timef();
+        fd = wopen_cloexec(path, flags, 0644);
+        if (fd == -1) {
+            if (errno == EINTR) continue;  // signaled; try again
 #ifdef O_EXLOCK
-            else if (err == ENOTSUP || err == EOPNOTSUPP) {
+            if (do_locking && (errno == ENOTSUP || errno == EOPNOTSUPP)) {
                 // Filesystem probably does not support locking. Clear the flag and try again. Note
                 // that we try taking the lock via flock anyways. Note that on Linux the two errno
                 // symbols have the same value but on BSD they're different.
@@ -630,25 +605,20 @@ bool env_universal_t::open_and_acquire_lock(const wcstring &path, int *out_fd) {
                 continue;
             }
 #endif
-            else {
-                report_error(err, L"Unable to open universal variable file '%ls'", path.c_str());
-                break;
-            }
+            const char *error = strerror(errno);
+            debug(0, _(L"Unable to open universal variable file '%ls': %s"), path.c_str(), error);
+            break;
         }
 
-        // If we get here, we must have a valid fd.
-        assert(fd >= 0);
+        assert(fd >= 0);  // if we get here, we must have a valid fd
+        if (!needs_lock && do_locking) {
+            do_locking = check_duration(start_time);
+        }
 
         // Try taking the lock, if necessary. If we failed, we may be on lockless NFS, etc.; in that
         // case we pretend we succeeded. See the comment in save_to_path for the rationale.
-        if (needs_lock) {
-            while (flock(fd, LOCK_EX) < 0) {
-                /* error */
-                if (errno != EINTR) {
-                    /* Do nothing per #2149 */
-                    break;
-                }
-            }
+        if (needs_lock && do_locking) {
+            do_locking = lock_uvar_file(fd);
         }
 
         // Hopefully we got the lock. However, it's possible the file changed out from under us
@@ -656,18 +626,12 @@ bool env_universal_t::open_and_acquire_lock(const wcstring &path, int *out_fd) {
         if (file_id_for_fd(fd) != file_id_for_path(path)) {
             // Oops, it changed! Try again.
             close(fd);
-            continue;
+            fd = -1;
         }
-
-        // Finally, we have an fd that's valid and hopefully locked. We're done.
-        assert(fd >= 0);
-        result_fd = fd;
-        break;
     }
 
-    *out_fd = result_fd;
-
-    return result_fd >= 0;
+    *out_fd = fd;
+    return fd >= 0;
 }
 
 // Returns true if modified variables were written, false if not. (There may still be variable
@@ -881,7 +845,7 @@ void env_universal_t::parse_message_internal(const wcstring &msgstr, var_table_t
             if (unescape_string(tmp + 1, &val, 0)) {
                 var_entry_t &entry = (*vars)[key];
                 entry.exportv = exportv;
-                entry.val.swap(val);  // acquire the value
+                entry.val = std::move(val);  // acquire the value
             }
         } else {
             debug(1, PARSE_ERR, msg);
@@ -902,6 +866,7 @@ void env_universal_t::parse_message_internal(const wcstring &msgstr, var_table_t
 
 // Linux
 #include 
+#include 
 static bool get_mac_address(unsigned char macaddr[MAC_ADDRESS_MAX_LEN],
                             const char *interface = "eth0") {
     bool result = false;
@@ -924,6 +889,7 @@ static bool get_mac_address(unsigned char macaddr[MAC_ADDRESS_MAX_LEN],
 // OS X and BSD
 #include 
 #include 
+#include 
 static bool get_mac_address(unsigned char macaddr[MAC_ADDRESS_MAX_LEN],
                             const char *interface = "en0") {
     // BSD, Mac OS X
@@ -986,6 +952,7 @@ wcstring get_machine_identifier() {
 }
 
 class universal_notifier_shmem_poller_t : public universal_notifier_t {
+#ifdef __CYGWIN__
     // This is what our shared memory looks like. Everything here is stored in network byte order
     // (big-endian).
     struct universal_notifier_shmem_t {
@@ -1013,8 +980,8 @@ class universal_notifier_shmem_poller_t : public universal_notifier_t {
         bool errored = false;
         int fd = shm_open(path, O_RDWR | O_CREAT, 0600);
         if (fd < 0) {
-            int err = errno;
-            report_error(err, L"Unable to open shared memory with path '%s'", path);
+            const char *error = strerror(errno);
+            debug(0, _(L"Unable to open shared memory with path '%s': %s"), path, error);
             errored = true;
         }
 
@@ -1023,8 +990,9 @@ class universal_notifier_shmem_poller_t : public universal_notifier_t {
         if (!errored) {
             struct stat buf = {};
             if (fstat(fd, &buf) < 0) {
-                int err = errno;
-                report_error(err, L"Unable to fstat shared memory object with path '%s'", path);
+                const char *error = strerror(errno);
+                debug(0, _(L"Unable to fstat shared memory object with path '%s': %s"), path,
+                      error);
                 errored = true;
             }
             size = buf.st_size;
@@ -1033,8 +1001,8 @@ class universal_notifier_shmem_poller_t : public universal_notifier_t {
         // Set the size, if it's too small.
         bool set_size = !errored && size < (off_t)sizeof(universal_notifier_shmem_t);
         if (set_size && ftruncate(fd, sizeof(universal_notifier_shmem_t)) < 0) {
-            int err = errno;
-            report_error(err, L"Unable to truncate shared memory object with path '%s'", path);
+            const char *error = strerror(errno);
+            debug(0, _(L"Unable to truncate shared memory object with path '%s': %s"), path, error);
             errored = true;
         }
 
@@ -1043,9 +1011,9 @@ class universal_notifier_shmem_poller_t : public universal_notifier_t {
             void *addr = mmap(NULL, sizeof(universal_notifier_shmem_t), PROT_READ | PROT_WRITE,
                               MAP_SHARED, fd, 0);
             if (addr == MAP_FAILED) {
-                int err = errno;
-                report_error(err, L"Unable to memory map shared memory object with path '%s'",
-                             path);
+                const char *error = strerror(errno);
+                debug(0, _(L"Unable to memory map shared memory object with path '%s': %s"), path,
+                      error);
                 this->region = NULL;
             } else {
                 this->region = static_cast(addr);
@@ -1059,7 +1027,6 @@ class universal_notifier_shmem_poller_t : public universal_notifier_t {
 
         // Read the current seed.
         this->poll();
-        // cppcheck-suppress memleak // addr not really leaked
     }
 
    public:
@@ -1123,16 +1090,22 @@ class universal_notifier_shmem_poller_t : public universal_notifier_t {
         }
         return usec_per_sec / 3;  // 3 times a second
     }
+#else  // this class isn't valid on this system
+   public:
+    universal_notifier_shmem_poller_t() {
+        DIE("universal_notifier_shmem_poller_t cannot be used on this system");
+    }
+#endif
 };
 
 /// A notifyd-based notifier. Very straightforward.
 class universal_notifier_notifyd_t : public universal_notifier_t {
+#if FISH_NOTIFYD_AVAILABLE
     int notify_fd;
     int token;
     std::string name;
 
     void setup_notifyd() {
-#if FISH_NOTIFYD_AVAILABLE
         // Per notify(3), the user.uid.%d style is only accessible to processes with that uid.
         char local_name[256];
         snprintf(local_name, sizeof local_name, "user.uid.%d.%ls.uvars", getuid(),
@@ -1142,10 +1115,8 @@ class universal_notifier_notifyd_t : public universal_notifier_t {
         uint32_t status =
             notify_register_file_descriptor(name.c_str(), &this->notify_fd, 0, &this->token);
         if (status != NOTIFY_STATUS_OK) {
-            fprintf(stderr,
-                    "Warning: notify_register_file_descriptor() failed with status %u. Universal "
-                    "variable notifications may not be received.",
-                    status);
+            debug(1, "notify_register_file_descriptor() failed with status %u.", status);
+            debug(1, "Universal variable notifications may not be received.");
         }
         if (this->notify_fd >= 0) {
             // Mark us for non-blocking reads, and CLO_EXEC.
@@ -1161,7 +1132,6 @@ class universal_notifier_notifyd_t : public universal_notifier_t {
             // marked as CLO_EXEC, that's probably a good thing.
             set_cloexec(this->notify_fd + 1);
         }
-#endif
     }
 
    public:
@@ -1171,9 +1141,7 @@ class universal_notifier_notifyd_t : public universal_notifier_t {
 
     ~universal_notifier_notifyd_t() {
         if (token != -1 /* NOTIFY_TOKEN_INVALID */) {
-#if FISH_NOTIFYD_AVAILABLE
             notify_cancel(token);
-#endif
         }
     }
 
@@ -1194,20 +1162,24 @@ class universal_notifier_notifyd_t : public universal_notifier_t {
     }
 
     void post_notification() {
-#if FISH_NOTIFYD_AVAILABLE
         uint32_t status = notify_post(name.c_str());
         if (status != NOTIFY_STATUS_OK) {
-            fprintf(stderr,
-                    "Warning: notify_post() failed with status %u. Universal variable "
-                    "notifications may not be sent.",
-                    status);
+            debug(1, "notify_post() failed with status %u. Uvar notifications may not be sent.",
+                  status);
         }
-#endif
     }
+#else  // this class isn't valid on this system
+   public:
+    universal_notifier_notifyd_t() {
+        DIE("universal_notifier_notifyd_t cannot be used on this system");
+    }
+#endif
 };
 
-#define NAMED_PIPE_FLASH_DURATION_USEC (1000000 / 10)
-#define SUSTAINED_READABILITY_CLEANUP_DURATION_USEC (1000000 * 5)
+#if !defined(__APPLE__) && !defined(__CYGWIN__)
+#define NAMED_PIPE_FLASH_DURATION_USEC (1e5)
+#define SUSTAINED_READABILITY_CLEANUP_DURATION_USEC (5 * 1e6)
+#endif
 
 // Named-pipe based notifier. All clients open the same named pipe for reading and writing. The
 // pipe's readability status is a trigger to enter polling mode.
@@ -1219,6 +1191,7 @@ class universal_notifier_notifyd_t : public universal_notifier_t {
 // when there is data remaining in the pipe, if the pipe is kept readable too long, clients will
 // attempt to read data out of it (to render it no longer readable).
 class universal_notifier_named_pipe_t : public universal_notifier_t {
+#if !defined(__APPLE__) && !defined(__CYGWIN__)
     int pipe_fd;
     long long readback_time_usec;
     size_t readback_amount;
@@ -1226,35 +1199,7 @@ class universal_notifier_named_pipe_t : public universal_notifier_t {
     bool polling_due_to_readable_fd;
     long long drain_if_still_readable_time_usec;
 
-    void make_pipe(const wchar_t *test_path) {
-        wcstring vars_path = test_path ? wcstring(test_path) : default_named_pipe_path();
-        vars_path.append(L".notifier");
-        const std::string narrow_path = wcs2string(vars_path);
-
-        int fd = wopen_cloexec(vars_path, O_RDWR | O_NONBLOCK, 0600);
-        if (fd < 0 && errno == ENOENT) {
-            // File doesn't exist, try creating it.
-            int mkfifo_status = mkfifo(narrow_path.c_str(), 0600);
-            if (mkfifo_status != -1) {
-                fd = wopen_cloexec(vars_path, O_RDWR | O_NONBLOCK, 0600);
-            }
-        }
-
-        if (fd < 0) {
-            // Maybe open failed, maybe mkfifo failed.
-            int err = errno;
-            // We explicitly do NOT report an error for ENOENT or EACCESS. This works around #1955,
-            // where $XDG_RUNTIME_DIR may get a bogus value under success.
-            if (err != ENOENT && err != EPERM) {
-                report_error(
-                    err, L"Unable to make or open a FIFO for universal variables with path '%ls'",
-                    vars_path.c_str());
-            }
-            pipe_fd = -1;
-        } else {
-            pipe_fd = fd;
-        }
-    }
+    void make_pipe(const wchar_t *test_path);
 
     void drain_excessive_data() {
         // The pipe seems to have data on it, that won't go away. Read a big chunk out of it. We
@@ -1267,7 +1212,7 @@ class universal_notifier_named_pipe_t : public universal_notifier_t {
     }
 
    public:
-    explicit universal_notifier_named_pipe_t(const wchar_t *test_path)
+    universal_notifier_named_pipe_t(const wchar_t *test_path)
         : pipe_fd(-1),
           readback_time_usec(0),
           readback_amount(0),
@@ -1393,52 +1338,16 @@ class universal_notifier_named_pipe_t : public universal_notifier_t {
         }
         return true;
     }
+#else  // this class isn't valid on this system
+   public:
+    universal_notifier_named_pipe_t(const wchar_t *test_path) {
+        static_cast(test_path);
+        DIE("universal_notifier_named_pipe_t cannot be used on this system");
+    }
+#endif
 };
 
-class universal_notifier_null_t : public universal_notifier_t {};  // does nothing
-
-static universal_notifier_t::notifier_strategy_t fetch_default_strategy_from_environment() {
-    universal_notifier_t::notifier_strategy_t result = universal_notifier_t::strategy_default;
-
-    const struct {
-        const char *name;
-        universal_notifier_t::notifier_strategy_t strat;
-    } options[] = {{"default", universal_notifier_t::strategy_default},
-                   {"shmem", universal_notifier_t::strategy_shmem_polling},
-                   {"pipe", universal_notifier_t::strategy_named_pipe},
-                   {"notifyd", universal_notifier_t::strategy_notifyd}};
-    const size_t opt_count = sizeof options / sizeof *options;
-
-    const char *var = getenv(UNIVERSAL_NOTIFIER_ENV_NAME);
-    if (var == NULL || var[0] == '\0') {
-        return result;
-    }
-
-    size_t i;
-    for (i = 0; i < opt_count; i++) {
-        if (!strcmp(var, options[i].name)) {
-            result = options[i].strat;
-            break;
-        }
-    }
-    if (i >= opt_count) {
-        fprintf(stderr, "Warning: unrecognized value for %s: '%s'\n",
-                UNIVERSAL_NOTIFIER_ENV_NAME, var);
-        fprintf(stderr, "Warning: valid values are ");
-        for (size_t j = 0; j < opt_count; j++) {
-            fprintf(stderr, "%s%s", j > 0 ? ", " : "", options[j].name);
-        }
-        fputc('\n', stderr);
-    }
-    return result;
-}
-
 universal_notifier_t::notifier_strategy_t universal_notifier_t::resolve_default_strategy() {
-    static universal_notifier_t::notifier_strategy_t s_explicit_strategy =
-        fetch_default_strategy_from_environment();
-    if (s_explicit_strategy != strategy_default) {
-        return s_explicit_strategy;
-    }
 #if FISH_NOTIFYD_AVAILABLE
     return strategy_notifyd;
 #elif defined(__CYGWIN__)
@@ -1449,30 +1358,25 @@ universal_notifier_t::notifier_strategy_t universal_notifier_t::resolve_default_
 }
 
 universal_notifier_t &universal_notifier_t::default_notifier() {
-    static universal_notifier_t *result = new_notifier_for_strategy(strategy_default);
+    static std::unique_ptr result =
+        new_notifier_for_strategy(universal_notifier_t::resolve_default_strategy());
     return *result;
 }
 
-universal_notifier_t *universal_notifier_t::new_notifier_for_strategy(
+std::unique_ptr universal_notifier_t::new_notifier_for_strategy(
     universal_notifier_t::notifier_strategy_t strat, const wchar_t *test_path) {
-    if (strat == strategy_default) {
-        strat = resolve_default_strategy();  //!OCLINT(parameter reassignment)
-    }
     switch (strat) {
-        case strategy_shmem_polling: {
-            return new universal_notifier_shmem_poller_t();
-        }
         case strategy_notifyd: {
-            return new universal_notifier_notifyd_t();
+            return make_unique();
+        }
+        case strategy_shmem_polling: {
+            return make_unique();
         }
         case strategy_named_pipe: {
-            return new universal_notifier_named_pipe_t(test_path);
-        }
-        case strategy_null: {
-            return new universal_notifier_null_t();
+            return make_unique(test_path);
         }
         default: {
-            fprintf(stderr, "Unsupported strategy %d\n", strat);
+            debug(0, "Unsupported universal notifier strategy %d\n", strat);
             return NULL;
         }
     }
@@ -1495,3 +1399,31 @@ bool universal_notifier_t::notification_fd_became_readable(int fd) {
     UNUSED(fd);
     return false;
 }
+
+#if !defined(__APPLE__) && !defined(__CYGWIN__)
+void universal_notifier_named_pipe_t::make_pipe(const wchar_t *test_path) {
+    wcstring vars_path = test_path ? wcstring(test_path) : default_named_pipe_path();
+    vars_path.append(L".notifier");
+    const std::string narrow_path = wcs2string(vars_path);
+
+    int mkfifo_status = mkfifo(narrow_path.c_str(), 0600);
+    if (mkfifo_status == -1 && errno != EEXIST) {
+        const char *error = strerror(errno);
+        const wchar_t *errmsg = _(L"Unable to make a pipe for universal variables using '%ls': %s");
+        debug(0, errmsg, vars_path.c_str(), error);
+        pipe_fd = -1;
+        return;
+    }
+
+    int fd = wopen_cloexec(vars_path, O_RDWR | O_NONBLOCK, 0600);
+    if (fd < 0) {
+        const char *error = strerror(errno);
+        const wchar_t *errmsg = _(L"Unable to open a pipe for universal variables using '%ls': %s");
+        debug(0, errmsg, vars_path.c_str(), error);
+        pipe_fd = -1;
+        return;
+    }
+
+    pipe_fd = fd;
+}
+#endif
diff --git a/src/env_universal_common.h b/src/env_universal_common.h
index 0675cbe52..dcd7b0756 100644
--- a/src/env_universal_common.h
+++ b/src/env_universal_common.h
@@ -1,5 +1,6 @@
 #ifndef FISH_ENV_UNIVERSAL_COMMON_H
 #define FISH_ENV_UNIVERSAL_COMMON_H
+#include "config.h"  // IWYU pragma: keep
 
 #include 
 #include 
@@ -112,22 +113,14 @@ class env_universal_t {
 class universal_notifier_t {
    public:
     enum notifier_strategy_t {
-        // Default meta-strategy to use the 'best' notifier for the system.
-        strategy_default,
-
         // Use a value in shared memory. Simple, but requires polling and therefore semi-frequent
         // wakeups.
         strategy_shmem_polling,
-
+        // Strategy that uses notify(3). Simple and efficient, but OS X/macOS only.
+        strategy_notifyd,
         // Strategy that uses a named pipe. Somewhat complex, but portable and doesn't require
         // polling most of the time.
         strategy_named_pipe,
-
-        // Strategy that uses notify(3). Simple and efficient, but OS X only.
-        strategy_notifyd,
-
-        // Null notifier, does nothing.
-        strategy_null
     };
 
    protected:
@@ -137,14 +130,14 @@ class universal_notifier_t {
     // No copying.
     universal_notifier_t &operator=(const universal_notifier_t &);
     universal_notifier_t(const universal_notifier_t &x);
-    static notifier_strategy_t resolve_default_strategy();
 
    public:
+    static notifier_strategy_t resolve_default_strategy();
     virtual ~universal_notifier_t();
 
-    // Factory constructor. Free with delete.
-    static universal_notifier_t *new_notifier_for_strategy(notifier_strategy_t strat,
-                                                           const wchar_t *test_path = NULL);
+    // Factory constructor.
+    static std::unique_ptr new_notifier_for_strategy(
+        notifier_strategy_t strat, const wchar_t *test_path = NULL);
 
     // Default instance. Other instances are possible for testing.
     static universal_notifier_t &default_notifier();
diff --git a/src/event.cpp b/src/event.cpp
index 31651054c..daac533e8 100644
--- a/src/event.cpp
+++ b/src/event.cpp
@@ -39,12 +39,10 @@ static signal_list_t sig_list[2] = {{}, {}};
 /// The index of sig_list that is the list of signals currently written to.
 static volatile int active_list = 0;
 
-typedef std::vector event_list_t;
+typedef std::vector> event_list_t;
 
 /// List of event handlers.
 static event_list_t s_event_handlers;
-/// List of event handlers that should be removed.
-static event_list_t killme;
 
 /// List of events that have been sent but have not yet been delivered because they are blocked.
 static event_list_t blocked;
@@ -162,11 +160,11 @@ wcstring event_get_desc(const event_t &e) {
 
 #if 0
 static void show_all_handlers(void) {
-    puts("event handlers:");
+    fwprintf(stdout, L"event handlers:\n");
     for (event_list_t::const_iterator iter = events.begin(); iter != events.end(); ++iter) {
         const event_t *foo = *iter;
         wcstring tmp = event_get_desc(foo);
-        printf("    handler now %ls\n", tmp.c_str());
+        fwprintf(stdout, L"    handler now %ls\n", tmp.c_str());
     }
 }
 #endif
@@ -242,61 +240,51 @@ static wcstring event_desc_compact(const event_t &event) {
 }
 
 void event_add_handler(const event_t &event) {
-    event_t *e;
-
     if (debug_level >= 3) {
         wcstring desc = event_desc_compact(event);
         debug(3, "register: %ls\n", desc.c_str());
     }
 
-    e = new event_t(event);
+    shared_ptr e = std::make_shared(event);
     if (e->type == EVENT_SIGNAL) {
         signal_handle(e->param1.signal, 1);
         set_signal_observed(e->param1.signal, true);
     }
 
-    s_event_handlers.push_back(e);
+    s_event_handlers.push_back(std::move(e));
 }
 
 void event_remove(const event_t &criterion) {
-    event_list_t new_list;
-
     if (debug_level >= 3) {
         wcstring desc = event_desc_compact(criterion);
         debug(3, "unregister: %ls\n", desc.c_str());
     }
 
-    // Because of concurrency issues (env_remove could remove an event that is currently being
-    // executed), env_remove does not actually free any events - instead it simply moves all events
-    // that should be removed from the event list to the killme list, and the ones that shouldn't be
-    // killed to new_list, and then drops the empty events-list.
-    if (s_event_handlers.empty()) return;
-
-    for (size_t i = 0; i < s_event_handlers.size(); i++) {
-        event_t *n = s_event_handlers.at(i);
-        if (event_match(criterion, *n)) {
-            killme.push_back(n);
-
-            // If this event was a signal handler and no other handler handles the specified signal
-            // type, do not handle that type of signal any more.
-            if (n->type == EVENT_SIGNAL) {
-                event_t e = event_t::signal_event(n->param1.signal);
-                if (event_get(e, 0) == 1) {
-                    signal_handle(e.param1.signal, 0);
-                    set_signal_observed(e.param1.signal, 0);
-                }
-            }
-        } else {
-            new_list.push_back(n);
+    event_list_t::iterator iter = s_event_handlers.begin();
+    while (iter != s_event_handlers.end()) {
+        const event_t *n = iter->get();
+        if (!event_match(criterion, *n)) {
+            ++iter;
+            continue;
         }
+
+        // If this event was a signal handler and no other handler handles the specified signal
+        // type, do not handle that type of signal any more.
+        if (n->type == EVENT_SIGNAL) {
+            event_t e = event_t::signal_event(n->param1.signal);
+            if (event_get(e, NULL) == 1) {
+                signal_handle(e.param1.signal, 0);
+                set_signal_observed(e.param1.signal, 0);
+            }
+        }
+        iter = s_event_handlers.erase(iter);
     }
-    s_event_handlers.swap(new_list);
 }
 
-int event_get(const event_t &criterion, std::vector *out) {
+int event_get(const event_t &criterion, event_list_t *out) {
+    ASSERT_IS_MAIN_THREAD();
     int found = 0;
-    for (size_t i = 0; i < s_event_handlers.size(); i++) {
-        event_t *n = s_event_handlers.at(i);
+    for (const shared_ptr &n : s_event_handlers) {
         if (event_match(criterion, *n)) {
             found++;
             if (out) out->push_back(n);
@@ -314,44 +302,15 @@ bool event_is_signal_observed(int sig) {
     return result;
 }
 
-/// Free all events in the kill list.
-static void event_free_kills() {
-    for_each(killme.begin(), killme.end(), event_free);
-    killme.resize(0);
-}
-
-/// Test if the specified event is waiting to be killed.
-static int event_is_killed(const event_t &e) {
-    return std::find(killme.begin(), killme.end(), &e) != killme.end();
-}
-
-/// Callback for firing (and then deleting) an event.
-static void fire_event_callback(void *arg) {
-    ASSERT_IS_MAIN_THREAD();
-    assert(arg != NULL);
-    event_t *event = static_cast(arg);
-    event_fire(event);
-    delete event;
-}
-
 /// Perform the specified event. Since almost all event firings will not be matched by even a single
 /// event handler, we make sure to optimize the 'no matches' path. This means that nothing is
 /// allocated/initialized unless needed.
 static void event_fire_internal(const event_t &event) {
-    event_list_t fire;
-
-    // First we free all events that have been removed, but only if this invocation of
-    // event_fire_internal is not a recursive call.
-    if (is_event <= 1) event_free_kills();
-
-    if (s_event_handlers.empty()) return;
-
-    // Then we iterate over all events, adding events that should be fired to a second list. We need
+    // Iterate over all events, adding events that should be fired to a second list. We need
     // to do this in a separate step since an event handler might call event_remove or
     // event_add_handler, which will change the contents of the \c events list.
-    for (size_t i = 0; i < s_event_handlers.size(); i++) {
-        event_t *criterion = s_event_handlers.at(i);
-
+    event_list_t fire;
+    for (shared_ptr &criterion : s_event_handlers) {
         // Check if this event is a match.
         if (event_match(*criterion, event)) {
             fire.push_back(criterion);
@@ -364,18 +323,20 @@ static void event_fire_internal(const event_t &event) {
     if (signal_is_blocked()) {
         // Fix for https://github.com/fish-shell/fish-shell/issues/608. Don't run event handlers
         // while signals are blocked.
-        event_t *heap_event = new event_t(event);
-        input_common_add_callback(fire_event_callback, heap_event);
+        input_common_add_callback([event]() {
+            ASSERT_IS_MAIN_THREAD();
+            event_fire(&event);
+        });
         return;
     }
 
     // Iterate over our list of matching events.
-    for (size_t i = 0; i < fire.size(); i++) {
-        event_t *criterion = fire.at(i);
-        int prev_status;
-
-        // Check if this event has been removed, if so, dont fire it.
-        if (event_is_killed(*criterion)) continue;
+    for (shared_ptr &criterion : fire) {
+        // Only fire if this event is still present
+        if (std::find(s_event_handlers.begin(), s_event_handlers.end(), criterion) ==
+            s_event_handlers.end()) {
+            continue;
+        }
 
         // Fire event.
         wcstring buffer = criterion->function_name;
@@ -391,19 +352,15 @@ static void event_fire_internal(const event_t &event) {
         // Event handlers are not part of the main flow of code, so they are marked as
         // non-interactive.
         proc_push_interactive(0);
-        prev_status = proc_get_last_status();
+        int prev_status = proc_get_last_status();
         parser_t &parser = parser_t::principal_parser();
 
-        block_t *block = new event_block_t(event);
-        parser.push_block(block);
+        event_block_t *b = parser.push_block(event);
         parser.eval(buffer, io_chain_t(), TOP);
-        parser.pop_block();
+        parser.pop_block(b);
         proc_pop_interactive();
         proc_set_last_status(prev_status);
     }
-
-    // Free killed events.
-    if (is_event <= 1) event_free_kills();
 }
 
 /// Handle all pending signal events.
@@ -413,18 +370,15 @@ static void event_fire_delayed() {
     // When the event handler has called a piece of code that triggers another event, we do not want
     // to fire delayed events because of concurrency problems.
     if (!blocked.empty() && is_event == 1) {
-        event_list_t new_blocked;
-
-        for (size_t i = 0; i < blocked.size(); i++) {
-            event_t *e = blocked.at(i);
+        event_list_t local_blocked;
+        local_blocked.swap(blocked);
+        for (const shared_ptr &e : local_blocked) {
             if (event_is_blocked(*e)) {
-                new_blocked.push_back(new event_t(*e));
+                blocked.push_back(e);
             } else {
                 event_fire_internal(*e);
-                event_free(e);
             }
         }
-        blocked.swap(new_blocked);
     }
 
     int al = active_list;
@@ -440,21 +394,20 @@ static void event_fire_delayed() {
 
         // Set up.
         lst = &sig_list[1 - al];
-        event_t e = event_t::signal_event(0);
-        e.arguments.resize(1);
-
         if (lst->overflow) {
             debug(0, _(L"Signal list overflow. Signals have been ignored."));
         }
 
         // Send all signals in our private list.
         for (int i = 0; i < lst->count; i++) {
-            e.param1.signal = lst->signal[i];
-            e.arguments.at(0) = sig2wcs(e.param1.signal);
-            if (event_is_blocked(e)) {
-                blocked.push_back(new event_t(e));
+            shared_ptr e = std::make_shared(EVENT_SIGNAL);
+            int signal = lst->signal[i];
+            e->param1.signal = signal;
+            e->arguments.push_back(sig2wcs(signal));
+            if (event_is_blocked(*e)) {
+                blocked.push_back(e);
             } else {
-                event_fire_internal(e);
+                event_fire_internal(*e);
             }
         }
     }
@@ -480,7 +433,7 @@ void event_fire(const event_t *event) {
 
         if (event) {
             if (event_is_blocked(*event)) {
-                blocked.push_back(new event_t(*event));
+                blocked.push_back(std::make_shared(*event));
             } else {
                 event_fire_internal(*event);
             }
@@ -491,18 +444,7 @@ void event_fire(const event_t *event) {
 
 void event_init() {}
 
-void event_destroy() {
-    for_each(s_event_handlers.begin(), s_event_handlers.end(), event_free);
-    s_event_handlers.clear();
-
-    for_each(killme.begin(), killme.end(), event_free);
-    killme.clear();
-}
-
-void event_free(event_t *e) {
-    CHECK(e, );
-    delete e;
-}
+void event_destroy() { s_event_handlers.clear(); }
 
 void event_fire_generic(const wchar_t *name, wcstring_list_t *args) {
     CHECK(name, );
diff --git a/src/event.h b/src/event.h
index 077731c7a..809489f44 100644
--- a/src/event.h
+++ b/src/event.h
@@ -7,6 +7,7 @@
 #define FISH_EVENT_H
 
 #include 
+#include 
 #include 
 
 #include "common.h"
@@ -100,7 +101,7 @@ void event_remove(const event_t &event);
 /// result count will still be valid
 ///
 /// \return the number of found matches
-int event_get(const event_t &criterion, std::vector *out);
+int event_get(const event_t &criterion, std::vector> *out);
 
 /// Returns whether an event listener is registered for the given signal. This is safe to call from
 /// a signal handler.
@@ -120,6 +121,7 @@ bool event_is_signal_observed(int signal);
 void event_fire(const event_t *event);
 
 /// Like event_fire, but takes a signal directly.
+/// May be called from signal handlers
 void event_fire_signal(int signal);
 
 /// Initialize the event-handling library.
@@ -128,9 +130,6 @@ void event_init();
 /// Destroy the event-handling library.
 void event_destroy();
 
-/// Free all memory used by the specified event.
-void event_free(event_t *e);
-
 /// Returns a string describing the specified event.
 wcstring event_get_desc(const event_t &e);
 
diff --git a/src/exec.cpp b/src/exec.cpp
index bd6ae4560..f413e3936 100644
--- a/src/exec.cpp
+++ b/src/exec.cpp
@@ -9,16 +9,13 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #ifdef HAVE_SPAWN_H
 #include 
 #endif
-#include 
 #include 
 #include 
 #include 
@@ -211,7 +208,7 @@ static void launch_process_nofork(process_t *p) {
     null_terminated_array_t argv_array;
     convert_wide_array_to_narrow(p->get_argv_array(), &argv_array);
 
-    const char *const *envv = env_export_arr(false);
+    const char *const *envv = env_export_arr();
     char *actual_cmd = wcs2str(p->actual_cmd.c_str());
 
     // Ensure the terminal modes are what they were before we changed them.
@@ -294,8 +291,8 @@ static bool io_transmogrify(const io_chain_t &in_chain, io_chain_t *out_chain,
 
     // Now either return success, or clean up.
     if (success) {
-        out_chain->swap(result_chain);
-        out_opened_fds->swap(opened_fds);
+        *out_chain = std::move(result_chain);
+        *out_opened_fds = std::move(opened_fds);
     } else {
         result_chain.clear();
         io_cleanup_fds(opened_fds);
@@ -348,10 +345,10 @@ static void internal_exec_helper(parser_t &parser, const wcstring &def, node_off
 // foreground process group, we don't use posix_spawn if we're going to foreground the process. (If
 // we use fork(), we can call tcsetpgrp after the fork, before the exec, and avoid the race).
 static bool can_use_posix_spawn_for_job(const job_t *job, const process_t *process) {
-    if (job_get_flag(job, JOB_CONTROL)) {  //!OCLINT(collapsible if statements)
+    if (job->get_flag(JOB_CONTROL)) {  //!OCLINT(collapsible if statements)
         // We are going to use job control; therefore when we launch this job it will get its own
         // process group ID. But will it be foregrounded?
-        if (job_get_flag(job, JOB_TERMINAL) && job_get_flag(job, JOB_FOREGROUND)) {
+        if (job->get_flag(JOB_TERMINAL) && job->get_flag(JOB_FOREGROUND)) {
             // It will be foregrounded, so we will call tcsetpgrp(), therefore do not use
             // posix_spawn.
             return false;
@@ -370,12 +367,10 @@ static bool can_use_posix_spawn_for_job(const job_t *job, const process_t *proce
 
 void exec_job(parser_t &parser, job_t *j) {
     pid_t pid = 0;
-    sigset_t chldset;
 
     // Set to true if something goes wrong while exec:ing the job, in which case the cleanup code
     // will kick in.
     bool exec_error = false;
-
     bool needs_keepalive = false;
     process_t keepalive;
 
@@ -387,9 +382,6 @@ void exec_job(parser_t &parser, job_t *j) {
         return;
     }
 
-    sigemptyset(&chldset);
-    sigaddset(&chldset, SIGCHLD);
-
     debug(4, L"Exec job '%ls' with id %d", j->command_wcstr(), j->job_id);
 
     // Verify that all IO_BUFFERs are output. We used to support a (single, hacked-in) magical input
@@ -405,7 +397,7 @@ void exec_job(parser_t &parser, job_t *j) {
         }
     }
 
-    if (j->first_process->type == INTERNAL_EXEC) {
+    if (j->processes.front()->type == INTERNAL_EXEC) {
         // Do a regular launch -  but without forking first...
         signal_block();
 
@@ -421,20 +413,18 @@ void exec_job(parser_t &parser, job_t *j) {
             const env_var_t shlvl_str = env_get_string(L"SHLVL", ENV_GLOBAL | ENV_EXPORT);
             wcstring nshlvl_str = L"0";
             if (!shlvl_str.missing()) {
-                wchar_t *end;
-                long shlvl_i = wcstol(shlvl_str.c_str(), &end, 10);
-                while (iswspace(*end)) ++end;  // skip trailing whitespace
-                if (shlvl_i > 0 && *end == '\0') {
+                long shlvl_i = fish_wcstol(shlvl_str.c_str());
+                if (!errno && shlvl_i > 0) {
                     nshlvl_str = to_string(shlvl_i - 1);
                 }
             }
             env_set(L"SHLVL", nshlvl_str.c_str(), ENV_GLOBAL | ENV_EXPORT);
 
             // launch_process _never_ returns.
-            launch_process_nofork(j->first_process);
+            launch_process_nofork(j->processes.front().get());
         } else {
-            job_set_flag(j, JOB_CONSTRUCTED, 1);
-            j->first_process->completed = 1;
+            j->set_flag(JOB_CONSTRUCTED, true);
+            j->processes.front()->completed = 1;
             return;
         }
         DIE("this should be unreachable");
@@ -450,7 +440,7 @@ void exec_job(parser_t &parser, job_t *j) {
             if (!io_buffer->avoid_conflicts_with_io_chain(all_ios)) {
                 // We could not avoid conflicts, probably due to fd exhaustion. Mark an error.
                 exec_error = true;
-                job_mark_process_as_failed(j, j->first_process);
+                job_mark_process_as_failed(j, j->processes.front().get());
                 break;
             }
         }
@@ -462,14 +452,10 @@ void exec_job(parser_t &parser, job_t *j) {
     // sure that the process group doesn't die accidentally, and is often needed when a
     // builtin/block/function is inside a pipeline, since that usually means we have to wait for one
     // program to exit before continuing in the pipeline, causing the group leader to exit.
-    if (job_get_flag(j, JOB_CONTROL) && !exec_error) {
-        for (const process_t *p = j->first_process; p; p = p->next) {
+    if (j->get_flag(JOB_CONTROL) && !exec_error) {
+        for (const process_ptr_t &p : j->processes) {
             if (p->type != EXTERNAL) {
-                if (p->next) {
-                    needs_keepalive = true;
-                    break;
-                }
-                if (p != j->first_process) {
+                if (!p->is_last_in_job || !p->is_first_in_job) {
                     needs_keepalive = true;
                     break;
                 }
@@ -508,7 +494,11 @@ void exec_job(parser_t &parser, job_t *j) {
     // We are careful to set these to -1 when closed, so if we exit the loop abruptly, we can still
     // close them.
     int pipe_current_read = -1, pipe_current_write = -1, pipe_next_read = -1;
-    for (process_t *p = j->first_process; p != NULL && !exec_error; p = p->next) {
+    for (std::unique_ptr &unique_p : j->processes) {
+        if (exec_error) {
+            break;
+        }
+        process_t *const p = unique_p.get();
         // The IO chain for this process. It starts with the block IO, then pipes, and then gets any
         // from the process.
         io_chain_t process_net_io_chain = j->block_io_chain();
@@ -519,7 +509,7 @@ void exec_job(parser_t &parser, job_t *j) {
         pipe_next_read = -1;
 
         // See if we need a pipe.
-        const bool pipes_to_next_command = (p->next != NULL);
+        const bool pipes_to_next_command = !p->is_last_in_job;
 
         // The pipes the current process write to and read from. Unfortunately these can't be just
         // allocated on the stack, since j->io wants shared_ptr.
@@ -555,7 +545,7 @@ void exec_job(parser_t &parser, job_t *j) {
         shared_ptr pipe_read;
 
         // Write pipe goes first.
-        if (p->next) {
+        if (pipes_to_next_command) {
             pipe_write.reset(new io_pipe_t(p->pipe_write_fd, false));
             process_net_io_chain.push_back(pipe_write);
         }
@@ -564,7 +554,7 @@ void exec_job(parser_t &parser, job_t *j) {
         process_net_io_chain.append(p->io_chain());
 
         // Read pipe goes last.
-        if (p != j->first_process) {
+        if (!p->is_first_in_job) {
             pipe_read.reset(new io_pipe_t(p->pipe_read_fd, true));
             // Record the current read in pipe_read.
             pipe_read->pipe_fd[0] = pipe_current_read;
@@ -576,7 +566,14 @@ void exec_job(parser_t &parser, job_t *j) {
         // to generate it, since that result would not get written back to the parent. This call
         // could be safely removed, but it would result in slightly lower performance - at least on
         // uniprocessor systems.
-        if (p->type == EXTERNAL) env_export_arr(true);
+        if (p->type == EXTERNAL) {
+            // Apply universal barrier so we have the most recent uvar changes
+            if (!get_proc_had_barrier()) {
+                set_proc_had_barrier(true);
+                env_universal_barrier();
+            }
+            env_export_arr();
+        }
 
         // Set up fds that will be used in the pipe.
         if (pipes_to_next_command) {
@@ -619,7 +616,7 @@ void exec_job(parser_t &parser, job_t *j) {
         shared_ptr block_output_io_buffer;
 
         // This is the io_streams we pass to internal builtins.
-        std::auto_ptr builtin_io_streams;
+        std::unique_ptr builtin_io_streams;
 
         switch (p->type) {
             case INTERNAL_FUNCTION: {
@@ -639,8 +636,9 @@ void exec_job(parser_t &parser, job_t *j) {
                     debug(0, _(L"Unknown function '%ls'"), p->argv0());
                     break;
                 }
-                function_block_t *newv = new function_block_t(p, func_name, shadow_scope);
-                parser.push_block(newv);
+
+                function_block_t *fb =
+                    parser.push_block(p, func_name, shadow_scope);
 
                 // Setting variables might trigger an event handler, hence we need to unblock
                 // signals.
@@ -650,9 +648,9 @@ void exec_job(parser_t &parser, job_t *j) {
 
                 parser.forbid_function(func_name);
 
-                if (p->next) {
+                if (!p->is_last_in_job) {
                     // Be careful to handle failure, e.g. too many open fds.
-                    block_output_io_buffer.reset(io_buffer_t::create(STDOUT_FILENO, all_ios));
+                    block_output_io_buffer = io_buffer_t::create(STDOUT_FILENO, all_ios);
                     if (block_output_io_buffer.get() == NULL) {
                         exec_error = true;
                         job_mark_process_as_failed(j, p);
@@ -671,14 +669,14 @@ void exec_job(parser_t &parser, job_t *j) {
                 }
 
                 parser.allow_function();
-                parser.pop_block();
+                parser.pop_block(fb);
 
                 break;
             }
 
             case INTERNAL_BLOCK_NODE: {
-                if (p->next) {
-                    block_output_io_buffer.reset(io_buffer_t::create(STDOUT_FILENO, all_ios));
+                if (!p->is_last_in_job) {
+                    block_output_io_buffer = io_buffer_t::create(STDOUT_FILENO, all_ios);
                     if (block_output_io_buffer.get() == NULL) {
                         // We failed (e.g. no more fds could be created).
                         exec_error = true;
@@ -703,7 +701,7 @@ void exec_job(parser_t &parser, job_t *j) {
 
                 // If this is the first process, check the io redirections and see where we should
                 // be reading from.
-                if (p == j->first_process) {
+                if (p->is_first_in_job) {
                     const shared_ptr in =
                         process_net_io_chain.get_io_for_fd(STDIN_FILENO);
 
@@ -767,7 +765,7 @@ void exec_job(parser_t &parser, job_t *j) {
                 } else {
                     // Determine if we have a "direct" redirection for stdin.
                     bool stdin_is_directly_redirected;
-                    if (p != j->first_process) {
+                    if (!p->is_first_in_job) {
                         // We must have a pipe
                         stdin_is_directly_redirected = true;
                     } else {
@@ -795,8 +793,8 @@ void exec_job(parser_t &parser, job_t *j) {
                     // way, the builtin does not need to know what job it is part of. It could
                     // probably figure that out by walking the job list, but it seems more robust to
                     // make exec handle things.
-                    const int fg = job_get_flag(j, JOB_FOREGROUND);
-                    job_set_flag(j, JOB_FOREGROUND, 0);
+                    const int fg = j->get_flag(JOB_FOREGROUND);
+                    j->set_flag(JOB_FOREGROUND, false);
 
                     signal_unblock();
 
@@ -806,7 +804,7 @@ void exec_job(parser_t &parser, job_t *j) {
 
                     // Restore the fg flag, which is temporarily set to false during builtin
                     // execution so as not to confuse some job-handling builtins.
-                    job_set_flag(j, JOB_FOREGROUND, fg);
+                    j->set_flag(JOB_FOREGROUND, fg);
                 }
 
                 // If stdin has been redirected, close the redirection stream.
@@ -841,8 +839,8 @@ void exec_job(parser_t &parser, job_t *j) {
                 if (!block_output_io_buffer.get()) {
                     // No buffer, so we exit directly. This means we have to manually set the exit
                     // status.
-                    if (p->next == NULL) {
-                        proc_set_last_status(job_get_flag(j, JOB_NEGATE) ? (!status) : status);
+                    if (p->is_last_in_job) {
+                        proc_set_last_status(j->get_flag(JOB_NEGATE) ? (!status) : status);
                     }
                     p->completed = 1;
                     break;
@@ -876,8 +874,8 @@ void exec_job(parser_t &parser, job_t *j) {
                     }
 
                 } else {
-                    if (p->next == 0) {
-                        proc_set_last_status(job_get_flag(j, JOB_NEGATE) ? (!status) : status);
+                    if (p->is_last_in_job) {
+                        proc_set_last_status(j->get_flag(JOB_NEGATE) ? (!status) : status);
                     }
                     p->completed = 1;
                 }
@@ -906,7 +904,7 @@ void exec_job(parser_t &parser, job_t *j) {
                 // output, so that we can truncate the file. Does not apply to /dev/null.
                 bool must_fork = redirection_is_to_real_file(stdout_io.get()) ||
                                  redirection_is_to_real_file(stderr_io.get());
-                if (!must_fork && p->next == NULL) {
+                if (!must_fork && p->is_last_in_job) {
                     const bool stdout_is_to_buffer = stdout_io && stdout_io->io_mode == IO_BUFFER;
                     const bool no_stdout_output = stdout_buffer.empty();
                     const bool no_stderr_output = stderr_buffer.empty();
@@ -939,6 +937,8 @@ void exec_job(parser_t &parser, job_t *j) {
                         bool builtin_io_done = do_builtin_io(outbuff.data(), outbuff.size(),
                                                              errbuff.data(), errbuff.size());
                         if (!builtin_io_done && errno != EPIPE) {
+                            redirect_tty_output();  // workaround glibc bug
+                            debug(0, "!builtin_io_done and errno != EPIPE");
                             show_stackframe(L'E');
                         }
                         fork_was_skipped = true;
@@ -947,12 +947,12 @@ void exec_job(parser_t &parser, job_t *j) {
 
                 if (fork_was_skipped) {
                     p->completed = 1;
-                    if (p->next == 0) {
+                    if (p->is_last_in_job) {
                         debug(3, L"Set status of %ls to %d using short circuit", j->command_wcstr(),
                               p->status);
 
                         int status = p->status;
-                        proc_set_last_status(job_get_flag(j, JOB_NEGATE) ? (!status) : status);
+                        proc_set_last_status(j->get_flag(JOB_NEGATE) ? (!status) : status);
                     }
                 } else {
                     // Ok, unfortunately, we have to do a real fork. Bummer. We work hard to make
@@ -1006,7 +1006,7 @@ void exec_job(parser_t &parser, job_t *j) {
                 make_fd_blocking(STDIN_FILENO);
 
                 const char *const *argv = argv_array.get();
-                const char *const *envv = env_export_arr(false);
+                const char *const *envv = env_export_arr();
 
                 std::string actual_cmd_str = wcs2string(p->actual_cmd);
                 const char *actual_cmd = actual_cmd_str.c_str();
@@ -1115,8 +1115,8 @@ void exec_job(parser_t &parser, job_t *j) {
     signal_unblock();
     debug(3, L"Job is constructed");
 
-    job_set_flag(j, JOB_CONSTRUCTED, 1);
-    if (!job_get_flag(j, JOB_FOREGROUND)) {
+    j->set_flag(JOB_CONSTRUCTED, true);
+    if (!j->get_flag(JOB_FOREGROUND)) {
         proc_last_bg_pid = j->pgid;
     }
 
@@ -1125,7 +1125,7 @@ void exec_job(parser_t &parser, job_t *j) {
     } else {
         // Mark the errored job as not in the foreground. I can't fully justify whether this is the
         // right place, but it prevents sanity_lose from complaining.
-        job_set_flag(j, JOB_FOREGROUND, 0);
+        j->set_flag(JOB_FOREGROUND, false);
     }
 }
 
@@ -1136,16 +1136,12 @@ static int exec_subshell_internal(const wcstring &cmd, wcstring_list_t *lst,
     const int prev_status = proc_get_last_status();
     bool split_output = false;
 
-    // fprintf(stderr, "subcmd %ls\n", cmd.c_str());
-
     const env_var_t ifs = env_get_string(L"IFS");
-
     if (!ifs.missing_or_empty()) {
         split_output = true;
     }
 
     is_subshell = 1;
-
     int subcommand_status = -1;  // assume the worst
 
     // IO buffer creation may fail (e.g. if we have too many open files to make a pipe), so this may
diff --git a/src/expand.cpp b/src/expand.cpp
index 4bb30bdd4..c17f68882 100644
--- a/src/expand.cpp
+++ b/src/expand.cpp
@@ -150,7 +150,7 @@ static int is_quotable(const wchar_t *str) {
         case L'\t':
         case L'\r':
         case L'\b':
-        case L'\x1b': {
+        case L'\e': {
             return 0;
         }
         default: { return is_quotable(str + 1); }
@@ -166,7 +166,7 @@ wcstring expand_escape_variable(const wcstring &in) {
 
     tokenize_variable_array(in, lst);
 
-    int size = lst.size();
+    size_t size = lst.size();
     if (size == 0) {
         buff.append(L"''");
     } else if (size == 1) {
@@ -393,7 +393,10 @@ bool process_iterator_t::next_process(wcstring *out_str, pid_t *out_pid) {
         if (buf.st_uid != getuid()) continue;
 
         // Remember the pid.
-        pid = fish_wcstoi(name.c_str(), NULL, 10);
+        pid = fish_wcstoi(name.c_str());
+        if (errno || pid < 0) {
+            debug(1, _(L"Unexpected failure to convert pid '%ls' to integer\n"), name.c_str());
+        }
 
         // The 'cmdline' file exists, it should contain the commandline.
         FILE *cmdfile;
@@ -426,25 +429,14 @@ bool process_iterator_t::next_process(wcstring *out_str, pid_t *out_pid) {
 
 #endif
 
-// Helper function to do a job search.
-struct find_job_data_t {
-    const wchar_t *proc;  // the process to search for - possibly numeric, possibly a name
-    expand_flags_t flags;
-    std::vector *completions;
-};
-
 /// The following function is invoked on the main thread, because the job list is not thread safe.
-/// It should search the job list for something matching the given proc, and then return 1 to stop
-/// the search, 0 to continue it.
-static int find_job(const struct find_job_data_t *info) {
+/// It should search the job list for something matching the given proc, and then return true to
+/// stop the search, false to continue it.
+static bool find_job(const wchar_t *proc, expand_flags_t flags,
+                     std::vector *completions) {
     ASSERT_IS_MAIN_THREAD();
 
-    const wchar_t *const proc = info->proc;
-    const expand_flags_t flags = info->flags;
-    std::vector &completions = *info->completions;
-
-    const job_t *j;
-    int found = 0;
+    bool found = false;
     // If we are not doing tab completion, we first check for the single '%' character, because an
     // empty string will pass the numeric check below. But if we are doing tab completion, we want
     // all of the job IDs as completion options, not just the last job backgrounded, so we pass this
@@ -452,20 +444,20 @@ static int find_job(const struct find_job_data_t *info) {
     if (wcslen(proc) == 0 && !(flags & EXPAND_FOR_COMPLETIONS)) {
         // This is an empty job expansion: '%'. It expands to the last job backgrounded.
         job_iterator_t jobs;
-        while ((j = jobs.next())) {
+        while (const job_t *j = jobs.next()) {
             if (!j->command_is_empty()) {
-                append_completion(&completions, to_string(j->pgid));
+                append_completion(completions, to_string(j->pgid));
                 break;
             }
         }
         // You don't *really* want to flip a coin between killing the last process backgrounded and
         // all processes, do you? Let's not try other match methods with the solo '%' syntax.
-        found = 1;
+        found = true;
     } else if (iswnumeric(proc)) {
         // This is a numeric job string, like '%2'.
         if (flags & EXPAND_FOR_COMPLETIONS) {
             job_iterator_t jobs;
-            while ((j = jobs.next())) {
+            while (const job_t *j = jobs.next()) {
                 wchar_t jid[16];
                 if (j->command_is_empty()) continue;
 
@@ -473,25 +465,21 @@ static int find_job(const struct find_job_data_t *info) {
 
                 if (wcsncmp(proc, jid, wcslen(proc)) == 0) {
                     wcstring desc_buff = format_string(COMPLETE_JOB_DESC_VAL, j->command_wcstr());
-                    append_completion(&completions, jid + wcslen(proc), desc_buff, 0);
+                    append_completion(completions, jid + wcslen(proc), desc_buff, 0);
                 }
             }
         } else {
-            int jid;
-            wchar_t *end;
-
-            errno = 0;
-            jid = fish_wcstoi(proc, &end, 10);
-            if (jid > 0 && !errno && !*end) {
-                j = job_get(jid);
-                if ((j != 0) && (j->command_wcstr() != 0) && (!j->command_is_empty())) {
-                    append_completion(&completions, to_string(j->pgid));
+            int jid = fish_wcstoi(proc);
+            if (!errno && jid > 0) {
+                const job_t *j = job_get(jid);
+                if (j && !j->command_is_empty()) {
+                    append_completion(completions, to_string(j->pgid));
                 }
             }
         }
         // Stop here so you can't match a random process name when you're just trying to use job
         // control.
-        found = 1;
+        found = true;
     }
 
     if (found) {
@@ -499,16 +487,16 @@ static int find_job(const struct find_job_data_t *info) {
     }
 
     job_iterator_t jobs;
-    while ((j = jobs.next())) {
+    while (const job_t *j = jobs.next()) {
         if (j->command_is_empty()) continue;
 
         size_t offset;
         if (match_pid(j->command(), proc, &offset)) {
             if (flags & EXPAND_FOR_COMPLETIONS) {
-                append_completion(&completions, j->command_wcstr() + offset + wcslen(proc),
+                append_completion(completions, j->command_wcstr() + offset + wcslen(proc),
                                   COMPLETE_JOB_DESC, 0);
             } else {
-                append_completion(&completions, to_string(j->pgid));
+                append_completion(completions, to_string(j->pgid));
                 found = 1;
             }
         }
@@ -519,19 +507,18 @@ static int find_job(const struct find_job_data_t *info) {
     }
 
     jobs.reset();
-    while ((j = jobs.next())) {
-        process_t *p;
+    while (const job_t *j = jobs.next()) {
         if (j->command_is_empty()) continue;
-        for (p = j->first_process; p; p = p->next) {
+        for (const process_ptr_t &p : j->processes) {
             if (p->actual_cmd.empty()) continue;
 
             size_t offset;
             if (match_pid(p->actual_cmd, proc, &offset)) {
                 if (flags & EXPAND_FOR_COMPLETIONS) {
-                    append_completion(&completions, wcstring(p->actual_cmd, offset + wcslen(proc)),
+                    append_completion(completions, wcstring(p->actual_cmd, offset + wcslen(proc)),
                                       COMPLETE_CHILD_PROCESS_DESC, 0);
                 } else {
-                    append_completion(&completions, to_string(p->pid), L"", 0);
+                    append_completion(completions, to_string(p->pid), L"", 0);
                     found = 1;
                 }
             }
@@ -553,8 +540,8 @@ static int find_job(const struct find_job_data_t *info) {
 static void find_process(const wchar_t *proc, expand_flags_t flags,
                          std::vector *out) {
     if (!(flags & EXPAND_SKIP_JOBS)) {
-        const struct find_job_data_t data = {proc, flags, out};
-        int found = iothread_perform_on_main(find_job, &data);
+        bool found = false;
+        iothread_perform_on_main([&]() { found = find_job(proc, flags, out); });
         if (found) {
             return;
         }
@@ -643,25 +630,22 @@ static bool expand_pid(const wcstring &instr_with_sep, expand_flags_t flags,
 /// with [.
 static size_t parse_slice(const wchar_t *in, wchar_t **end_ptr, std::vector &idx,
                           std::vector &source_positions, size_t array_size) {
-    wchar_t *end;
-
     const long size = (long)array_size;
     size_t pos = 1;  // skip past the opening square bracket
-    //  debug( 0, L"parse_slice on '%ls'", in );
 
     while (1) {
-        long tmp;
-
         while (iswspace(in[pos]) || (in[pos] == INTERNAL_SEPARATOR)) pos++;
         if (in[pos] == L']') {
             pos++;
             break;
         }
 
-        errno = 0;
         const size_t i1_src_pos = pos;
-        tmp = wcstol(&in[pos], &end, 10);
-        if ((errno) || (end == &in[pos])) {
+        const wchar_t *end;
+        long tmp = fish_wcstol(&in[pos], &end);
+        // We don't test `*end` as is typically done because we expect it to not be the null char.
+        // Ignore the case of errno==-1 because it means the end char wasn't the null char.
+        if (errno > 0) {
             return pos;
         }
         // debug( 0, L"Push idx %d", tmp );
@@ -674,8 +658,9 @@ static size_t parse_slice(const wchar_t *in, wchar_t **end_ptr, std::vector 0) {
                 return pos;
             }
             pos = end - in;
@@ -698,11 +683,8 @@ static size_t parse_slice(const wchar_t *in, wchar_t **end_ptr, std::vector *ou
             stop_pos++;
         }
 
-        // printf( "Stop for '%c'\n", in[stop_pos]);
+        // fwprintf(stdout, L"Stop for '%c'\n", in[stop_pos]);
         var_len = stop_pos - start_pos;
 
         if (var_len == 0) {
@@ -837,7 +819,7 @@ static int expand_variables(const wcstring &instr, std::vector *ou
                     }
 
                     // string_values is the new var_item_list.
-                    var_item_list.swap(string_values);
+                    var_item_list = std::move(string_values);
                 }
             }
 
diff --git a/src/fallback.cpp b/src/fallback.cpp
index 255d8d95f..5570f06f5 100644
--- a/src/fallback.cpp
+++ b/src/fallback.cpp
@@ -91,7 +91,20 @@ char *tparm_solaris_kludge(char *str, ...) {
 
 #endif
 
-#if __APPLE__
+int fish_mkstemp_cloexec(char *name_template) {
+#if HAVE_MKOSTEMP
+    // null check because mkostemp may be a weak symbol
+    if (&mkostemp != nullptr) {
+        return mkostemp(name_template, O_CLOEXEC);
+    }
+#endif
+    int result_fd = mkstemp(name_template);
+    if (result_fd != -1) {
+        fcntl(result_fd, F_SETFD, FD_CLOEXEC);
+    }
+    return result_fd;
+}
+
 /// Fallback implementations of wcsdup and wcscasecmp. On systems where these are not needed (e.g.
 /// building on Linux) these should end up just being stripped, as they are static functions that
 /// are not referenced in this file.
@@ -105,7 +118,6 @@ __attribute__((unused)) static wchar_t *wcsdup_fallback(const wchar_t *in) {
     memcpy(out, in, sizeof(wchar_t) * (len + 1));
     return out;
 }
-#endif
 
 __attribute__((unused)) static int wcscasecmp_fallback(const wchar_t *a, const wchar_t *b) {
     if (*a == 0) {
@@ -158,7 +170,21 @@ int wcsncasecmp(const wchar_t *a, const wchar_t *b, size_t n) {
     return wcsncasecmp_fallback(a, b, n);
 }
 #endif  // __DARWIN_C_LEVEL >= 200809L
-#endif  // __APPLE__
+#else   // __APPLE__
+
+/// These functions are missing from Solaris 10
+#ifndef HAVE_WCSDUP
+wchar_t *wcsdup(const wchar_t *in) { return wcsdup_fallback(in); }
+#endif
+#ifndef HAVE_WCSCASECMP
+int wcscasecmp(const wchar_t *a, const wchar_t *b) { return wcscasecmp_fallback(a, b); }
+#endif
+#ifndef HAVE_WCSNCASECMP
+int wcsncasecmp(const wchar_t *a, const wchar_t *b, size_t n) {
+    return wcsncasecmp_fallback(a, b, n);
+}
+#endif
+#endif
 
 #ifndef HAVE_WCSNDUP
 wchar_t *wcsndup(const wchar_t *in, size_t c) {
@@ -204,7 +230,8 @@ size_t wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz) {
     // Not enough room in dst, add NUL and traverse rest of src.
     if (n == 0) {
         if (siz != 0) *d = '\0';  // NUL-terminate dst
-        while (*s++) ;  // ignore rest of src
+        while (*s++)
+            ;  // ignore rest of src
     }
     return s - src - 1;  // count does not include NUL
 }
@@ -464,3 +491,72 @@ static int mk_wcswidth(const wchar_t *pwcs, size_t n) {
     return width;
 }
 #endif  // HAVE_BROKEN_WCWIDTH
+
+#ifndef HAVE_FLOCK
+/*	$NetBSD: flock.c,v 1.6 2008/04/28 20:24:12 martin Exp $	*/
+
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Todd Vierling.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Emulate flock() with fcntl().
+ */
+
+int flock(int fd, int op) {
+    int rc = 0;
+
+    struct flock fl = {0};
+
+    switch (op & (LOCK_EX | LOCK_SH | LOCK_UN)) {
+        case LOCK_EX:
+            fl.l_type = F_WRLCK;
+            break;
+
+        case LOCK_SH:
+            fl.l_type = F_RDLCK;
+            break;
+
+        case LOCK_UN:
+            fl.l_type = F_UNLCK;
+            break;
+
+        default:
+            errno = EINVAL;
+            return -1;
+    }
+
+    fl.l_whence = SEEK_SET;
+    rc = fcntl(fd, op & LOCK_NB ? F_SETLK : F_SETLKW, &fl);
+
+    if (rc && (errno == EAGAIN)) errno = EWOULDBLOCK;
+
+    return rc;
+}
+
+#endif  // HAVE_FLOCK
diff --git a/src/fallback.h b/src/fallback.h
index 49120c901..cb5775c35 100644
--- a/src/fallback.h
+++ b/src/fallback.h
@@ -23,6 +23,11 @@
 int fish_wcwidth(wchar_t wc);
 int fish_wcswidth(const wchar_t *str, size_t n);
 
+// Replacement for mkostemp(str, O_CLOEXEC)
+// This uses mkostemp if available,
+// otherwise it uses mkstemp followed by fcntl
+int fish_mkstemp_cloexec(char *);
+
 #ifndef WCHAR_MAX
 /// This _should_ be defined by wchar.h, but e.g. OpenBSD doesn't.
 #define WCHAR_MAX INT_MAX
@@ -63,6 +68,12 @@ char *tparm_solaris_kludge(char *str, ...);
 /// On other platforms, use what's detected at build time.
 #if __APPLE__
 #if __DARWIN_C_LEVEL >= 200809L
+// We have to explicitly redeclare these as weak,
+// since we are forced to set the MIN_REQUIRED availability macro to 10.7
+// to use libc++, which in turn exposes these as strong
+wchar_t *wcsdup(const wchar_t *) __attribute__((weak_import));
+int wcscasecmp(const wchar_t *, const wchar_t *) __attribute__((weak_import));
+int wcsncasecmp(const wchar_t *, const wchar_t *, size_t n) __attribute__((weak_import));
 wchar_t *wcsdup_use_weak(const wchar_t *);
 int wcscasecmp_use_weak(const wchar_t *, const wchar_t *);
 int wcsncasecmp_use_weak(const wchar_t *s1, const wchar_t *s2, size_t n);
@@ -75,7 +86,26 @@ int wcscasecmp(const wchar_t *a, const wchar_t *b);
 int wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n);
 wchar_t *wcsndup(const wchar_t *in, size_t c);
 #endif
-#endif  //__APPLE__
+#else  //__APPLE__
+
+/// These functions are missing from Solaris 10
+#ifndef HAVE_WCSDUP
+wchar_t *wcsdup(const wchar_t *in);
+#endif
+#ifndef HAVE_WCSCASECMP
+int wcscasecmp(const wchar_t *a, const wchar_t *b);
+#endif
+#ifndef HAVE_WCSNCASECMP
+int wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n);
+#endif
+#ifndef HAVE_DIRFD
+#ifndef __XOPEN_OR_POSIX
+#define dirfd(d) (d->dd_fd)
+#else
+#define dirfd(d) (d->d_fd)
+#endif
+#endif
+#endif
 
 #ifndef HAVE_WCSNDUP
 /// Fallback for wcsndup function. Returns a copy of \c in, truncated to a maximum length of \c c.
@@ -125,4 +155,20 @@ char *fish_textdomain(const char *domainname);
 int killpg(int pgr, int sig);
 #endif
 
+#ifndef HAVE_FLOCK
+/// Fallback implementation of flock in terms of fcntl
+/// Danger! The semantics of flock and fcntl locking are very different.
+/// Use with caution.
+// Ignore the cppcheck warning as this is the implementation that it is
+// warning about!
+// cppcheck-suppress flockSemanticsWarning
+int flock(int fd, int op);
+
+#define LOCK_SH 1  // Shared lock.
+#define LOCK_EX 2  // Exclusive lock.
+#define LOCK_UN 8  // Unlock.
+#define LOCK_NB 4  // Don't block when locking.
+
+#endif
+
 #endif
diff --git a/src/fish.cpp b/src/fish.cpp
index cc84686c0..8223a9e3e 100644
--- a/src/fish.cpp
+++ b/src/fish.cpp
@@ -17,20 +17,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 */
 #include "config.h"
 
-#include 
 #include 
 #include 
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
 #include 
-#include   // IWYU pragma: keep
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -47,13 +43,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 #include "function.h"
 #include "history.h"
 #include "input.h"
-#include "input_common.h"
 #include "io.h"
 #include "parser.h"
 #include "path.h"
 #include "proc.h"
 #include "reader.h"
-#include "wildcard.h"
 #include "wutil.h"  // IWYU pragma: keep
 
 // PATH_MAX may not exist.
@@ -202,82 +196,6 @@ static void source_config_in_directory(const wcstring &dir) {
     parser.set_is_within_fish_initialization(false);
 }
 
-static int try_connect_socket(std::string &name) {
-    int s, r, ret = -1;
-
-    /// Connect to a DGRAM socket rather than the expected STREAM. This avoids any notification to a
-    /// remote socket that we have connected, preventing any surprising behaviour. If the connection
-    /// fails with EPROTOTYPE, the connection is probably a STREAM; if it succeeds or fails any
-    /// other way, there is no cause for alarm. With thanks to Andrew Lutomirski 
-    if ((s = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) {
-        wperror(L"socket");
-        return -1;
-    }
-
-    debug(3, L"Connect to socket %s at fd %d", name.c_str(), s);
-
-    struct sockaddr_un local = {};
-    local.sun_family = AF_UNIX;
-    strncpy(local.sun_path, name.c_str(), (sizeof local.sun_path) - 1);
-
-    r = connect(s, (struct sockaddr *)&local, sizeof local);
-
-    if (r == -1 && errno == EPROTOTYPE) {
-        ret = 0;
-    }
-
-    close(s);
-    return ret;
-}
-
-/// Check for a running fishd from old versions and warn about not being able to share variables.
-/// https://github.com/fish-shell/fish-shell/issues/1730
-static void check_running_fishd() {
-    // There are two paths to check:
-    // $FISHD_SOCKET_DIR/fishd.socket.$USER or /tmp/fishd.socket.$USER
-    //   - referred to as the "old socket"
-    // $XDG_RUNTIME_DIR/fishd.socket or /tmp/fish.$USER/fishd.socket
-    //   - referred to as the "new socket"
-    // All existing versions of fish attempt to create the old socket, but
-    // failure in newer versions is not treated as critical, so both need
-    // to be checked.
-    const char *uname = getenv("USER");
-    if (uname == NULL) {
-        const struct passwd *pw = getpwuid(getuid());
-        uname = pw->pw_name;
-    }
-
-    const char *dir_old_socket = getenv("FISHD_SOCKET_DIR");
-    std::string path_old_socket;
-
-    if (dir_old_socket == NULL) {
-        path_old_socket = "/tmp/";
-    } else {
-        path_old_socket.append(dir_old_socket);
-    }
-
-    path_old_socket.append("fishd.socket.");
-    path_old_socket.append(uname);
-
-    const char *dir_new_socket = getenv("XDG_RUNTIME_DIR");
-    std::string path_new_socket;
-    if (dir_new_socket == NULL) {
-        path_new_socket = "/tmp/fish.";
-        path_new_socket.append(uname);
-        path_new_socket.push_back('/');
-    } else {
-        path_new_socket.append(dir_new_socket);
-    }
-
-    path_new_socket.append("fishd.socket");
-
-    if (try_connect_socket(path_old_socket) == 0 || try_connect_socket(path_new_socket) == 0) {
-        debug(1, _(L"Old versions of fish appear to be running. You will not be able to share "
-                   L"variable values between old and new fish sessions. For best results, restart "
-                   L"all running instances of fish."));
-    }
-}
-
 /// Parse init files. exec_path is the path of fish executable as determined by argv[0].
 static int read_init(const struct config_paths_t &paths) {
     source_config_in_directory(paths.data);
@@ -474,6 +392,11 @@ int main(int argc, char **argv) {
 
     const io_chain_t empty_ios;
     if (read_init(paths)) {
+        // TODO: Remove this once we're confident that not blocking/unblocking every signal around
+        // some critical sections is no longer necessary.
+        env_var_t fish_no_signal_block = env_get_string(L"FISH_NO_SIGNAL_BLOCK");
+        if (!fish_no_signal_block.missing()) ignore_signal_block = true;
+
         // Stomp the exit status of any initialization commands (issue #635).
         proc_set_last_status(STATUS_BUILTIN_OK);
 
@@ -490,7 +413,6 @@ int main(int argc, char **argv) {
             reader_exit(0, 0);
         } else if (my_optind == argc) {
             // Interactive mode
-            check_running_fishd();
             res = reader_read(STDIN_FILENO, empty_ios);
         } else {
             char *file = *(argv + (my_optind++));
diff --git a/src/fish_indent.cpp b/src/fish_indent.cpp
index 8605e4ead..80235a2df 100644
--- a/src/fish_indent.cpp
+++ b/src/fish_indent.cpp
@@ -491,7 +491,7 @@ int main(int argc, char *argv[]) {
         case output_type_file: {
             FILE *fh = fopen(output_location, "w");
             if (fh) {
-                fputs(wcs2str(output_wtext), fh);
+                fputws(output_wtext.c_str(), fh);
                 fclose(fh);
                 exit(0);
             } else {
@@ -511,6 +511,6 @@ int main(int argc, char *argv[]) {
         }
     }
 
-    fputs(colored_output.c_str(), stdout);
+    fputws(str2wcstring(colored_output).c_str(), stdout);
     return 0;
 }
diff --git a/src/fish_key_reader.cpp b/src/fish_key_reader.cpp
index 281396638..b850cbd28 100644
--- a/src/fish_key_reader.cpp
+++ b/src/fish_key_reader.cpp
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -33,10 +34,10 @@
 
 struct config_paths_t determine_config_directory_paths(const char *argv0);
 
-static const char *ctrl_symbolic_names[] = {NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL, "\\a",
-                                            "\\b", "\\t", "\\n", "\\v", "\\f", "\\r", NULL, NULL,
-                                            NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL, NULL,
-                                            NULL,  NULL,  NULL,  "\\e", NULL,  NULL,  NULL, NULL};
+static const wchar_t *ctrl_symbolic_names[] = {
+    NULL,   NULL,   NULL,   NULL, NULL, NULL,   NULL, L"\\a", L"\\b", L"\\t", L"\\n",
+    L"\\v", L"\\f", L"\\r", NULL, NULL, NULL,   NULL, NULL,   NULL,   NULL,   NULL,
+    NULL,   NULL,   NULL,   NULL, NULL, L"\\e", NULL, NULL,   NULL,   NULL};
 static bool keep_running = true;
 
 /// Return true if the recent sequence of characters indicates the user wants to exit the program.
@@ -48,9 +49,17 @@ static bool should_exit(wchar_t wc) {
     recent_chars[1] = recent_chars[2];
     recent_chars[2] = recent_chars[3];
     recent_chars[3] = c;
-    return (memcmp(recent_chars, "exit", 4) == 0 || memcmp(recent_chars, "quit", 4) == 0 ||
-            memcmp(recent_chars + 2, "\x3\x3", 2) == 0 ||  // ctrl-C, ctrl-C
-            memcmp(recent_chars + 2, "\x4\x4", 2) == 0);   // ctrl-D, ctrl-D
+    if (c == shell_modes.c_cc[VINTR]) {
+        if (recent_chars[2] == shell_modes.c_cc[VINTR]) return true;
+        fwprintf(stderr, L"Press [ctrl-%c] again to exit\n", shell_modes.c_cc[VINTR] + 0x40);
+        return false;
+    }
+    if (c == shell_modes.c_cc[VEOF]) {
+        if (recent_chars[2] == shell_modes.c_cc[VEOF]) return true;
+        fwprintf(stderr, L"Press [ctrl-%c] again to exit\n", shell_modes.c_cc[VEOF] + 0x40);
+        return false;
+    }
+    return memcmp(recent_chars, "exit", 4) == 0 || memcmp(recent_chars, "quit", 4) == 0;
 }
 
 /// Return the name if the recent sequence of characters matches a known terminfo sequence.
@@ -107,46 +116,48 @@ static bool must_escape(wchar_t wc) {
     }
 }
 
-static char *char_to_symbol(wchar_t wc, bool bind_friendly) {
-    static char buf[128];
+static wchar_t *char_to_symbol(wchar_t wc, bool bind_friendly) {
+#define BUF_LEN 64
+    static wchar_t buf[BUF_LEN];
 
-    if (wc < ' ') {
+    if (wc < L' ') {
         // ASCII control character.
         if (ctrl_symbolic_names[wc]) {
             if (bind_friendly) {
-                snprintf(buf, sizeof(buf), "%s", ctrl_symbolic_names[wc]);
+                swprintf(buf, BUF_LEN, L"%ls", ctrl_symbolic_names[wc]);
             } else {
-                snprintf(buf, sizeof(buf), "\\c%c  (or %s)", wc + 64, ctrl_symbolic_names[wc]);
+                swprintf(buf, BUF_LEN, L"\\c%c  (or %ls)", wc + 0x40, ctrl_symbolic_names[wc]);
             }
         } else {
-            snprintf(buf, sizeof(buf), "\\c%c", wc + 64);
+            swprintf(buf, BUF_LEN, L"\\c%c", wc + 0x40);
         }
-    } else if (wc == ' ') {
+    } else if (wc == L' ') {
         // The "space" character.
         if (bind_friendly) {
-            snprintf(buf, sizeof(buf), "\\x%X", wc);
+            swprintf(buf, BUF_LEN, L"\\x%X", ' ');
         } else {
-            snprintf(buf, sizeof(buf), "\\x%X  (aka \"space\")", wc);
+            swprintf(buf, BUF_LEN, L"\\x%X  (aka \"space\")", ' ');
         }
     } else if (wc == 0x7F) {
         // The "del" character.
         if (bind_friendly) {
-            snprintf(buf, sizeof(buf), "\\x%X", wc);
+            swprintf(buf, BUF_LEN, L"\\x%X", 0x7F);
         } else {
-            snprintf(buf, sizeof(buf), "\\x%X  (aka \"del\")", wc);
+            swprintf(buf, BUF_LEN, L"\\x%X  (aka \"del\")", 0x7F);
         }
     } else if (wc < 0x80) {
         // ASCII characters that are not control characters.
         if (bind_friendly && must_escape(wc)) {
-            snprintf(buf, sizeof(buf), "\\%c", wc);
+            swprintf(buf, BUF_LEN, L"\\%c", wc);
         } else {
-            snprintf(buf, sizeof(buf), "%c", wc);
+            swprintf(buf, BUF_LEN, L"%c", wc);
         }
     } else if (wc <= 0xFFFF) {
-        snprintf(buf, sizeof(buf), "\\u%04X", wc);
+        swprintf(buf, BUF_LEN, L"\\u%04X", (int)wc);
     } else {
-        snprintf(buf, sizeof(buf), "\\U%06X", wc);
+        swprintf(buf, BUF_LEN, L"\\U%06X", (int)wc);
     }
+
     return buf;
 }
 
@@ -156,23 +167,23 @@ static void add_char_to_bind_command(wchar_t wc, std::vector &bind_char
 
 static void output_bind_command(std::vector &bind_chars) {
     if (bind_chars.size()) {
-        fputs("bind ", stdout);
+        fputws(L"bind ", stdout);
         for (size_t i = 0; i < bind_chars.size(); i++) {
-            fputs(char_to_symbol(bind_chars[i], true), stdout);
+            fputws(char_to_symbol(bind_chars[i], true), stdout);
         }
-        fputs(" 'do something'\n", stdout);
+        fputws(L" 'do something'\n", stdout);
         bind_chars.clear();
     }
 }
 
 static void output_info_about_char(wchar_t wc) {
-    fprintf(stderr, "hex: %4X  char: %s\n", wc, char_to_symbol(wc, false));
+    fwprintf(stderr, L"hex: %4X  char: %ls\n", wc, char_to_symbol(wc, false));
 }
 
 static bool output_matching_key_name(wchar_t wc) {
     char *name = sequence_name(wc);
     if (name) {
-        printf("bind -k %s 'do something'\n", name);
+        fwprintf(stdout, L"bind -k %s 'do something'\n", name);
         free(name);
         return true;
     }
@@ -184,11 +195,11 @@ static double output_elapsed_time(double prev_tstamp, bool first_char_seen) {
     double now = timef();
     long long int delta_tstamp_us = 1000000 * (now - prev_tstamp);
 
-    if (delta_tstamp_us >= 200000 && first_char_seen) putc('\n', stderr);
+    if (delta_tstamp_us >= 200000 && first_char_seen) fputwc(L'\n', stderr);
     if (delta_tstamp_us >= 1000000) {
-        fprintf(stderr, "              ");
+        fwprintf(stderr, L"              ");
     } else {
-        fprintf(stderr, "(%3lld.%03lld ms)  ", delta_tstamp_us / 1000, delta_tstamp_us % 1000);
+        fwprintf(stderr, L"(%3lld.%03lld ms)  ", delta_tstamp_us / 1000, delta_tstamp_us % 1000);
     }
     return now;
 }
@@ -199,9 +210,14 @@ static void process_input(bool continuous_mode) {
     double prev_tstamp = 0.0;
     std::vector bind_chars;
 
-    fprintf(stderr, "Press a key\n\n");
+    fwprintf(stderr, L"Press a key\n\n");
     while (keep_running) {
-        wchar_t wc = input_common_readch(true);
+        wchar_t wc;
+        if (reader_interrupted()) {
+            wc = shell_modes.c_cc[VINTR];
+        } else {
+            wc = input_common_readch(true);
+        }
         if (wc == R_TIMEOUT || wc == R_EOF) {
             output_bind_command(bind_chars);
             if (first_char_seen && !continuous_mode) {
@@ -218,7 +234,7 @@ static void process_input(bool continuous_mode) {
         }
 
         if (should_exit(wc)) {
-            fprintf(stderr, "\nExiting at your request.\n");
+            fwprintf(stderr, L"\nExiting at your request.\n");
             break;
         }
 
@@ -230,12 +246,11 @@ static void process_input(bool continuous_mode) {
 /// Otherwise just report receipt of the signal.
 static struct sigaction old_sigactions[32];
 static void signal_handler(int signo, siginfo_t *siginfo, void *siginfo_arg) {
-    debug(2, L"signal #%d (%ls) received", signo, sig2wcs(signo));
-    // SIGINT isn't included in the following conditional because it is handled specially by fish.
-    // Specifically, it causes \cC to be reinserted into the tty input stream.
+    fwprintf(stdout, _(L"signal #%d (%ls) received\n"), signo, sig2wcs(signo));
     if (signo == SIGHUP || signo == SIGTERM || signo == SIGABRT || signo == SIGSEGV) {
         keep_running = false;
     }
+
     if (old_sigactions[signo].sa_handler != SIG_IGN &&
         old_sigactions[signo].sa_handler != SIG_DFL) {
         int needs_siginfo = old_sigactions[signo].sa_flags & SA_SIGINFO;
@@ -279,14 +294,14 @@ static void setup_and_process_keys(bool continuous_mode) {
     reader_init();
     input_init();
     proc_push_interactive(1);
-    signal_set_handlers();
     install_our_signal_handlers();
 
     if (continuous_mode) {
-        fprintf(stderr, "\n");
-        fprintf(stderr, "To terminate this program type \"exit\" or \"quit\" in this window,\n");
-        fprintf(stderr, "or press [ctrl-C] or [ctrl-D] twice in a row.\n");
-        fprintf(stderr, "\n");
+        fwprintf(stderr, L"\n");
+        fwprintf(stderr, L"To terminate this program type \"exit\" or \"quit\" in this window,\n");
+        fwprintf(stderr, L"or press [ctrl-%c] or [ctrl-%c] twice in a row.\n",
+                 shell_modes.c_cc[VINTR] + 0x40, shell_modes.c_cc[VEOF] + 0x40);
+        fwprintf(stderr, L"\n");
     }
 
     process_input(continuous_mode);
@@ -310,7 +325,7 @@ int main(int argc, char **argv) {
     while (!error && (opt = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
         switch (opt) {
             case 0: {
-                fprintf(stderr, "getopt_long() unexpectedly returned zero\n");
+                fwprintf(stderr, L"getopt_long() unexpectedly returned zero\n");
                 error = true;
                 break;
             }
@@ -365,12 +380,12 @@ int main(int argc, char **argv) {
 
     argc -= optind;
     if (argc != 0) {
-        fprintf(stderr, "Expected no arguments, got %d\n", argc);
+        fwprintf(stderr, L"Expected no arguments, got %d\n", argc);
         return 1;
     }
 
     if (!isatty(STDIN_FILENO)) {
-        fprintf(stderr, "Stdin must be attached to a tty.\n");
+        fwprintf(stderr, L"Stdin must be attached to a tty.\n");
         return 1;
     }
 
diff --git a/src/fish_tests.cpp b/src/fish_tests.cpp
index f08eeecbf..f06a2997a 100644
--- a/src/fish_tests.cpp
+++ b/src/fish_tests.cpp
@@ -4,12 +4,14 @@
 // IWYU pragma: no_include 
 // IWYU pragma: no_include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -23,11 +25,9 @@
 #include 
 #include 
 #include 
-#include 
-#include 
+#include 
 #include 
 #include 
-#include 
 #include 
 #include 
 
@@ -67,8 +67,6 @@
 static const char *const *s_arguments;
 static int s_test_run_count = 0;
 
-bool is_wchar_ucs2() { return sizeof(wchar_t) == 2; }
-
 // Indicate if we should test the given function. Either we test everything (all arguments) or we
 // run only tests that have a prefix in s_arguments.
 static bool should_test_function(const char *func_name) {
@@ -100,12 +98,12 @@ static bool should_test_function(const char *func_name) {
 static int err_count = 0;
 
 /// Print formatted output.
-static void say(const wchar_t *blah, ...) {
+static void say(const wchar_t *fmt, ...) {
     va_list va;
-    va_start(va, blah);
-    vwprintf(blah, va);
+    va_start(va, fmt);
+    vfwprintf(stdout, fmt, va);
     va_end(va);
-    wprintf(L"\n");
+    fwprintf(stdout, L"\n");
 }
 
 /// Print formatted error string.
@@ -119,18 +117,18 @@ static void err(const wchar_t *blah, ...) {
 
     // Show errors in red.
     if (colorize) {
-        fputs("\x1b[31m", stdout);
+        fputws(L"\e[31m", stdout);
     }
-    wprintf(L"Error: ");
-    vwprintf(blah, va);
+    fwprintf(stdout, L"Error: ");
+    vfwprintf(stdout, blah, va);
     va_end(va);
 
     // Return to normal color.
     if (colorize) {
-        fputs("\x1b[0m", stdout);
+        fputws(L"\e[0m", stdout);
     }
 
-    wprintf(L"\n");
+    fwprintf(stdout, L"\n");
 }
 
 /// Joins a wcstring_list_t via commas.
@@ -157,21 +155,100 @@ static int chdir_set_pwd(const char *path) {
 // The odd formulation of these macros is to avoid "multiple unary operator" warnings from oclint
 // were we to use the more natural "if (!(e)) err(..." form. We have to do this because the rules
 // for the C preprocessor make it practically impossible to embed a comment in the body of a macro.
-#define do_test(e)                                                   \
-    do {                                                             \
-        if (e) { ; } else { err(L"Test failed on line %lu: %s", __LINE__, #e); } \
+#define do_test(e)                                             \
+    do {                                                       \
+        if (e) {                                               \
+            ;                                                  \
+        } else {                                               \
+            err(L"Test failed on line %lu: %s", __LINE__, #e); \
+        }                                                      \
     } while (0)
 
-#define do_test_from(e, from)                                                         \
-    do {                                                                                   \
-        if (e) { ; } else { err(L"Test failed on line %lu (from %lu): %s", __LINE__, from, #e); } \
+#define do_test_from(e, from)                                                   \
+    do {                                                                        \
+        if (e) {                                                                \
+            ;                                                                   \
+        } else {                                                                \
+            err(L"Test failed on line %lu (from %lu): %s", __LINE__, from, #e); \
+        }                                                                       \
     } while (0)
 
-#define do_test1(e, msg)                                                 \
-    do {                                                                 \
-        if (e) { ; } else { err(L"Test failed on line %lu: %ls", __LINE__, (msg)); } \
+#define do_test1(e, msg)                                           \
+    do {                                                           \
+        if (e) {                                                   \
+            ;                                                      \
+        } else {                                                   \
+            err(L"Test failed on line %lu: %ls", __LINE__, (msg)); \
+        }                                                          \
     } while (0)
 
+/// Test that the fish functions for converting strings to numbers work.
+static void test_str_to_num() {
+    const wchar_t *end;
+    int i;
+    long l;
+
+    i = fish_wcstoi(L"");
+    do_test1(errno == EINVAL && i == 0, L"converting empty string to int did not fail");
+    i = fish_wcstoi(L" \n ");
+    do_test1(errno == EINVAL && i == 0, L"converting whitespace string to int did not fail");
+    i = fish_wcstoi(L"123");
+    do_test1(errno == 0 && i == 123, L"converting valid num to int did not succeed");
+    i = fish_wcstoi(L"-123");
+    do_test1(errno == 0 && i == -123, L"converting valid num to int did not succeed");
+    i = fish_wcstoi(L" 345  ");
+    do_test1(errno == 0 && i == 345, L"converting valid num to int did not succeed");
+    i = fish_wcstoi(L" -345  ");
+    do_test1(errno == 0 && i == -345, L"converting valid num to int did not succeed");
+    i = fish_wcstoi(L"x345");
+    do_test1(errno == EINVAL && i == 0, L"converting invalid num to int did not fail");
+    i = fish_wcstoi(L" x345");
+    do_test1(errno == EINVAL && i == 0, L"converting invalid num to int did not fail");
+    i = fish_wcstoi(L"456 x");
+    do_test1(errno == -1 && i == 456, L"converting invalid num to int did not fail");
+    i = fish_wcstoi(L"99999999999999999999999");
+    do_test1(errno == ERANGE && i == INT_MAX, L"converting invalid num to int did not fail");
+    i = fish_wcstoi(L"-99999999999999999999999");
+    do_test1(errno == ERANGE && i == INT_MIN, L"converting invalid num to int did not fail");
+    i = fish_wcstoi(L"567]", &end);
+    do_test1(errno == -1 && i == 567 && *end == L']',
+             L"converting valid num to int did not succeed");
+    // This is subtle. "567" in base 8 is "375" in base 10. The final "8" is not converted.
+    i = fish_wcstoi(L"5678", &end, 8);
+    do_test1(errno == -1 && i == 375 && *end == L'8',
+             L"converting invalid num to int did not fail");
+
+    l = fish_wcstol(L"");
+    do_test1(errno == EINVAL && l == 0, L"converting empty string to long did not fail");
+    l = fish_wcstol(L" \t ");
+    do_test1(errno == EINVAL && l == 0, L"converting whitespace string to long did not fail");
+    l = fish_wcstol(L"123");
+    do_test1(errno == 0 && l == 123, L"converting valid num to long did not succeed");
+    l = fish_wcstol(L"-123");
+    do_test1(errno == 0 && l == -123, L"converting valid num to long did not succeed");
+    l = fish_wcstol(L" 345  ");
+    do_test1(errno == 0 && l == 345, L"converting valid num to long did not succeed");
+    l = fish_wcstol(L" -345  ");
+    do_test1(errno == 0 && l == -345, L"converting valid num to long did not succeed");
+    l = fish_wcstol(L"x345");
+    do_test1(errno == EINVAL && l == 0, L"converting invalid num to long did not fail");
+    l = fish_wcstol(L" x345");
+    do_test1(errno == EINVAL && l == 0, L"converting invalid num to long did not fail");
+    l = fish_wcstol(L"456 x");
+    do_test1(errno == -1 && l == 456, L"converting invalid num to long did not fail");
+    l = fish_wcstol(L"99999999999999999999999");
+    do_test1(errno == ERANGE && l == LONG_MAX, L"converting invalid num to long did not fail");
+    l = fish_wcstol(L"-99999999999999999999999");
+    do_test1(errno == ERANGE && l == LONG_MIN, L"converting invalid num to long did not fail");
+    l = fish_wcstol(L"567]", &end);
+    do_test1(errno == -1 && l == 567 && *end == L']',
+             L"converting valid num to long did not succeed");
+    // This is subtle. "567" in base 8 is "375" in base 10. The final "8" is not converted.
+    l = fish_wcstol(L"5678", &end, 8);
+    do_test1(errno == -1 && l == 375 && *end == L'8',
+             L"converting invalid num to long did not fail");
+}
+
 /// Test sane escapes.
 static void test_unescape_sane() {
     const struct test_t {
@@ -201,13 +278,12 @@ static void test_unescape_sane() {
     if (unescape_string(L"echo \\U110000", &output, UNESCAPE_DEFAULT)) {
         err(L"Should not have been able to unescape \\U110000\n");
     }
-    if (is_wchar_ucs2()) {
-        ; // TODO: Make this work on MS Windows.
-    } else {
-        if (!unescape_string(L"echo \\U10FFFF", &output, UNESCAPE_DEFAULT)) {
-            err(L"Should have been able to unescape \\U10FFFF\n");
-        }
+#if WCHAR_MAX != 0xffff
+    // TODO: Make this work on MS Windows.
+    if (!unescape_string(L"echo \\U10FFFF", &output, UNESCAPE_DEFAULT)) {
+        err(L"Should have been able to unescape \\U10FFFF\n");
     }
+#endif
 }
 
 /// Test the escaping/unescaping code by escaping/unescaping random strings and verifying that the
@@ -376,8 +452,8 @@ static void test_tokenizer() {
             }
             if (types[i] != token.type) {
                 err(L"Tokenization error:");
-                wprintf(L"Token number %zu of string \n'%ls'\n, got token type %ld\n", i + 1, str,
-                        (long)token.type);
+                fwprintf(stdout, L"Token number %zu of string \n'%ls'\n, got token type %ld\n",
+                         i + 1, str, (long)token.type);
             }
             i++;
         }
@@ -436,16 +512,10 @@ static void test_tokenizer() {
         err(L"redirection_type_for_string failed on line %ld", (long)__LINE__);
 }
 
-// Little function that runs in the main thread.
-static int test_iothread_main_call(int *addr) {
-    *addr += 1;
-    return *addr;
-}
-
 // Little function that runs in a background thread, bouncing to the main.
-static int test_iothread_thread_call(int *addr) {
+static int test_iothread_thread_call(std::atomic *addr) {
     int before = *addr;
-    iothread_perform_on_main(test_iothread_main_call, addr);
+    iothread_perform_on_main([=]() { *addr += 1; });
     int after = *addr;
 
     // Must have incremented it at least once.
@@ -457,12 +527,12 @@ static int test_iothread_thread_call(int *addr) {
 
 static void test_iothread(void) {
     say(L"Testing iothreads");
-    int *int_ptr = new int(0);
+    std::unique_ptr> int_ptr = make_unique>(0);
     int iterations = 50000;
     int max_achieved_thread_count = 0;
     double start = timef();
     for (int i = 0; i < iterations; i++) {
-        int thread_count = iothread_perform(test_iothread_thread_call, int_ptr);
+        int thread_count = iothread_perform([&]() { test_iothread_thread_call(int_ptr.get()); });
         max_achieved_thread_count = std::max(max_achieved_thread_count, thread_count);
     }
 
@@ -472,13 +542,11 @@ static void test_iothread(void) {
 
     // Should have incremented it once per thread.
     if (*int_ptr != iterations) {
-        say(L"Expected int to be %d, but instead it was %d", iterations, *int_ptr);
+        say(L"Expected int to be %d, but instead it was %d", iterations, int_ptr->load());
     }
 
     say(L"    (%.02f msec, with max of %d threads)", (end - start) * 1000.0,
         max_achieved_thread_count);
-
-    delete int_ptr;
 }
 
 static parser_test_error_bits_t detect_argument_errors(const wcstring &src) {
@@ -646,23 +714,16 @@ static void test_parser() {
     do_test(comps.at(2).completion == L"delta");
 }
 
-/// Wait a while and then SIGINT the main thread.
-struct test_cancellation_info_t {
-    pthread_t thread;
-    double delay;
-};
-
-static int signal_main(test_cancellation_info_t *info) {
-    usleep(info->delay * 1E6);
-    pthread_kill(info->thread, SIGINT);
-    return 0;
-}
-
 static void test_1_cancellation(const wchar_t *src) {
     shared_ptr out_buff(io_buffer_t::create(STDOUT_FILENO, io_chain_t()));
     const io_chain_t io_chain(out_buff);
-    test_cancellation_info_t ctx = {pthread_self(), 0.25 /* seconds */};
-    iothread_perform(signal_main, &ctx);
+    pthread_t thread = pthread_self();
+    double delay = 0.25 /* seconds */;
+    iothread_perform([=]() {
+        /// Wait a while and then SIGINT the main thread.
+        usleep(delay * 1E6);
+        pthread_kill(thread, SIGINT);
+    });
     parser_t::principal_parser().eval(src, io_chain, TOP);
     out_buff->read();
     if (out_buff->out_buffer_size() != 0) {
@@ -691,19 +752,20 @@ static void test_cancellation() {
     // we cancel we expect no output.
     test_1_cancellation(L"echo (while true ; echo blah ; end)");
 
-    fprintf(stderr, ".");
-
     // Nasty infinite loop that doesn't actually execute anything.
     test_1_cancellation(L"echo (while true ; end) (while true ; end) (while true ; end)");
-    fprintf(stderr, ".");
-
     test_1_cancellation(L"while true ; end");
-    fprintf(stderr, ".");
-
+    test_1_cancellation(L"while true ; echo nothing > /dev/null; end");
     test_1_cancellation(L"for i in (while true ; end) ; end");
-    fprintf(stderr, ".");
 
-    fprintf(stderr, "\n");
+    // Ensure that if child processes SIGINT, we exit our loops
+    // Test for #3780
+    // Ugly hack - temporarily set is_interactive_session
+    // else we will SIGINT ourselves in response to our child death
+    scoped_push iis(&is_interactive_session, 1);
+    const wchar_t *child_self_destructor = L"while true ; sh -c 'sleep .25; kill -s INT $$' ; end";
+    parser_t::principal_parser().eval(child_self_destructor, io_chain_t(), TOP);
+    iis.restore();
 
     // Restore signal handling.
     proc_pop_interactive();
@@ -836,9 +898,10 @@ static void test_utf82wchar(const char *src, size_t slen, const wchar_t *dst, si
     size_t size;
     wchar_t *mem = NULL;
 
+#if WCHAR_MAX == 0xffff
     // Hack: if wchar is only UCS-2, and the UTF-8 input string contains astral characters, then
     // tweak the expected size to 0.
-    if (src != NULL && is_wchar_ucs2()) {
+    if (src) {
         // A UTF-8 code unit may represent an astral code point if it has 4 or more leading 1s.
         const unsigned char astral_mask = 0xF0;
         for (size_t i = 0; i < slen; i++) {
@@ -849,6 +912,7 @@ static void test_utf82wchar(const char *src, size_t slen, const wchar_t *dst, si
             }
         }
     }
+#endif
 
     if (!dst) {
         size = utf8_to_wchar(src, slen, NULL, flags);
@@ -885,9 +949,10 @@ static void test_wchar2utf8(const wchar_t *src, size_t slen, const char *dst, si
     size_t size;
     char *mem = NULL;
 
+#if WCHAR_MAX == 0xffff
     // Hack: if wchar is simulating UCS-2, and the wchar_t input string contains astral characters,
     // then tweak the expected size to 0.
-    if (src != NULL && is_wchar_ucs2()) {
+    if (src) {
         const uint32_t astral_mask = 0xFFFF0000U;
         for (size_t i = 0; i < slen; i++) {
             if ((src[i] & astral_mask) != 0) {
@@ -897,6 +962,7 @@ static void test_wchar2utf8(const wchar_t *src, size_t slen, const char *dst, si
             }
         }
     }
+#endif
 
     if (dst) {
         mem = (char *)malloc(dlen);
@@ -928,10 +994,7 @@ static void test_utf8() {
     wchar_t w1[] = {0x54, 0x65, 0x73, 0x74};
     wchar_t w2[] = {0x0422, 0x0435, 0x0441, 0x0442};
     wchar_t w3[] = {0x800, 0x1e80, 0x98c4, 0x9910, 0xff00};
-    wchar_t w4[] = {0x15555, 0xf7777, 0x0a};
-    wchar_t wb[] = {(wchar_t)-2, 0xa, (wchar_t)0xffffffff, 0x0441};
     wchar_t wm[] = {0x41, 0x0441, 0x3042, 0xff67, 0x9b0d};
-    wchar_t wb1[] = {0x0a, 0x0422};
     wchar_t wb2[] = {0xd800, 0xda00, 0x41, 0xdfff, 0x0a};
     wchar_t wbom[] = {0xfeff, 0x41, 0x0a};
     wchar_t wbom2[] = {0x41, 0xa};
@@ -940,14 +1003,19 @@ static void test_utf8() {
     unsigned char u2[] = {0xd0, 0xa2, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82};
     unsigned char u3[] = {0xe0, 0xa0, 0x80, 0xe1, 0xba, 0x80, 0xe9, 0xa3,
                           0x84, 0xe9, 0xa4, 0x90, 0xef, 0xbc, 0x80};
-    unsigned char u4[] = {0xf0, 0x95, 0x95, 0x95, 0xf3, 0xb7, 0x9d, 0xb7, 0x0a};
-    unsigned char ub[] = {0xa, 0xd1, 0x81};
     unsigned char um[] = {0x41, 0xd1, 0x81, 0xe3, 0x81, 0x82, 0xef, 0xbd, 0xa7, 0xe9, 0xac, 0x8d};
-    unsigned char ub1[] = {0xa, 0xff, 0xd0, 0xa2, 0xfe, 0x8f, 0xe0, 0x80};
     unsigned char uc080[] = {0xc0, 0x80};
     unsigned char ub2[] = {0xed, 0xa1, 0x8c, 0xed, 0xbe, 0xb4, 0x0a};
     unsigned char ubom[] = {0x41, 0xa};
     unsigned char ubom2[] = {0xef, 0xbb, 0xbf, 0x41, 0x0a};
+#if WCHAR_MAX != 0xffff
+    wchar_t w4[] = {0x15555, 0xf7777, 0x0a};
+    wchar_t wb[] = {(wchar_t)-2, 0xa, (wchar_t)0xffffffff, 0x0441};
+    wchar_t wb1[] = {0x0a, 0x0422};
+    unsigned char u4[] = {0xf0, 0x95, 0x95, 0x95, 0xf3, 0xb7, 0x9d, 0xb7, 0x0a};
+    unsigned char ub[] = {0xa, 0xd1, 0x81};
+    unsigned char ub1[] = {0xa, 0xff, 0xd0, 0xa2, 0xfe, 0x8f, 0xe0, 0x80};
+#endif
 
     // UTF-8 -> UCS-4 string.
     test_utf82wchar(ubom2, sizeof(ubom2), wbom2, sizeof(wbom2) / sizeof(*wbom2), UTF8_SKIP_BOM,
@@ -991,18 +1059,6 @@ static void test_utf8() {
     test_wchar2utf8(w1, sizeof(w1) / sizeof(*w1), u1, 0, 0, 0, "invalid params, dst is not NULL");
     test_wchar2utf8(NULL, 10, nullc, 0, 0, 0, "invalid params, src length is not 0");
 
-    // The following tests won't pass on systems (e.g., Cygwin) where sizeof wchar_t is 2. That's
-    // due to several reasons but the primary one is that narrowing conversions of literals assigned
-    // to the wchar_t arrays above don't result in values that will be treated as errors by the
-    // conversion functions.
-    if (is_wchar_ucs2()) return;
-    test_utf82wchar(u4, sizeof(u4), w4, sizeof(w4) / sizeof(*w4), 0, sizeof(w4) / sizeof(*w4),
-                    "u4/w4 4 octets chars");
-    test_wchar2utf8(w4, sizeof(w4) / sizeof(*w4), u4, sizeof(u4), 0, sizeof(u4),
-                    "w4/u4 4 octets chars");
-    test_wchar2utf8(wb, sizeof(wb) / sizeof(*wb), ub, sizeof(ub), 0, 0, "wb/ub bad chars");
-    test_wchar2utf8(wb, sizeof(wb) / sizeof(*wb), ub, sizeof(ub), UTF8_IGNORE_ERROR, sizeof(ub),
-                    "wb/ub ignore bad chars");
     test_wchar2utf8(wm, sizeof(wm) / sizeof(*wm), um, sizeof(um), 0, sizeof(um),
                     "wm/um mixed languages");
     test_wchar2utf8(wm, sizeof(wm) / sizeof(*wm), um, sizeof(um) - 1, 0, 0, "wm/um boundaries -1");
@@ -1010,20 +1066,34 @@ static void test_utf8() {
                     "wm/um boundaries +1");
     test_wchar2utf8(wm, sizeof(wm) / sizeof(*wm), nullc, 0, 0, sizeof(um),
                     "wm/um calculate length");
+    test_utf82wchar(um, sizeof(um), wm, sizeof(wm) / sizeof(*wm), 0, sizeof(wm) / sizeof(*wm),
+                    "um/wm mixed languages");
+    test_utf82wchar(um, sizeof(um), wm, sizeof(wm) / sizeof(*wm) + 1, 0, sizeof(wm) / sizeof(*wm),
+                    "um/wm boundaries +1");
+    test_utf82wchar(um, sizeof(um), NULL, 0, 0, sizeof(wm) / sizeof(*wm), "um/wm calculate length");
+
+// The following tests won't pass on systems (e.g., Cygwin) where sizeof wchar_t is 2. That's
+// due to several reasons but the primary one is that narrowing conversions of literals assigned
+// to the wchar_t arrays above don't result in values that will be treated as errors by the
+// conversion functions.
+#if WCHAR_MAX != 0xffff
+    test_utf82wchar(u4, sizeof(u4), w4, sizeof(w4) / sizeof(*w4), 0, sizeof(w4) / sizeof(*w4),
+                    "u4/w4 4 octets chars");
+    test_wchar2utf8(w4, sizeof(w4) / sizeof(*w4), u4, sizeof(u4), 0, sizeof(u4),
+                    "w4/u4 4 octets chars");
+    test_wchar2utf8(wb, sizeof(wb) / sizeof(*wb), ub, sizeof(ub), 0, 0, "wb/ub bad chars");
+    test_wchar2utf8(wb, sizeof(wb) / sizeof(*wb), ub, sizeof(ub), UTF8_IGNORE_ERROR, sizeof(ub),
+                    "wb/ub ignore bad chars");
     test_wchar2utf8(wb, sizeof(wb) / sizeof(*wb), nullc, 0, 0, 0,
                     "wb calculate length of bad chars");
     test_wchar2utf8(wb, sizeof(wb) / sizeof(*wb), nullc, 0, UTF8_IGNORE_ERROR, sizeof(ub),
                     "calculate length, ignore bad chars");
     test_utf82wchar(ub1, sizeof(ub1), wb1, sizeof(wb1) / sizeof(*wb1), UTF8_IGNORE_ERROR,
                     sizeof(wb1) / sizeof(*wb1), "ub1/wb1 ignore bad chars");
-    test_utf82wchar(um, sizeof(um), wm, sizeof(wm) / sizeof(*wm), 0, sizeof(wm) / sizeof(*wm),
-                    "um/wm mixed languages");
-    test_utf82wchar(um, sizeof(um), wm, sizeof(wm) / sizeof(*wm) + 1, 0, sizeof(wm) / sizeof(*wm),
-                    "um/wm boundaries +1");
-    test_utf82wchar(um, sizeof(um), NULL, 0, 0, sizeof(wm) / sizeof(*wm), "um/wm calculate length");
     test_utf82wchar(ub1, sizeof(ub1), NULL, 0, 0, 0, "ub1 calculate length of bad chars");
     test_utf82wchar(ub1, sizeof(ub1), NULL, 0, UTF8_IGNORE_ERROR, sizeof(wb1) / sizeof(*wb1),
                     "ub1 calculate length, ignore bad chars");
+#endif
 }
 
 static void test_escape_sequences(void) {
@@ -1031,43 +1101,53 @@ static void test_escape_sequences(void) {
     if (escape_code_length(L"") != 0) err(L"test_escape_sequences failed on line %d\n", __LINE__);
     if (escape_code_length(L"abcd") != 0)
         err(L"test_escape_sequences failed on line %d\n", __LINE__);
-    if (escape_code_length(L"\x1b[2J") != 4)
+    if (escape_code_length(L"\e[2J") != 4)
         err(L"test_escape_sequences failed on line %d\n", __LINE__);
-    if (escape_code_length(L"\x1b[38;5;123mABC") != strlen("\x1b[38;5;123m"))
+    if (escape_code_length(L"\e[38;5;123mABC") != strlen("\e[38;5;123m"))
         err(L"test_escape_sequences failed on line %d\n", __LINE__);
-    if (escape_code_length(L"\x1b@") != 2)
+    if (escape_code_length(L"\e@") != 2)
         err(L"test_escape_sequences failed on line %d\n", __LINE__);
 
     // iTerm2 escape sequences.
-    if (escape_code_length(L"\x1b]50;CurrentDir=/tmp/foo\x07NOT_PART_OF_SEQUENCE") != 25)
+    if (escape_code_length(L"\e]50;CurrentDir=/tmp/foo\x07NOT_PART_OF_SEQUENCE") != 25)
         err(L"test_escape_sequences failed on line %d\n", __LINE__);
-    if (escape_code_length(L"\x1b]50;SetMark\x07NOT_PART_OF_SEQUENCE") != 13)
+    if (escape_code_length(L"\e]50;SetMark\x07NOT_PART_OF_SEQUENCE") != 13)
         err(L"test_escape_sequences failed on line %d\n", __LINE__);
-    if (escape_code_length(L"\x1b"
-                           L"]6;1;bg;red;brightness;255\x07NOT_PART_OF_SEQUENCE") != 28)
+    if (escape_code_length(L"\e]6;1;bg;red;brightness;255\x07NOT_PART_OF_SEQUENCE") != 28)
         err(L"test_escape_sequences failed on line %d\n", __LINE__);
-    if (escape_code_length(L"\x1b]Pg4040ff\x1b\\NOT_PART_OF_SEQUENCE") != 12)
+    if (escape_code_length(L"\e]Pg4040ff\e\\NOT_PART_OF_SEQUENCE") != 12)
         err(L"test_escape_sequences failed on line %d\n", __LINE__);
-    if (escape_code_length(L"\x1b]blahblahblah\x1b\\") != 16)
+    if (escape_code_length(L"\e]blahblahblah\e\\") != 16)
         err(L"test_escape_sequences failed on line %d\n", __LINE__);
-    if (escape_code_length(L"\x1b]blahblahblah\x07") != 15)
+    if (escape_code_length(L"\e]blahblahblah\x07") != 15)
         err(L"test_escape_sequences failed on line %d\n", __LINE__);
 }
 
-class lru_node_test_t : public lru_node_t {
+class test_lru_t : public lru_cache_t {
    public:
-    explicit lru_node_test_t(const wcstring &tmp) : lru_node_t(tmp) {}
-};
+    static constexpr size_t test_capacity = 16;
+    typedef std::pair value_type;
 
-class test_lru_t : public lru_cache_t {
-   public:
-    test_lru_t() : lru_cache_t(16) {}
+    test_lru_t() : lru_cache_t(test_capacity) {}
 
-    std::vector evicted_nodes;
+    std::vector evicted;
 
-    virtual void node_was_evicted(lru_node_test_t *node) {
-        do_test(find(evicted_nodes.begin(), evicted_nodes.end(), node) == evicted_nodes.end());
-        evicted_nodes.push_back(node);
+    void entry_was_evicted(wcstring key, int val) { evicted.push_back({key, val}); }
+
+    std::vector values() const {
+        std::vector result;
+        for (const auto &p : *this) {
+            result.push_back(p);
+        }
+        return result;
+    }
+
+    std::vector ints() const {
+        std::vector result;
+        for (const auto &p : *this) {
+            result.push_back(p.second);
+        }
+        return result;
     }
 };
 
@@ -1075,24 +1155,53 @@ static void test_lru(void) {
     say(L"Testing LRU cache");
 
     test_lru_t cache;
-    std::vector expected_evicted;
-    size_t total_nodes = 20;
-    for (size_t i = 0; i < total_nodes; i++) {
-        do_test(cache.size() == std::min(i, (size_t)16));
-        lru_node_test_t *node = new lru_node_test_t(to_string(i));
-        if (i < 4) expected_evicted.push_back(node);
+    std::vector> expected_evicted;
+    std::vector> expected_values;
+    int total_nodes = 20;
+    for (int i = 0; i < total_nodes; i++) {
+        do_test(cache.size() == size_t(std::min(i, 16)));
+        do_test(cache.values() == expected_values);
+        if (i < 4) expected_evicted.push_back({to_string(i), i});
         // Adding the node the first time should work, and subsequent times should fail.
-        do_test(cache.add_node(node));
-        do_test(!cache.add_node(node));
+        do_test(cache.insert(to_string(i), i));
+        do_test(!cache.insert(to_string(i), i + 1));
+
+        expected_values.push_back({to_string(i), i});
+        while (expected_values.size() > test_lru_t::test_capacity) {
+            expected_values.erase(expected_values.begin());
+        }
+        cache.check_sanity();
     }
-    do_test(cache.evicted_nodes == expected_evicted);
+    do_test(cache.evicted == expected_evicted);
+    do_test(cache.values() == expected_values);
+    cache.check_sanity();
+
+    // Stable-sort ints in reverse order
+    // This a/2 check ensures that some different ints compare the same
+    // It also gives us a different order than we started with
+    auto comparer = [](int a, int b){
+        return a/2 > b/2;
+    };
+    std::vector ints = cache.ints();
+    std::stable_sort(ints.begin(), ints.end(), comparer);
+
+    cache.stable_sort(comparer);
+    std::vector new_ints = cache.ints();
+    if (new_ints != ints) {
+        auto commajoin = [](const std::vector &vs) {
+            wcstring ret;
+            for (int v : vs) {
+                append_format(ret, L"%d,", v);
+            }
+            if (! ret.empty()) ret.pop_back();
+            return ret;
+        };
+        err(L"LRU stable sort failed. Expected %ls, got %ls\n", commajoin(new_ints).c_str(), commajoin(ints).c_str());
+    }
+
+
     cache.evict_all_nodes();
-    do_test(cache.evicted_nodes.size() == total_nodes);
-    while (!cache.evicted_nodes.empty()) {
-        lru_node_t *node = cache.evicted_nodes.back();
-        cache.evicted_nodes.pop_back();
-        delete node;
-    }
+    do_test(cache.evicted.size() == size_t(total_nodes));
 }
 
 /// Perform parameter expansion and test if the output equals the zero-terminated parameter list
@@ -1541,6 +1650,88 @@ static void test_pager_navigation() {
     }
 }
 
+struct pager_layout_testcase_t {
+    size_t width;
+    const wchar_t *expected;
+
+    // Run ourselves as a test case
+    // Set our data on the pager, and then check the rendering
+    // We should have one line, and it should have our expected text
+    void run(pager_t &pager) const {
+        pager.set_term_size(this->width, 24);
+        page_rendering_t rendering = pager.render();
+        const screen_data_t &sd = rendering.screen_data;
+        do_test(sd.line_count() == 1);
+        if (sd.line_count() > 0) {
+            wcstring expected = this->expected;
+
+            // hack: handle the case where ellipsis is not L'\x2026'
+            if (ellipsis_char != L'\x2026') {
+                std::replace(expected.begin(), expected.end(), L'\x2026', ellipsis_char);
+            }
+
+            wcstring text = sd.line(0).to_string();
+            if (text != expected) {
+                fwprintf(stderr, L"width %zu got <%ls>, expected <%ls>\n", this->width,
+                         text.c_str(), expected.c_str());
+            }
+            do_test(text == expected);
+        }
+    }
+};
+
+static void test_pager_layout() {
+    // These tests are woefully incomplete
+    // They only test the truncation logic for a single completion
+    say(L"Testing pager layout");
+    pager_t pager;
+
+    // These test cases have equal completions and descriptions
+    const completion_t c1(L"abcdefghij", L"1234567890");
+    pager.set_completions(completion_list_t(1, c1));
+    const pager_layout_testcase_t testcases1[] = {
+        {26, L"abcdefghij  (1234567890)"}, {25, L"abcdefghij  (1234567890)"},
+        {24, L"abcdefghij  (1234567890)"}, {23, L"abcdefghij  (12345678…)"},
+        {22, L"abcdefghij  (1234567…)"},   {21, L"abcdefghij  (123456…)"},
+        {20, L"abcdefghij  (12345…)"},     {19, L"abcdefghij  (1234…)"},
+        {18, L"abcdefgh…  (1234…)"},       {17, L"abcdefg…  (1234…)"},
+        {16, L"abcdefg…  (123…)"},         {0, NULL}  // sentinel terminator
+    };
+    for (size_t i = 0; testcases1[i].expected != NULL; i++) {
+        testcases1[i].run(pager);
+    }
+
+    // These test cases have heavyweight completions
+    const completion_t c2(L"abcdefghijklmnopqrs", L"1");
+    pager.set_completions(completion_list_t(1, c2));
+    const pager_layout_testcase_t testcases2[] = {
+        {26, L"abcdefghijklmnopqrs  (1)"}, {25, L"abcdefghijklmnopqrs  (1)"},
+        {24, L"abcdefghijklmnopqrs  (1)"}, {23, L"abcdefghijklmnopq…  (1)"},
+        {22, L"abcdefghijklmnop…  (1)"},   {21, L"abcdefghijklmno…  (1)"},
+        {20, L"abcdefghijklmn…  (1)"},     {19, L"abcdefghijklm…  (1)"},
+        {18, L"abcdefghijkl…  (1)"},       {17, L"abcdefghijk…  (1)"},
+        {16, L"abcdefghij…  (1)"},         {0, NULL}  // sentinel terminator
+    };
+    for (size_t i = 0; testcases2[i].expected != NULL; i++) {
+        testcases2[i].run(pager);
+    }
+
+    // These test cases have no descriptions
+    const completion_t c3(L"abcdefghijklmnopqrst", L"");
+    pager.set_completions(completion_list_t(1, c3));
+    const pager_layout_testcase_t testcases3[] = {
+        {26, L"abcdefghijklmnopqrst"}, {25, L"abcdefghijklmnopqrst"},
+        {24, L"abcdefghijklmnopqrst"}, {23, L"abcdefghijklmnopqrst"},
+        {22, L"abcdefghijklmnopqrst"}, {21, L"abcdefghijklmnopqrst"},
+        {20, L"abcdefghijklmnopqrst"}, {19, L"abcdefghijklmnopqr…"},
+        {18, L"abcdefghijklmnopq…"},   {17, L"abcdefghijklmnop…"},
+        {16, L"abcdefghijklmno…"},     {0, NULL}  // sentinel terminator
+    };
+    for (size_t i = 0; testcases3[i].expected != NULL; i++) {
+        testcases3[i].run(pager);
+    }
+}
+
 enum word_motion_t { word_motion_left, word_motion_right };
 static void test_1_word_motion(word_motion_t motion, move_word_style_t style,
                                const wcstring &test) {
@@ -1571,7 +1762,8 @@ static void test_1_word_motion(word_motion_t motion, move_word_style_t style,
         size_t char_idx = (motion == word_motion_left ? idx - 1 : idx);
         wchar_t wc = command.at(char_idx);
         bool will_stop = !sm.consume_char(wc);
-        // printf("idx %lu, looking at %lu (%c): %d\n", idx, char_idx, (char)wc, will_stop);
+        // fwprintf(stdout, L"idx %lu, looking at %lu (%c): %d\n", idx, char_idx, (char)wc,
+        //          will_stop);
         bool expected_stop = (stops.count(idx) > 0);
         if (will_stop != expected_stop) {
             wcstring tmp = command;
@@ -1678,15 +1870,18 @@ static bool run_one_test_test(int expected, wcstring_list_t &lst, bool bracket)
 
 static bool run_test_test(int expected, const wcstring &str) {
     using namespace std;
-    wcstring_list_t lst;
+    wcstring_list_t argv;
+    completion_list_t comps;
 
-    wistringstream iss(str);
-    copy(istream_iterator >(iss),
-         istream_iterator >(),
-         back_inserter >(lst));
+    // We need to tokenize the string in the same manner a normal shell would do. This is because we
+    // need to test things like quoted strings that have leading and trailing whitespace.
+    parser_t::expand_argument_list(str, 0, &comps);
+    for (completion_list_t::const_iterator it = comps.begin(), end = comps.end(); it != end; ++it) {
+        argv.push_back(it->completion);
+    }
 
-    bool bracket = run_one_test_test(expected, lst, true);
-    bool nonbracket = run_one_test_test(expected, lst, false);
+    bool bracket = run_one_test_test(expected, argv, true);
+    bool nonbracket = run_one_test_test(expected, argv, false);
     do_test(bracket == nonbracket);
     return nonbracket;
 }
@@ -1715,6 +1910,17 @@ static void test_test() {
     do_test(run_test_test(0, L"0 -eq 0"));
     do_test(run_test_test(0, L"-1 -eq -1"));
     do_test(run_test_test(0, L"1 -ne -1"));
+    do_test(run_test_test(1, L"' 2 ' -ne 2"));
+    do_test(run_test_test(0, L"' 2' -eq 2"));
+    do_test(run_test_test(0, L"'2 ' -eq 2"));
+    do_test(run_test_test(0, L"' 2 ' -eq 2"));
+    do_test(run_test_test(1, L"' 2x' -eq 2"));
+    do_test(run_test_test(1, L"'' -eq 0"));
+    do_test(run_test_test(1, L"'' -ne 0"));
+    do_test(run_test_test(1, L"'  ' -eq 0"));
+    do_test(run_test_test(1, L"'  ' -ne 0"));
+    do_test(run_test_test(1, L"'x' -eq 0"));
+    do_test(run_test_test(1, L"'x' -ne 0"));
     do_test(run_test_test(1, L"-1 -ne -1"));
     do_test(run_test_test(0, L"abc != def"));
     do_test(run_test_test(1, L"abc = def"));
@@ -1997,8 +2203,8 @@ static void test_1_completion(wcstring line, const wcstring &completion, complet
     wcstring result =
         completion_apply_to_command_line(completion, flags, line, &cursor_pos, append_only);
     if (result != expected) {
-        fprintf(stderr, "line %ld: %ls + %ls -> [%ls], expected [%ls]\n", source_line, line.c_str(),
-                completion.c_str(), result.c_str(), expected.c_str());
+        fwprintf(stderr, L"line %ld: %ls + %ls -> [%ls], expected [%ls]\n", source_line,
+                 line.c_str(), completion.c_str(), result.c_str(), expected.c_str());
     }
     do_test(result == expected);
     do_test(cursor_pos == out_cursor_pos);
@@ -2042,15 +2248,15 @@ static void perform_one_autosuggestion_cd_test(const wcstring &command,
     bool expects_error = (expected == L"");
 
     if (comps.empty() && !expects_error) {
-        printf("line %ld: autosuggest_suggest_special() failed for command %ls\n", line,
-               command.c_str());
+        fwprintf(stderr, L"line %ld: autosuggest_suggest_special() failed for command %ls\n", line,
+                 command.c_str());
         do_test(!comps.empty());
         return;
     } else if (!comps.empty() && expects_error) {
-        printf(
-            "line %ld: autosuggest_suggest_special() was expected to fail but did not, for command "
-            "%ls\n",
-            line, command.c_str());
+        fwprintf(stderr,
+                 L"line %ld: autosuggest_suggest_special() was expected to fail but did not, "
+                 L"for command %ls\n",
+                 line, command.c_str());
         do_test(comps.empty());
     }
 
@@ -2059,11 +2265,12 @@ static void perform_one_autosuggestion_cd_test(const wcstring &command,
         const completion_t &suggestion = comps.at(0);
 
         if (suggestion.completion != expected) {
-            printf(
-                "line %ld: complete() for cd returned the wrong expected string for command %ls\n",
+            fwprintf(
+                stderr,
+                L"line %ld: complete() for cd returned the wrong expected string for command %ls\n",
                 line, command.c_str());
-            printf("  actual: %ls\n", suggestion.completion.c_str());
-            printf("expected: %ls\n", expected.c_str());
+            fwprintf(stderr, L"  actual: %ls\n", suggestion.completion.c_str());
+            fwprintf(stderr, L"expected: %ls\n", expected.c_str());
             do_test(suggestion.completion == expected);
         }
     }
@@ -2178,8 +2385,9 @@ static void perform_one_autosuggestion_should_ignore_test(const wcstring &comman
     do_test(comps.empty());
     if (!comps.empty()) {
         const wcstring &suggestion = comps.front().completion;
-        printf("line %ld: complete() expected to return nothing for %ls\n", line, command.c_str());
-        printf("  instead got: %ls\n", suggestion.c_str());
+        fwprintf(stderr, L"line %ld: complete() expected to return nothing for %ls\n", line,
+                 command.c_str());
+        fwprintf(stderr, L"  instead got: %ls\n", suggestion.c_str());
     }
 }
 
@@ -2237,6 +2445,10 @@ static bool history_contains(history_t *history, const wcstring &txt) {
     return result;
 }
 
+static bool history_contains(const std::unique_ptr &history, const wcstring &txt) {
+    return history_contains(history.get(), txt);
+}
+
 static void test_input() {
     say(L"Testing input");
     // Ensure sequences are order independent. Here we add two bindings where the first is a prefix
@@ -2262,26 +2474,24 @@ static void test_input() {
 #define UVARS_PER_THREAD 8
 #define UVARS_TEST_PATH L"/tmp/fish_uvars_test/varsfile.txt"
 
-static int test_universal_helper(int *x) {
+static int test_universal_helper(int x) {
     env_universal_t uvars(UVARS_TEST_PATH);
     for (int j = 0; j < UVARS_PER_THREAD; j++) {
-        const wcstring key = format_string(L"key_%d_%d", *x, j);
-        const wcstring val = format_string(L"val_%d_%d", *x, j);
+        const wcstring key = format_string(L"key_%d_%d", x, j);
+        const wcstring val = format_string(L"val_%d_%d", x, j);
         uvars.set(key, val, false);
         bool synced = uvars.sync(NULL);
         if (!synced) {
             err(L"Failed to sync universal variables after modification");
         }
-        fputc('.', stderr);
     }
 
     // Last step is to delete the first key.
-    uvars.remove(format_string(L"key_%d_%d", *x, 0));
+    uvars.remove(format_string(L"key_%d_%d", x, 0));
     bool synced = uvars.sync(NULL);
     if (!synced) {
         err(L"Failed to sync universal variables after deletion");
     }
-    fputc('.', stderr);
     return 0;
 }
 
@@ -2290,10 +2500,8 @@ static void test_universal() {
     if (system("mkdir -p /tmp/fish_uvars_test/")) err(L"mkdir failed");
 
     const int threads = 16;
-    static int ctx[threads];
     for (int i = 0; i < threads; i++) {
-        ctx[i] = i;
-        iothread_perform(test_universal_helper, &ctx[i]);
+        iothread_perform([=]() { test_universal_helper(i); });
     }
     iothread_drain_all();
 
@@ -2325,7 +2533,6 @@ static void test_universal() {
     }
 
     if (system("rm -Rf /tmp/fish_uvars_test")) err(L"rm failed");
-    putc('\n', stderr);
 }
 
 static bool callback_data_less_than(const callback_data_t &a, const callback_data_t &b) {
@@ -2383,7 +2590,7 @@ static void test_universal_callbacks() {
     if (system("rm -Rf /tmp/fish_uvars_test")) err(L"rm failed");
 }
 
-bool poll_notifier(universal_notifier_t *note) {
+bool poll_notifier(const std::unique_ptr ¬e) {
     bool result = false;
     if (note->usec_delay_between_polls() > 0) {
         result = note->poll();
@@ -2402,33 +2609,26 @@ bool poll_notifier(universal_notifier_t *note) {
     return result;
 }
 
-static void trigger_or_wait_for_notification(universal_notifier_t *notifier,
-                                             universal_notifier_t::notifier_strategy_t strategy) {
+static void trigger_or_wait_for_notification(universal_notifier_t::notifier_strategy_t strategy) {
     switch (strategy) {
-        case universal_notifier_t::strategy_default: {
-            DIE("strategy_default should be passed");
-            break;
-        }
         case universal_notifier_t::strategy_shmem_polling: {
             break;  // nothing required
         }
         case universal_notifier_t::strategy_notifyd: {
             // notifyd requires a round trip to the notifyd server, which means we have to wait a
-            // little bit to receive it. In practice, this seems to be enough.
-            usleep(1000000 / 25);
+            // little bit to receive it. In practice 40 ms seems to be enough.
+            usleep(40000);
             break;
         }
-        case universal_notifier_t::strategy_named_pipe:
-        case universal_notifier_t::strategy_null: {
-            break;
+        case universal_notifier_t::strategy_named_pipe: {
+            break;  // nothing required
         }
     }
 }
 
 static void test_notifiers_with_strategy(universal_notifier_t::notifier_strategy_t strategy) {
-    assert(strategy != universal_notifier_t::strategy_default);
     say(L"Testing universal notifiers with strategy %d", (int)strategy);
-    universal_notifier_t *notifiers[16];
+    std::unique_ptr notifiers[16];
     size_t notifier_count = sizeof notifiers / sizeof *notifiers;
 
     // Populate array of notifiers.
@@ -2449,7 +2649,7 @@ static void test_notifiers_with_strategy(universal_notifier_t::notifier_strategy
         notifiers[post_idx]->post_notification();
 
         // Do special stuff to "trigger" a notification for testing.
-        trigger_or_wait_for_notification(notifiers[post_idx], strategy);
+        trigger_or_wait_for_notification(strategy);
 
         for (size_t i = 0; i < notifier_count; i++) {
             // We aren't concerned with the one who posted. Poll from it (to drain it), and then
@@ -2462,7 +2662,7 @@ static void test_notifiers_with_strategy(universal_notifier_t::notifier_strategy
             if (!poll_notifier(notifiers[i])) {
                 err(L"Universal variable notifier (%lu) %p polled failed to notice changes, with "
                     L"strategy %d",
-                    i, notifiers[i], (int)strategy);
+                    i, notifiers[i].get(), (int)strategy);
             }
         }
 
@@ -2485,21 +2685,15 @@ static void test_notifiers_with_strategy(universal_notifier_t::notifier_strategy
                 (int)strategy);
         }
     }
-
-    // Clean up.
-    for (size_t i = 0; i < notifier_count; i++) {
-        delete notifiers[i];
-    }
 }
 
 static void test_universal_notifiers() {
-    if (system("mkdir -p /tmp/fish_uvars_test/ && touch /tmp/fish_uvars_test/varsfile.txt"))
+    if (system("mkdir -p /tmp/fish_uvars_test/ && touch /tmp/fish_uvars_test/varsfile.txt")) {
         err(L"mkdir failed");
-    test_notifiers_with_strategy(universal_notifier_t::strategy_shmem_polling);
-    test_notifiers_with_strategy(universal_notifier_t::strategy_named_pipe);
-#if __APPLE__
-    test_notifiers_with_strategy(universal_notifier_t::strategy_notifyd);
-#endif
+    }
+
+    auto strategy = universal_notifier_t::resolve_default_strategy();
+    test_notifiers_with_strategy(strategy);
 
     if (system("rm -Rf /tmp/fish_uvars_test/")) err(L"rm failed");
 }
@@ -2648,7 +2842,7 @@ static wcstring_list_t generate_history_lines(int pid) {
 
 void history_tests_t::test_history_races_pound_on_history() {
     // Called in child process to modify history.
-    history_t *hist = new history_t(L"race_test");
+    std::unique_ptr hist = make_unique(L"race_test");
     hist->chaos_mode = true;
     const wcstring_list_t hist_lines = generate_history_lines(getpid());
     for (size_t idx = 0; idx < hist_lines.size(); idx++) {
@@ -2656,16 +2850,16 @@ void history_tests_t::test_history_races_pound_on_history() {
         hist->add(line);
         hist->save();
     }
-    delete hist;
 }
 
 void history_tests_t::test_history_races(void) {
     say(L"Testing history race conditions");
 
     // Ensure history is clear.
-    history_t *hist = new history_t(L"race_test");
-    hist->clear();
-    delete hist;
+    {
+        std::unique_ptr hist = make_unique(L"race_test");
+        hist->clear();
+    }
 
 // Test concurrent history writing.
 #define RACE_COUNT 10
@@ -2706,7 +2900,7 @@ void history_tests_t::test_history_races(void) {
     time_barrier();
 
     // Ensure that we got sane, sorted results.
-    hist = new history_t(L"race_test");
+    std::unique_ptr hist = make_unique(L"race_test");
     hist->chaos_mode = true;
     size_t hist_idx;
     for (hist_idx = 1;; hist_idx++) {
@@ -2735,7 +2929,6 @@ void history_tests_t::test_history_races(void) {
     do_test(hist_idx >= RACE_COUNT);
 
     // hist->clear();
-    delete hist;
 }
 
 void history_tests_t::test_history_merge(void) {
@@ -2746,7 +2939,8 @@ void history_tests_t::test_history_merge(void) {
     say(L"Testing history merge");
     const size_t count = 3;
     const wcstring name = L"merge_test";
-    history_t *hists[count] = {new history_t(name), new history_t(name), new history_t(name)};
+    std::unique_ptr hists[count] = {
+        make_unique(name), make_unique(name), make_unique(name)};
     const wcstring texts[count] = {L"History 1", L"History 2", L"History 3"};
     const wcstring alt_texts[count] = {L"History Alt 1", L"History Alt 2", L"History Alt 3"};
 
@@ -2780,7 +2974,7 @@ void history_tests_t::test_history_merge(void) {
     // Make a new history. It should contain everything. The time_barrier() is so that the timestamp
     // is newer, since we only pick up items whose timestamp is before the birth stamp.
     time_barrier();
-    history_t *everything = new history_t(name);
+    std::unique_ptr everything = make_unique(name);
     for (size_t i = 0; i < count; i++) {
         do_test(history_contains(everything, texts[i]));
     }
@@ -2816,12 +3010,22 @@ void history_tests_t::test_history_merge(void) {
         }
     }
 
-    // Clean up.
-    for (size_t i = 0; i < 3; i++) {
-        delete hists[i];
+    // Make sure incorporate_external_changes doesn't drop items! (#3496)
+    history_t *const writer = hists[0].get();
+    history_t *const reader = hists[1].get();
+    const wcstring more_texts[] = {L"Item_#3496_1", L"Item_#3496_2", L"Item_#3496_3",
+                                   L"Item_#3496_4", L"Item_#3496_5", L"Item_#3496_6"};
+    for (size_t i = 0; i < sizeof more_texts / sizeof *more_texts; i++) {
+        // time_barrier because merging will ignore items that may be newer
+        if (i > 0) time_barrier();
+        writer->add(more_texts[i]);
+        writer->incorporate_external_changes();
+        reader->incorporate_external_changes();
+        for (size_t j = 0; j < i; j++) {
+            do_test(history_contains(reader, more_texts[j]));
+        }
     }
     everything->clear();
-    delete everything;  // not as scary as it looks
 }
 
 static bool install_sample_history(const wchar_t *name) {
@@ -2943,7 +3147,7 @@ void history_tests_t::test_history_formats(void) {
 void history_tests_t::test_history_speed(void)
 {
     say(L"Testing history speed (pid is %d)", getpid());
-    history_t *hist = new history_t(L"speed_test");
+    std::unique_ptr hist = make_unique(L"speed_test");
     wcstring item = L"History Speed Test - X";
 
     // Test for 10 seconds.
@@ -2961,9 +3165,8 @@ void history_tests_t::test_history_speed(void)
         if (stop >= end)
             break;
     }
-    printf("%lu items - %.2f msec per item\n", (unsigned long)count, (stop - start) * 1E6 / count);
+    fwprintf(stdout, L"%lu items - %.2f msec per item\n", (unsigned long)count, (stop - start) * 1E6 / count);
     hist->clear();
-    delete hist;
 }
 #endif
 
@@ -3041,7 +3244,7 @@ static void test_new_parser_fuzzing(void) {
     bool log_it = true;
     unsigned long max_len = 5;
     for (unsigned long len = 0; len < max_len; len++) {
-        if (log_it) fprintf(stderr, "%lu / %lu...", len, max_len);
+        if (log_it) fwprintf(stderr, L"%lu / %lu...", len, max_len);
 
         // We wish to look at all permutations of 4 elements of 'fuzzes' (with replacement).
         // Construct an int and keep incrementing it.
@@ -3050,7 +3253,7 @@ static void test_new_parser_fuzzing(void) {
                                       &src)) {
             parse_tree_from_string(src, parse_flag_continue_after_error, &node_tree, &errors);
         }
-        if (log_it) fprintf(stderr, "done (%lu)\n", permutation);
+        if (log_it) fwprintf(stderr, L"done (%lu)\n", permutation);
     }
     double end = timef();
     if (log_it) say(L"All fuzzed in %f seconds!", end - start);
@@ -3086,8 +3289,7 @@ static bool test_1_parse_ll2(const wcstring &src, wcstring *out_cmd, wcstring *o
     tree.command_for_plain_statement(stmt, src, out_cmd);
 
     // Return arguments separated by spaces.
-    const parse_node_tree_t::parse_node_list_t arg_nodes =
-        tree.find_nodes(stmt, symbol_argument);
+    const parse_node_tree_t::parse_node_list_t arg_nodes = tree.find_nodes(stmt, symbol_argument);
     for (size_t i = 0; i < arg_nodes.size(); i++) {
         if (i > 0) out_joined_args->push_back(L' ');
         out_joined_args->append(arg_nodes.at(i)->get_source(src));
@@ -3856,7 +4058,7 @@ long return_timezone_hour(time_t tstamp, const wchar_t *timezone) {
     struct tm ltime;
     char ltime_str[3];
     char *str_ptr;
-    int n;
+    size_t n;
 
     env_set(L"TZ", timezone, ENV_EXPORT);
     localtime_r(&tstamp, <ime);
@@ -3887,6 +4089,38 @@ static void test_env_vars(void) {
     // TODO: Add tests for the locale and ncurses vars.
 }
 
+static void test_illegal_command_exit_code(void) {
+    say(L"Testing illegal command exit code");
+
+    struct command_result_tuple_t {
+        const wchar_t *txt;
+        int result;
+    };
+
+    const command_result_tuple_t tests[] = {
+        {L"echo -n", STATUS_BUILTIN_OK}, {L"pwd", STATUS_BUILTIN_OK},
+        {L")", STATUS_ILLEGAL_CMD},      {L") ", STATUS_ILLEGAL_CMD},
+        {L"*", STATUS_ILLEGAL_CMD},      {L"**", STATUS_ILLEGAL_CMD},
+        {L"%", STATUS_ILLEGAL_CMD},      {L"%test", STATUS_ILLEGAL_CMD},
+        {L"?", STATUS_ILLEGAL_CMD},      {L"abc?def", STATUS_ILLEGAL_CMD},
+        {L") ", STATUS_ILLEGAL_CMD}};
+
+    int res = 0;
+    const io_chain_t empty_ios;
+    parser_t &parser = parser_t::principal_parser();
+
+    size_t i = 0;
+    for (i = 0; i < sizeof tests / sizeof *tests; i++) {
+        res = parser.eval(tests[i].txt, empty_ios, TOP);
+
+        int exit_status = res ? STATUS_UNKNOWN_COMMAND : proc_get_last_status();
+        if (exit_status != tests[i].result) {
+            err(L"command '%ls': expected exit code %d , got %d", tests[i].txt, tests[i].result,
+                exit_status);
+        }
+    }
+}
+
 /// Main test.
 int main(int argc, char **argv) {
     UNUSED(argc);
@@ -3899,8 +4133,8 @@ int main(int argc, char **argv) {
             exit(-1);
         }
         if (!strcmp(wd, "/")) {
-            fprintf(stderr,
-                    "Unable to find 'tests' directory, which should contain file test.fish\n");
+            fwprintf(stderr,
+                     L"Unable to find 'tests' directory, which should contain file test.fish\n");
             exit(EXIT_FAILURE);
         }
         if (chdir(dirname(wd)) < 0) {
@@ -3908,10 +4142,12 @@ int main(int argc, char **argv) {
         }
     }
 
-    srand(time(0));
+    srand((unsigned int)time(NULL));
     configure_thread_assertions_for_testing();
 
-    program_name = L"(ignore)";
+    // Set the program name to this sentinel value
+    // This will prevent some misleading stderr output during the tests
+    program_name = TESTS_PROGRAM_NAME;
     s_arguments = argv + 1;
 
     struct utsname uname_info;
@@ -3931,6 +4167,7 @@ int main(int argc, char **argv) {
     // Set default signal handlers, so we can ctrl-C out of this.
     signal_reset_handlers();
 
+    if (should_test_function("str_to_num")) test_str_to_num();
     if (should_test_function("highlighting")) test_highlighting();
     if (should_test_function("new_parser_ll2")) test_new_parser_ll2();
     if (should_test_function("new_parser_fuzzing"))
@@ -3959,6 +4196,7 @@ int main(int argc, char **argv) {
     if (should_test_function("test")) test_test();
     if (should_test_function("path")) test_path();
     if (should_test_function("pager_navigation")) test_pager_navigation();
+    if (should_test_function("pager_layout")) test_pager_layout();
     if (should_test_function("word_motion")) test_word_motion();
     if (should_test_function("is_potential_path")) test_is_potential_path();
     if (should_test_function("colors")) test_colors();
@@ -3978,6 +4216,7 @@ int main(int argc, char **argv) {
     if (should_test_function("history_formats")) history_tests_t::test_history_formats();
     if (should_test_function("string")) test_string();
     if (should_test_function("env_vars")) test_env_vars();
+    if (should_test_function("illegal_command_exit_code")) test_illegal_command_exit_code();
     // history_tests_t::test_history_speed();
 
     say(L"Encountered %d errors in low-level tests", err_count);
diff --git a/src/function.cpp b/src/function.cpp
index 3f303a468..da5fc30b5 100644
--- a/src/function.cpp
+++ b/src/function.cpp
@@ -37,25 +37,16 @@ static std::set function_tombstones;
 /// Lock for functions.
 static pthread_mutex_t functions_lock;
 
-/// Autoloader for functions.
-class function_autoload_t : public autoload_t {
-   public:
-    function_autoload_t();
-    virtual void command_removed(const wcstring &cmd);
-};
-
-static function_autoload_t function_autoloader;
-
-/// Constructor
-function_autoload_t::function_autoload_t() : autoload_t(L"fish_function_path", NULL, 0) {}
-
 static bool function_remove_ignore_autoload(const wcstring &name, bool tombstone = true);
 
 /// Callback when an autoloaded function is removed.
-void function_autoload_t::command_removed(const wcstring &cmd) {
+void autoloaded_function_removed(const wcstring &cmd) {
     function_remove_ignore_autoload(cmd, false);
 }
 
+// Function autoloader
+static autoload_t function_autoloader(L"fish_function_path", autoloaded_function_removed);
+
 /// Kludgy flag set by the load function in order to tell function_add that the function being
 /// defined is autoloaded. There should be a better way to do this...
 static bool is_autoload = false;
@@ -259,7 +250,7 @@ std::map function_get_inherit_vars(const wcstring &name) {
     return func ? func->inherit_vars : std::map();
 }
 
-int function_get_shadow_scope(const wcstring &name) {
+bool function_get_shadow_scope(const wcstring &name) {
     scoped_lock locker(functions_lock);
     const function_info_t *func = function_get(name);
     return func ? func->shadow_scope : false;
@@ -325,6 +316,12 @@ const wchar_t *function_get_definition_file(const wcstring &name) {
     return func ? func->definition_file : NULL;
 }
 
+bool function_is_autoloaded(const wcstring &name) {
+    scoped_lock locker(functions_lock);
+    const function_info_t *func = function_get(name);
+    return func->is_autoload;
+}
+
 int function_get_definition_offset(const wcstring &name) {
     scoped_lock locker(functions_lock);
     const function_info_t *func = function_get(name);
diff --git a/src/function.h b/src/function.h
index c104f080d..95957a90b 100644
--- a/src/function.h
+++ b/src/function.h
@@ -99,6 +99,9 @@ int function_exists_no_autoload(const wcstring &name, const env_vars_snapshot_t
 /// \param get_hidden whether to include hidden functions, i.e. ones starting with an underscore.
 wcstring_list_t function_get_names(int get_hidden);
 
+/// Returns true if the function was autoloaded.
+bool function_is_autoloaded(const wcstring &name);
+
 /// Returns tha absolute path of the file where the specified function was defined. Returns 0 if the
 /// file was defined on the commandline.
 ///
@@ -126,7 +129,7 @@ std::map function_get_inherit_vars(const wcstring &name);
 bool function_copy(const wcstring &name, const wcstring &new_name);
 
 /// Returns whether this function shadows variables of the underlying function.
-int function_get_shadow_scope(const wcstring &name);
+bool function_get_shadow_scope(const wcstring &name);
 
 /// Prepares the environment for executing a function.
 void function_prepare_environment(const wcstring &name, const wchar_t *const *argv,
diff --git a/src/highlight.cpp b/src/highlight.cpp
index 85844dc1c..ac5909613 100644
--- a/src/highlight.cpp
+++ b/src/highlight.cpp
@@ -4,11 +4,9 @@
 // IWYU pragma: no_include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -239,7 +237,7 @@ bool plain_statement_get_expanded_command(const wcstring &src, const parse_node_
     if (tree.command_for_plain_statement(plain_statement, src, &cmd) &&
         expand_one(cmd, EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_VARIABLES | EXPAND_SKIP_JOBS)) {
         // Success, return the expanded string by reference.
-        out_cmd->swap(cmd);
+        *out_cmd = std::move(cmd);
         return true;
     }
     return false;
@@ -277,6 +275,9 @@ rgb_color_t highlight_get_color(highlight_spec_t highlight, bool is_background)
         else {
             if (result2.is_bold()) result.set_bold(true);
             if (result2.is_underline()) result.set_underline(true);
+            if (result2.is_italics()) result.set_italics(true);
+            if (result2.is_dim()) result.set_dim(true);
+            if (result2.is_reverse()) result.set_reverse(true);
         }
     }
 
@@ -326,7 +327,6 @@ static bool autosuggest_parse_command(const wcstring &buff, wcstring *out_expand
 }
 
 bool autosuggest_validate_from_history(const history_item_t &item,
-                                       file_detection_context_t &detector,
                                        const wcstring &working_directory,
                                        const env_vars_snapshot_t &vars) {
     ASSERT_IS_BACKGROUND_THREAD();
@@ -371,11 +371,7 @@ bool autosuggest_validate_from_history(const history_item_t &item,
 
     if (cmd_ok) {
         const path_list_t &paths = item.get_required_paths();
-        if (paths.empty()) {
-            suggestionOK = true;
-        } else {
-            suggestionOK = detector.paths_are_valid(paths);
-        }
+        suggestionOK = all_paths_are_valid(paths, working_directory);
     }
 
     return suggestionOK;
@@ -874,19 +870,8 @@ void highlighter_t::color_redirection(const parse_node_t &redirection_node) {
                     path_apply_working_directory(target, this->working_directory);
                 switch (redirect_type) {
                     case TOK_REDIRECT_FD: {
-                        // Target should be an fd. It must be all digits, and must not overflow.
-                        // fish_wcstoi returns INT_MAX on overflow; we could instead check errno to
-                        // disambiguiate this from a real INT_MAX fd, but instead we just disallow
-                        // that.
-                        const wchar_t *target_cstr = target.c_str();
-                        wchar_t *end = NULL;
-                        int fd = fish_wcstoi(target_cstr, &end, 10);
-
-                        // The iswdigit check ensures there's no leading whitespace, the *end check
-                        // ensures the entire string was consumed, and the numeric checks ensure the
-                        // fd is at least zero and there was no overflow.
-                        target_is_valid =
-                            (iswdigit(target_cstr[0]) && *end == L'\0' && fd >= 0 && fd < INT_MAX);
+                        int fd = fish_wcstoi(target.c_str());
+                        target_is_valid = !errno && fd >= 0;
                         break;
                     }
                     case TOK_REDIRECT_IN: {
@@ -1041,7 +1026,7 @@ const highlighter_t::color_array_t &highlighter_t::highlight() {
 #if 0
     // Disabled for the 2.2.0 release: https://github.com/fish-shell/fish-shell/issues/1809.
     const wcstring dump = parse_dump_tree(parse_tree, buff);
-    fprintf(stderr, "%ls\n", dump.c_str());
+    fwprintf(stderr, L"%ls\n", dump.c_str());
 #endif
 
     // Walk the node tree.
diff --git a/src/highlight.h b/src/highlight.h
index e708733de..a63cb28dd 100644
--- a/src/highlight.h
+++ b/src/highlight.h
@@ -108,7 +108,6 @@ rgb_color_t highlight_get_color(highlight_spec_t highlight, bool is_background);
 /// specially recognizing the command. Returns true if we validated the command. If so, returns by
 /// reference whether the suggestion is valid or not.
 bool autosuggest_validate_from_history(const history_item_t &item,
-                                       file_detection_context_t &detector,
                                        const wcstring &working_directory,
                                        const env_vars_snapshot_t &vars);
 
diff --git a/src/history.cpp b/src/history.cpp
index 0f07f566f..a967653b9 100644
--- a/src/history.cpp
+++ b/src/history.cpp
@@ -1,5 +1,4 @@
 // History functions, part of the user interface.
-//
 #include "config.h"  // IWYU pragma: keep
 
 #include 
@@ -10,6 +9,8 @@
 #include 
 #include 
 #include 
+// We need the sys/file.h for the flock() declaration on Linux but not OS X.
+#include   // IWYU pragma: keep
 #include 
 #include 
 #include 
@@ -17,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -121,35 +123,41 @@ class time_profiler_t {
     }
 };
 
-/// Lock a file via fcntl; returns true on success, false on failure.
-static bool history_file_lock(int fd, short type) {
-    assert(type == F_RDLCK || type == F_WRLCK);
-    struct flock flk = {};
-    flk.l_type = type;
-    flk.l_whence = SEEK_SET;
-    int ret = fcntl(fd, F_SETLKW, (void *)&flk);
-    return ret != -1;
+/// Lock the history file.
+/// Returns true on success, false on failure.
+static bool history_file_lock(int fd, int lock_type) {
+    static bool do_locking = true;
+    if (!do_locking) return false;
+
+    double start_time = timef();
+    int retval = flock(fd, lock_type);
+    double duration = timef() - start_time;
+    if (duration > 0.25) {
+        debug(1, _(L"Locking the history file took too long (%.3f seconds)."), duration);
+        do_locking = false;
+        return false;
+    }
+    return retval != -1;
 }
 
 /// Our LRU cache is used for restricting the amount of history we have, and limiting how long we
 /// order it.
-class history_lru_node_t : public lru_node_t {
+class history_lru_item_t {
    public:
+    wcstring text;
     time_t timestamp;
     path_list_t required_paths;
-    explicit history_lru_node_t(const history_item_t &item)
-        : lru_node_t(item.str()),
+    explicit history_lru_item_t(const history_item_t &item)
+        : text(item.str()),
           timestamp(item.timestamp()),
           required_paths(item.get_required_paths()) {}
 };
 
-class history_lru_cache_t : public lru_cache_t {
-   protected:
-    /// Override to delete evicted nodes.
-    virtual void node_was_evicted(history_lru_node_t *node) { delete node; }
+class history_lru_cache_t : public lru_cache_t {
+    typedef lru_cache_t super;
 
    public:
-    explicit history_lru_cache_t(size_t max) : lru_cache_t(max) {}
+    using super::super;
 
     /// Function to add a history item.
     void add_item(const history_item_t &item) {
@@ -158,10 +166,10 @@ class history_lru_cache_t : public lru_cache_t {
 
         // See if it's in the cache. If it is, update the timestamp. If not, we create a new node
         // and add it. Note that calling get_node promotes the node to the front.
-        history_lru_node_t *node = this->get_node(item.str());
+        wcstring key = item.str();
+        history_lru_item_t *node = this->get(key);
         if (node == NULL) {
-            node = new history_lru_node_t(item);
-            this->add_node(node);
+            this->insert(std::move(key), history_lru_item_t(item));
         } else {
             node->timestamp = std::max(node->timestamp, item.timestamp());
             // What to do about paths here? Let's just ignore them.
@@ -169,20 +177,13 @@ class history_lru_cache_t : public lru_cache_t {
     }
 };
 
+// The set of histories
+// Note that histories are currently immortal
 class history_collection_t {
-    pthread_mutex_t m_lock;
-    std::map m_histories;
+    owning_lock>> histories;
 
-   public:
-    history_collection_t() { VOMIT_ON_FAILURE_NO_ERRNO(pthread_mutex_init(&m_lock, NULL)); }
-    ~history_collection_t() {
-        for (std::map::const_iterator i = m_histories.begin();
-             i != m_histories.end(); ++i) {
-            delete i->second;
-        }
-        pthread_mutex_destroy(&m_lock);
-    }
-    history_t &alloc(const wcstring &name);
+    public:
+    history_t &get_creating(const wcstring &name);
     void save();
 };
 
@@ -308,16 +309,10 @@ static history_item_t decode_item_fish_1_x(const char *begin, size_t length) {
             if (timestamp_mode) {
                 const wchar_t *time_string = out.c_str();
                 while (*time_string && !iswdigit(*time_string)) time_string++;
-                errno = 0;
 
                 if (*time_string) {
-                    time_t tm;
-                    wchar_t *end;
-
-                    errno = 0;
-                    tm = (time_t)wcstol(time_string, &end, 10);
-
-                    if (tm && !errno && !*end) {
+                    time_t tm = (time_t)fish_wcstol(time_string);
+                    if (!errno && tm >= 0) {
                         timestamp = tm;
                     }
                 }
@@ -696,16 +691,21 @@ static size_t offset_of_next_item(const char *begin, size_t mmap_length,
     return result;
 }
 
-history_t &history_collection_t::alloc(const wcstring &name) {
+history_t &history_collection_t::get_creating(const wcstring &name) {
+    // Return a history for the given name, creating it if necessary
     // Note that histories are currently never deleted, so we can return a reference to them without
-    // using something like shared_ptr.
-    scoped_lock locker(m_lock);
-    history_t *¤t = m_histories[name];
-    if (current == NULL) current = new history_t(name);
-    return *current;
+    // using something like shared_ptr
+    auto hs = histories.acquire();
+    std::unique_ptr &hist = hs.value[name];
+    if (! hist) {
+        hist = make_unique(name);
+    }
+    return *hist;
 }
 
-history_t &history_t::history_with_name(const wcstring &name) { return histories.alloc(name); }
+history_t &history_t::history_with_name(const wcstring &name) {
+    return histories.get_creating(name);
+}
 
 history_t::history_t(const wcstring &pname)
     : name(pname),
@@ -791,15 +791,6 @@ void history_t::add(const wcstring &str, history_identifier_t ident, bool pendin
     this->add(history_item_t(str, when, ident), pending);
 }
 
-bool icompare_pred(wchar_t a, wchar_t b) { return std::tolower(a) == std::tolower(b); }
-
-bool icompare(wcstring const &a, wcstring const &b) {
-    if (a.length() != b.length()) {
-        return false;
-    }
-    return std::equal(b.begin(), b.end(), a.begin(), icompare_pred);
-}
-
 // Remove matching history entries from our list of new items. This only supports literal,
 // case-sensitive, matches.
 void history_t::remove(const wcstring &str_to_remove) {
@@ -962,20 +953,21 @@ bool history_t::map_file(const wcstring &name, const char **out_map_start, size_
     // unlikely because we only treat an item as valid if it has a terminating newline.
     //
     // Simulate a failing lock in chaos_mode.
-    if (!chaos_mode) history_file_lock(fd, F_RDLCK);
+    if (!chaos_mode) history_file_lock(fd, LOCK_SH);
     off_t len = lseek(fd, 0, SEEK_END);
     if (len != (off_t)-1) {
         size_t mmap_length = (size_t)len;
         if (lseek(fd, 0, SEEK_SET) == 0) {
             char *mmap_start;
-            if ((mmap_start = (char *)mmap(0, mmap_length, PROT_READ, MAP_PRIVATE, fd,
-                                            0)) != MAP_FAILED) {
+            if ((mmap_start = (char *)mmap(0, mmap_length, PROT_READ, MAP_PRIVATE, fd, 0)) !=
+                MAP_FAILED) {
                 result = true;
                 *out_map_start = mmap_start;
                 *out_map_len = mmap_length;
             }
         }
     }
+    if (!chaos_mode) history_file_lock(fd, LOCK_UN);
     close(fd);
     return result;
 }
@@ -1235,24 +1227,16 @@ bool history_t::save_internal_via_rewrite() {
 
         signal_block();
 
-        // Try to create a temporary file, up to 10 times. We don't use mkstemps because we want to
-        // open it CLO_EXEC. This should almost always succeed on the first try.
+        // Try to create a CLO_EXEC temporary file, up to 10 times.
+        // This should almost always succeed on the first try.
         int out_fd = -1;
         wcstring tmp_name;
         for (size_t attempt = 0; attempt < 10 && out_fd == -1; attempt++) {
             char *narrow_str = wcs2str(tmp_name_template.c_str());
-#if HAVE_MKOSTEMP
-            out_fd = mkostemp(narrow_str, O_CLOEXEC);
+            out_fd = fish_mkstemp_cloexec(narrow_str);
             if (out_fd >= 0) {
                 tmp_name = str2wcstring(narrow_str);
             }
-#else
-            if (narrow_str && mktemp(narrow_str)) {
-                // It was successfully templated; try opening it atomically.
-                tmp_name = str2wcstring(narrow_str);
-                out_fd = wopen_cloexec(tmp_name, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, 0600);
-            }
-#endif
             free(narrow_str);
         }
 
@@ -1261,8 +1245,9 @@ bool history_t::save_internal_via_rewrite() {
             bool errored = false;
             history_output_buffer_t buffer;
             for (history_lru_cache_t::iterator iter = lru.begin(); iter != lru.end(); ++iter) {
-                const history_lru_node_t *node = *iter;
-                append_yaml_to_buffer(node->key, node->timestamp, node->required_paths, &buffer);
+                const wcstring &text = (*iter).first;
+                const history_lru_item_t &item = (*iter).second;
+                append_yaml_to_buffer(text, item.timestamp, item.required_paths, &buffer);
                 if (buffer.output_size() >= HISTORY_OUTPUT_BUFFER_SIZE &&
                     !buffer.flush_to_fd(out_fd)) {
                     errored = true;
@@ -1353,7 +1338,7 @@ bool history_t::save_internal_via_appending() {
         // by writing with O_APPEND.
         //
         // Simulate a failing lock in chaos_mode
-        if (!chaos_mode) history_file_lock(out_fd, F_WRLCK);
+        if (!chaos_mode) history_file_lock(out_fd, LOCK_EX);
 
         // We (hopefully successfully) took the exclusive lock. Append to the file.
         // Note that this is sketchy for a few reasons:
@@ -1393,6 +1378,7 @@ bool history_t::save_internal_via_appending() {
             ok = true;
         }
 
+        if (!chaos_mode) history_file_lock(out_fd, LOCK_UN);
         close(out_fd);
     }
 
@@ -1450,7 +1436,11 @@ static bool format_history_record(const history_item_t &item, const wchar_t *sho
         streams.out.append(timestamp_string);
     }
     streams.out.append(item.str());
-    streams.out.append(null_terminate ? L'\0' : L'\n');
+    if (null_terminate) {
+        streams.out.append(L'\0');
+    } else {
+        streams.out.append(L'\n');
+    }
     return true;
 }
 
@@ -1648,17 +1638,17 @@ void history_t::incorporate_external_changes() {
         // We'll pick them up from the file (#2312)
         this->save_internal(false);
         this->new_items.clear();
+        this->first_unwritten_new_item_index = 0;
     }
 }
 
 void history_init() {}
 
 void history_collection_t::save() {
-    // Save all histories.
-    for (std::map::iterator iter = m_histories.begin();
-         iter != m_histories.end(); ++iter) {
-        history_t *hist = iter->second;
-        hist->save();
+    // Save all histories
+    auto h = histories.acquire();
+    for (auto &p : h.value) {
+        p.second->save();
     }
 }
 
@@ -1668,53 +1658,25 @@ void history_sanity_check() {
     // No sanity checking implemented yet...
 }
 
-int file_detection_context_t::perform_file_detection(bool test_all) {
+path_list_t valid_paths(const path_list_t &paths, const wcstring &working_directory) {
     ASSERT_IS_BACKGROUND_THREAD();
-    valid_paths.clear();
-    // TODO: Figure out why this bothers to return a variable result since the only consumer,
-    // perform_file_detection_done(), ignores the result. It seems like either this should always
-    // return a constant or perform_file_detection_done() should use our return value.
-    int result = 1;
-    for (path_list_t::const_iterator iter = potential_paths.begin(); iter != potential_paths.end();
-         ++iter) {
-        if (path_is_valid(*iter, working_directory)) {
-            // Push the original (possibly relative) path.
-            valid_paths.push_back(*iter);
-        } else {
-            // Not a valid path.
-            result = 0;
-            if (!test_all) break;
+    wcstring_list_t result;
+    for (const wcstring &path : paths) {
+        if (path_is_valid(path, working_directory)) {
+            result.push_back(path);
         }
     }
     return result;
 }
 
-bool file_detection_context_t::paths_are_valid(const path_list_t &paths) {
-    this->potential_paths = paths;
-    return perform_file_detection(false) > 0;
-}
-
-file_detection_context_t::file_detection_context_t(history_t *hist, history_identifier_t ident)
-    : history(hist), working_directory(env_get_pwd_slash()), history_item_identifier(ident) {}
-
-static int threaded_perform_file_detection(file_detection_context_t *ctx) {
+bool all_paths_are_valid(const path_list_t &paths, const wcstring &working_directory) {
     ASSERT_IS_BACKGROUND_THREAD();
-    assert(ctx != NULL);
-    return ctx->perform_file_detection(true /* test all */);
-}
-
-static void perform_file_detection_done(file_detection_context_t *ctx, int success) {
-    UNUSED(success);
-    ASSERT_IS_MAIN_THREAD();
-
-    // Now that file detection is done, update the history item with the valid file paths.
-    ctx->history->set_valid_file_paths(ctx->valid_paths, ctx->history_item_identifier);
-
-    // Allow saving again.
-    ctx->history->enable_automatic_saving();
-
-    // Done with the context.
-    delete ctx;
+    for (const wcstring &path : paths) {
+        if (!path_is_valid(path, working_directory)) {
+            return false;
+        }
+    }
+    return true;
 }
 
 static bool string_could_be_path(const wcstring &potential_path) {
@@ -1727,7 +1689,6 @@ static bool string_could_be_path(const wcstring &potential_path) {
 
 void history_t::add_pending_with_file_detection(const wcstring &str) {
     ASSERT_IS_MAIN_THREAD();
-    path_list_t potential_paths;
 
     // Find all arguments that look like they could be file paths.
     bool impending_exit = false;
@@ -1735,6 +1696,7 @@ void history_t::add_pending_with_file_detection(const wcstring &str) {
     parse_tree_from_string(str, parse_flag_none, &tree, NULL);
     size_t count = tree.size();
 
+    path_list_t potential_paths;
     for (size_t i = 0; i < count; i++) {
         const parse_node_t &node = tree.at(i);
         if (!node.has_source()) {
@@ -1771,16 +1733,17 @@ void history_t::add_pending_with_file_detection(const wcstring &str) {
         static history_identifier_t sLastIdentifier = 0;
         identifier = ++sLastIdentifier;
 
-        // Create a new detection context.
-        file_detection_context_t *context = new file_detection_context_t(this, identifier);
-        context->potential_paths.swap(potential_paths);
-
         // Prevent saving until we're done, so we have time to get the paths.
         this->disable_automatic_saving();
 
-        // Kick it off. Even though we haven't added the item yet, it updates the item on the main
-        // thread, so we can't race.
-        iothread_perform(threaded_perform_file_detection, perform_file_detection_done, context);
+        // Check for which paths are valid on a background thread,
+        // then on the main thread update our history item
+        const wcstring wd = env_get_pwd_slash();
+        iothread_perform([=]() { return valid_paths(potential_paths, wd); },
+                         [=](path_list_t validated_paths) {
+                             this->set_valid_file_paths(validated_paths, identifier);
+                             this->enable_automatic_saving();
+                         });
     }
 
     // Actually add the item to the history.
diff --git a/src/history.h b/src/history.h
index a8aa51575..11aece2c0 100644
--- a/src/history.h
+++ b/src/history.h
@@ -7,6 +7,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -326,7 +327,8 @@ class history_search_t {
     }
 
     // Default constructor.
-    history_search_t() : history(), term(), search_type(HISTORY_SEARCH_TYPE_CONTAINS), case_sensitive(true) {}
+    history_search_t()
+        : history(), term(), search_type(HISTORY_SEARCH_TYPE_CONTAINS), case_sensitive(true) {}
 };
 
 // Init history library. The history file won't actually be loaded until the first time a history
@@ -339,34 +341,12 @@ void history_destroy();
 // Perform sanity checks.
 void history_sanity_check();
 
-// A helper class for threaded detection of paths.
-struct file_detection_context_t {
-    // Constructor.
-    explicit file_detection_context_t(history_t *hist, history_identifier_t ident = 0);
+// Given a list of paths and a working directory, return the paths that are valid
+// This does disk I/O and may only be called in a background thread
+path_list_t valid_paths(const path_list_t &paths, const wcstring &working_directory);
 
-    // Determine which of potential_paths are valid, and put them in valid_paths.
-    int perform_file_detection();
-
-    // The history associated with this context.
-    history_t *const history;
-
-    // The working directory at the time the command was issued.
-    wcstring working_directory;
-
-    // Paths to test.
-    path_list_t potential_paths;
-
-    // Paths that were found to be valid.
-    path_list_t valid_paths;
-
-    // Identifier of the history item to which we are associated.
-    const history_identifier_t history_item_identifier;
-
-    // Performs file detection. Returns 1 if every path in potential_paths is valid, 0 otherwise. If
-    // test_all is true, tests every path; otherwise stops as soon as it reaches an invalid path.
-    int perform_file_detection(bool test_all);
-
-    // Determine whether the given paths are all valid.
-    bool paths_are_valid(const path_list_t &paths);
-};
+// Given a list of paths and a working directory,
+// return true if all paths in the list are valid
+// Returns true for if paths is empty
+bool all_paths_are_valid(const path_list_t &paths, const wcstring &working_directory);
 #endif
diff --git a/src/input.cpp b/src/input.cpp
index 971a6a9c8..9e9989b84 100644
--- a/src/input.cpp
+++ b/src/input.cpp
@@ -2,8 +2,12 @@
 #include "config.h"
 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
+#include 
 #if HAVE_NCURSES_H
 #include 
 #elif HAVE_NCURSES_CURSES_H
@@ -16,8 +20,7 @@
 #elif HAVE_NCURSES_TERM_H
 #include 
 #endif
-#include 
-#include 
+
 #include 
 #include 
 #include 
@@ -289,8 +292,7 @@ static int interrupt_handler() {
     if (job_reap(1)) reader_repaint_needed();
     // Tell the reader an event occured.
     if (reader_reading_interrupted()) {
-        // Return 3, i.e. the character read by a Control-C.
-        return 3;
+        return shell_modes.c_cc[VINTR];
     }
 
     return R_NULL;
@@ -372,6 +374,7 @@ int input_init() {
         } else {
             debug(0, _(L"Using fallback terminal type '%ls'"), DEFAULT_TERM);
         }
+        fputwc(L'\n', stderr);
     }
 
     input_terminfo_init();
@@ -490,7 +493,7 @@ static void input_mapping_execute(const input_mapping_t &m, bool allow_commands)
 
 /// Try reading the specified function mapping.
 static bool input_mapping_is_match(const input_mapping_t &m) {
-    wint_t c = 0;
+    wchar_t c = 0;
     int j;
 
     debug(2, L"trying to match mapping %ls", escape(m.seq.c_str(), ESCAPE_ALL).c_str());
diff --git a/src/input_common.cpp b/src/input_common.cpp
index a82e801ce..3d44a7953 100644
--- a/src/input_common.cpp
+++ b/src/input_common.cpp
@@ -25,9 +25,10 @@
 #include "input_common.h"
 #include "iothread.h"
 #include "util.h"
+#include "wutil.h"
 
 /// Time in milliseconds to wait for another byte to be available for reading
-/// after \x1b is read before assuming that escape key was pressed, and not an
+/// after \e is read before assuming that escape key was pressed, and not an
 /// escape sequence.
 #define WAIT_ON_ESCAPE_DEFAULT 300
 static int wait_on_escape_ms = WAIT_ON_ESCAPE_DEFAULT;
@@ -36,8 +37,7 @@ static int wait_on_escape_ms = WAIT_ON_ESCAPE_DEFAULT;
 static std::deque lookahead_list;
 
 // Queue of pairs of (function pointer, argument) to be invoked. Expected to be mostly empty.
-typedef std::pair callback_info_t;
-typedef std::queue > callback_queue_t;
+typedef std::list> callback_queue_t;
 static callback_queue_t callback_queue;
 static void input_flush_callbacks(void);
 
@@ -167,13 +167,11 @@ void update_wait_on_escape_ms() {
         return;
     }
 
-    wchar_t *endptr;
-    long tmp = wcstol(escape_time_ms.c_str(), &endptr, 10);
-
-    if (*endptr != '\0' || tmp < 10 || tmp >= 5000) {
+    long tmp = fish_wcstol(escape_time_ms.c_str());
+    if (errno || tmp < 10 || tmp >= 5000) {
         fwprintf(stderr,
                  L"ignoring fish_escape_delay_ms: value '%ls' "
-                 "is not an integer or is < 10 or >= 5000 ms\n",
+                 L"is not an integer or is < 10 or >= 5000 ms\n",
                  escape_time_ms.c_str());
     } else {
         wait_on_escape_ms = (int)tmp;
@@ -238,22 +236,18 @@ void input_common_queue_ch(wint_t ch) { lookahead_push_back(ch); }
 
 void input_common_next_ch(wint_t ch) { lookahead_push_front(ch); }
 
-void input_common_add_callback(void (*callback)(void *), void *arg) {
+void input_common_add_callback(std::function callback) {
     ASSERT_IS_MAIN_THREAD();
-    callback_queue.push(callback_info_t(callback, arg));
+    callback_queue.push_back(std::move(callback));
 }
 
 static void input_flush_callbacks(void) {
-    // Nothing to do if nothing to do.
-    if (callback_queue.empty()) return;
-
     // We move the queue into a local variable, so that events queued up during a callback don't get
     // fired until next round.
+    ASSERT_IS_MAIN_THREAD();
     callback_queue_t local_queue;
     std::swap(local_queue, callback_queue);
-    while (!local_queue.empty()) {
-        const callback_info_t &callback = local_queue.front();
-        callback.first(callback.second);  // cute
-        local_queue.pop();
+    for (auto &f : local_queue) {
+        f();
     }
 }
diff --git a/src/input_common.h b/src/input_common.h
index 88e75c0fd..3b8bb0535 100644
--- a/src/input_common.h
+++ b/src/input_common.h
@@ -3,6 +3,7 @@
 #define INPUT_COMMON_H
 
 #include 
+#include 
 
 #include "common.h"
 
@@ -104,6 +105,6 @@ void input_common_next_ch(wint_t ch);
 
 /// Adds a callback to be invoked at the next turn of the "event loop." The callback function will
 /// be invoked and passed arg.
-void input_common_add_callback(void (*callback)(void *), void *arg);
+void input_common_add_callback(std::function);
 
 #endif
diff --git a/src/intern.cpp b/src/intern.cpp
index 2ec335648..1f83b2f82 100644
--- a/src/intern.cpp
+++ b/src/intern.cpp
@@ -12,53 +12,29 @@
 #include "fallback.h"  // IWYU pragma: keep
 #include "intern.h"
 
-/// Comparison function for intern'd strings.
-class string_table_compare_t {
-   public:
-    bool operator()(const wchar_t *a, const wchar_t *b) const { return wcscmp(a, b) < 0; }
-};
+bool string_less_than_string(const wchar_t *a, const wchar_t *b) {
+    return wcscmp(a, b) < 0;
+}
 
-// A sorted vector ends up being a little more memory efficient than a std::set for the intern'd
-// string table.
-#define USE_SET 0
-#if USE_SET
 /// The table of intern'd strings.
-typedef std::set string_table_t;
-#else
-/// The table of intern'd strings.
-typedef std::vector string_table_t;
-#endif
-
-static string_table_t string_table;
-
-/// The lock to provide thread safety for intern'd strings.
-static pthread_mutex_t intern_lock = PTHREAD_MUTEX_INITIALIZER;
+owning_lock> string_table;
 
 static const wchar_t *intern_with_dup(const wchar_t *in, bool dup) {
     if (!in) return NULL;
 
     debug(5, L"intern %ls", in);
-    scoped_lock locker(intern_lock);
-    const wchar_t *result;
+    auto lock_string_table = string_table.acquire();
+    std::vector &string_table = lock_string_table.value;
 
-#if USE_SET
-    string_table_t::const_iterator iter = string_table.find(in);
-    if (iter != string_table.end()) {
-        result = *iter;
-    } else {
-        result = dup ? wcsdup(in) : in;
-        string_table.insert(result);
-    }
-#else
-    string_table_t::iterator iter =
-        std::lower_bound(string_table.begin(), string_table.end(), in, string_table_compare_t());
+    const wchar_t *result;
+    auto iter = std::lower_bound(string_table.begin(), string_table.end(),
+                                 in, string_less_than_string);
     if (iter != string_table.end() && wcscmp(*iter, in) == 0) {
         result = *iter;
     } else {
         result = dup ? wcsdup(in) : in;
         string_table.insert(iter, result);
     }
-#endif
     return result;
 }
 
diff --git a/src/io.cpp b/src/io.cpp
index be33bcb12..22af1195e 100644
--- a/src/io.cpp
+++ b/src/io.cpp
@@ -6,6 +6,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "common.h"
 #include "exec.h"
@@ -15,19 +16,20 @@
 
 io_data_t::~io_data_t() {}
 
-void io_close_t::print() const { fprintf(stderr, "close %d\n", fd); }
+void io_close_t::print() const { fwprintf(stderr, L"close %d\n", fd); }
 
-void io_fd_t::print() const { fprintf(stderr, "FD map %d -> %d\n", old_fd, fd); }
+void io_fd_t::print() const { fwprintf(stderr, L"FD map %d -> %d\n", old_fd, fd); }
 
-void io_file_t::print() const { fprintf(stderr, "file (%s)\n", filename_cstr); }
+void io_file_t::print() const { fwprintf(stderr, L"file (%s)\n", filename_cstr); }
 
 void io_pipe_t::print() const {
-    fprintf(stderr, "pipe {%d, %d} (input: %s)\n", pipe_fd[0], pipe_fd[1], is_input ? "yes" : "no");
+    fwprintf(stderr, L"pipe {%d, %d} (input: %s)\n", pipe_fd[0], pipe_fd[1],
+             is_input ? "yes" : "no");
 }
 
 void io_buffer_t::print() const {
-    fprintf(stderr, "buffer %p (input: %s, size %lu)\n", out_buffer_ptr(), is_input ? "yes" : "no",
-            (unsigned long)out_buffer_size());
+    fwprintf(stderr, L"buffer %p (input: %s, size %lu)\n", out_buffer_ptr(),
+             is_input ? "yes" : "no", (unsigned long)out_buffer_size());
 }
 
 void io_buffer_t::read() {
@@ -74,10 +76,10 @@ bool io_buffer_t::avoid_conflicts_with_io_chain(const io_chain_t &ios) {
     return result;
 }
 
-io_buffer_t *io_buffer_t::create(int fd, const io_chain_t &conflicts) {
+shared_ptr io_buffer_t::create(int fd, const io_chain_t &conflicts) {
     bool success = true;
     assert(fd >= 0);
-    io_buffer_t *buffer_redirect = new io_buffer_t(fd);
+    shared_ptr buffer_redirect(new io_buffer_t(fd));
 
     if (exec_pipe(buffer_redirect->pipe_fd) == -1) {
         debug(1, PIPE_ERROR);
@@ -93,8 +95,7 @@ io_buffer_t *io_buffer_t::create(int fd, const io_chain_t &conflicts) {
     }
 
     if (!success) {
-        delete buffer_redirect;
-        buffer_redirect = NULL;
+        buffer_redirect.reset();
     }
     return buffer_redirect;
 }
@@ -139,21 +140,21 @@ void io_print(const io_chain_t &chain)
 {
     if (chain.empty())
     {
-        fprintf(stderr, "Empty chain %p\n", &chain);
+        fwprintf(stderr, L"Empty chain %p\n", &chain);
         return;
     }
 
-    fprintf(stderr, "Chain %p (%ld items):\n", &chain, (long)chain.size());
+    fwprintf(stderr, L"Chain %p (%ld items):\n", &chain, (long)chain.size());
     for (size_t i=0; i < chain.size(); i++)
     {
         const shared_ptr &io = chain.at(i);
         if (io.get() == NULL)
         {
-            fprintf(stderr, "\t(null)\n");
+            fwprintf(stderr, L"\t(null)\n");
         }
         else
         {
-            fprintf(stderr, "\t%lu: fd:%d, ", (unsigned long)i, io->fd);
+            fwprintf(stderr, L"\t%lu: fd:%d, ", (unsigned long)i, io->fd);
             io->print();
         }
     }
diff --git a/src/io.h b/src/io.h
index f8149a818..25a277cd7 100644
--- a/src/io.h
+++ b/src/io.h
@@ -133,7 +133,7 @@ class io_buffer_t : public io_pipe_t {
     /// \param fd the fd that will be mapped in the child process, typically STDOUT_FILENO
     /// \param conflicts A set of IO redirections. The function ensures that any pipe it makes does
     /// not conflict with an fd redirection in this list.
-    static io_buffer_t *create(int fd, const io_chain_t &conflicts);
+    static shared_ptr create(int fd, const io_chain_t &conflicts);
 };
 
 class io_chain_t : public std::vector > {
diff --git a/src/iothread.cpp b/src/iothread.cpp
index e9279dae9..5ec7f92e7 100644
--- a/src/iothread.cpp
+++ b/src/iothread.cpp
@@ -6,7 +6,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -15,6 +14,7 @@
 
 #include "common.h"
 #include "iothread.h"
+#include "wutil.h"
 
 #ifdef _POSIX_THREAD_THREADS_MAX
 #if _POSIX_THREAD_THREADS_MAX < 64
@@ -33,34 +33,52 @@
 static void iothread_service_main_thread_requests(void);
 static void iothread_service_result_queue();
 
-struct SpawnRequest_t {
-    int (*handler)(void *);
-    void (*completionCallback)(void *, int);
-    void *context;
-    int handlerResult;
+typedef std::function void_function_t;
+
+struct spawn_request_t {
+    void_function_t handler;
+    void_function_t completion;
+
+    spawn_request_t() {}
+
+    spawn_request_t(void_function_t f, void_function_t comp)
+        : handler(std::move(f)), completion(std::move(comp)) {}
+
+    // Move-only
+    spawn_request_t &operator=(const spawn_request_t &) = delete;
+    spawn_request_t &operator=(spawn_request_t &&) = default;
+    spawn_request_t(const spawn_request_t &) = delete;
+    spawn_request_t(spawn_request_t &&) = default;
 };
 
-struct MainThreadRequest_t {
-    int (*handler)(void *);
-    void *context;
-    volatile int handlerResult;
-    volatile bool done;
+struct main_thread_request_t {
+    volatile bool done = false;
+    void_function_t func;
+
+    main_thread_request_t(void_function_t f) : func(std::move(f)) {}
+
+    // No moving OR copying
+    // main_thread_requests are always stack allocated, and we deal in pointers to them
+    void operator=(const main_thread_request_t &) = delete;
+    main_thread_request_t(const main_thread_request_t &) = delete;
+    main_thread_request_t(main_thread_request_t &&) = delete;
 };
 
-// Spawn support. Requests are allocated and come in on request_queue. They go out on result_queue,
-// at which point they can be deallocated. s_active_thread_count is also protected by the lock.
-static pthread_mutex_t s_spawn_queue_lock;
-static std::queue s_request_queue;
-static int s_active_thread_count;
-
-static pthread_mutex_t s_result_queue_lock;
-static std::queue s_result_queue;
+// Spawn support. Requests are allocated and come in on request_queue and go out on result_queue
+struct thread_data_t {
+    std::queue request_queue;
+    int thread_count = 0;
+};
+static owning_lock s_spawn_requests;
+static owning_lock> s_result_queue;
 
 // "Do on main thread" support.
-static pthread_mutex_t s_main_thread_performer_lock;  // protects the main thread requests
-static pthread_cond_t s_main_thread_performer_cond;   // protects the main thread requests
-static pthread_mutex_t s_main_thread_request_q_lock;  // protects the queue
-static std::queue s_main_thread_request_queue;
+static pthread_mutex_t s_main_thread_performer_lock =
+    PTHREAD_MUTEX_INITIALIZER;                       // protects the main thread requests
+static pthread_cond_t s_main_thread_performer_cond;  // protects the main thread requests
+static pthread_mutex_t s_main_thread_request_q_lock =
+    PTHREAD_MUTEX_INITIALIZER;  // protects the queue
+static std::queue s_main_thread_request_queue;
 
 // Notifying pipes.
 static int s_read_pipe, s_write_pipe;
@@ -71,10 +89,6 @@ static void iothread_init(void) {
         inited = true;
 
         // Initialize some locks.
-        VOMIT_ON_FAILURE(pthread_mutex_init(&s_spawn_queue_lock, NULL));
-        VOMIT_ON_FAILURE(pthread_mutex_init(&s_result_queue_lock, NULL));
-        VOMIT_ON_FAILURE(pthread_mutex_init(&s_main_thread_request_q_lock, NULL));
-        VOMIT_ON_FAILURE(pthread_mutex_init(&s_main_thread_performer_lock, NULL));
         VOMIT_ON_FAILURE(pthread_cond_init(&s_main_thread_performer_cond, NULL));
 
         // Initialize the completion pipes.
@@ -83,31 +97,24 @@ static void iothread_init(void) {
         s_read_pipe = pipes[0];
         s_write_pipe = pipes[1];
 
-        // 0 means success to VOMIT_ON_FAILURE. Arrange to pass 0 if fcntl returns anything other
-        // than -1.
-        VOMIT_ON_FAILURE(-1 == fcntl(s_read_pipe, F_SETFD, FD_CLOEXEC));
-        VOMIT_ON_FAILURE(-1 == fcntl(s_write_pipe, F_SETFD, FD_CLOEXEC));
+        set_cloexec(s_read_pipe);
+        set_cloexec(s_write_pipe);
     }
 }
 
-static void add_to_queue(struct SpawnRequest_t *req) {
-    ASSERT_IS_LOCKED(s_spawn_queue_lock);
-    s_request_queue.push(req);
-}
-
-static SpawnRequest_t *dequeue_spawn_request(void) {
-    ASSERT_IS_LOCKED(s_spawn_queue_lock);
-    SpawnRequest_t *result = NULL;
-    if (!s_request_queue.empty()) {
-        result = s_request_queue.front();
-        s_request_queue.pop();
+static bool dequeue_spawn_request(spawn_request_t *result) {
+    auto locker = s_spawn_requests.acquire();
+    thread_data_t &td = locker.value;
+    if (!td.request_queue.empty()) {
+        *result = std::move(td.request_queue.front());
+        td.request_queue.pop();
+        return true;
     }
-    return result;
+    return false;
 }
 
-static void enqueue_thread_result(SpawnRequest_t *req) {
-    scoped_lock locker(s_result_queue_lock);
-    s_result_queue.push(req);
+static void enqueue_thread_result(spawn_request_t req) {
+    s_result_queue.acquire().value.push(std::move(req));
 }
 
 static void *this_thread() { return (void *)(intptr_t)pthread_self(); }
@@ -115,41 +122,32 @@ static void *this_thread() { return (void *)(intptr_t)pthread_self(); }
 /// The function that does thread work.
 static void *iothread_worker(void *unused) {
     UNUSED(unused);
-    scoped_lock locker(s_spawn_queue_lock);
-    struct SpawnRequest_t *req;
-    while ((req = dequeue_spawn_request()) != NULL) {
-        debug(5, "pthread %p dequeued %p\n", this_thread(), req);
-        // Unlock the queue while we execute the request.
-        locker.unlock();
+    struct spawn_request_t req;
+    while (dequeue_spawn_request(&req)) {
+        debug(5, "pthread %p dequeued\n", this_thread());
 
-        // Perform the work.
-        req->handlerResult = req->handler(req->context);
+        // Perform the work
+        req.handler();
 
-        // If there's a completion handler, we have to enqueue it on the result queue. Otherwise, we
-        // can just delete the request!
-        if (req->completionCallback == NULL) {
-            delete req;
-        } else {
+        // If there's a completion handler, we have to enqueue it on the result queue.
+        // Note we're using std::function's weirdo operator== here
+        if (req.completion != nullptr) {
             // Enqueue the result, and tell the main thread about it.
-            enqueue_thread_result(req);
+            enqueue_thread_result(std::move(req));
             const char wakeup_byte = IO_SERVICE_RESULT_QUEUE;
             VOMIT_ON_FAILURE(!write_loop(s_write_pipe, &wakeup_byte, sizeof wakeup_byte));
         }
-
-        // Lock us up again.
-        locker.lock();
     }
 
     // We believe we have exhausted the thread request queue. We want to decrement
-    // s_active_thread_count and exit. But it's possible that a request just came in. Furthermore,
-    // it's possible that the main thread saw that s_active_thread_count is full, and decided to not
+    // thread_count and exit. But it's possible that a request just came in. Furthermore,
+    // it's possible that the main thread saw that thread_count is full, and decided to not
     // spawn a new thread, trusting in one of the existing threads to handle it. But we've already
     // committed to not handling anything else. Therefore, we have to decrement
-    // s_active_thread_count under the lock, which we still hold. Likewise, the main thread must
+    // the thread count under the lock, which we still hold. Likewise, the main thread must
     // check the value under the lock.
-    ASSERT_IS_LOCKED(s_spawn_queue_lock);
-    assert(s_active_thread_count > 0);
-    s_active_thread_count -= 1;
+    int new_thread_count = --s_spawn_requests.acquire().value.thread_count;
+    assert(new_thread_count >= 0);
 
     debug(5, "pthread %p exiting\n", this_thread());
     // We're done.
@@ -178,38 +176,30 @@ static void iothread_spawn() {
     VOMIT_ON_FAILURE(pthread_sigmask(SIG_SETMASK, &saved_set, NULL));
 }
 
-int iothread_perform_base(int (*handler)(void *), void (*completionCallback)(void *, int),
-                          void *context) {
+int iothread_perform_impl(void_function_t &&func, void_function_t &&completion) {
     ASSERT_IS_MAIN_THREAD();
     ASSERT_IS_NOT_FORKED_CHILD();
     iothread_init();
 
-    // Create and initialize a request.
-    struct SpawnRequest_t *req = new SpawnRequest_t();
-    req->handler = handler;
-    req->completionCallback = completionCallback;
-    req->context = context;
-
+    struct spawn_request_t req(std::move(func), std::move(completion));
     int local_thread_count = -1;
     bool spawn_new_thread = false;
     {
-        // Lock around a local region. Note that we can only access s_active_thread_count under the
-        // lock.
-        scoped_lock locker(s_spawn_queue_lock);
-        add_to_queue(req);
-        if (s_active_thread_count < IO_MAX_THREADS) {
-            s_active_thread_count++;
+        // Lock around a local region.
+        auto locker = s_spawn_requests.acquire();
+        thread_data_t &td = locker.value;
+        td.request_queue.push(std::move(req));
+        if (td.thread_count < IO_MAX_THREADS) {
+            td.thread_count++;
             spawn_new_thread = true;
         }
-        local_thread_count = s_active_thread_count;
+        local_thread_count = td.thread_count;
     }
 
     // Kick off the thread if we decided to do so.
     if (spawn_new_thread) {
         iothread_spawn();
     }
-
-    // We return the active thread count for informational purposes only.
     return local_thread_count;
 }
 
@@ -228,7 +218,7 @@ void iothread_service_completion(void) {
     } else if (wakeup_byte == IO_SERVICE_RESULT_QUEUE) {
         iothread_service_result_queue();
     } else {
-        fprintf(stderr, "Unknown wakeup byte %02x in %s\n", wakeup_byte, __FUNCTION__);
+        debug(0, "Unknown wakeup byte %02x in %s", wakeup_byte, __FUNCTION__);
     }
 }
 
@@ -258,25 +248,22 @@ void iothread_drain_all(void) {
     ASSERT_IS_MAIN_THREAD();
     ASSERT_IS_NOT_FORKED_CHILD();
 
-    scoped_lock locker(s_spawn_queue_lock);
-
 #define TIME_DRAIN 0
 #if TIME_DRAIN
-    int thread_count = s_active_thread_count;
+    int thread_count = s_spawn_requests.acquire().value.thread_count;
     double now = timef();
 #endif
 
     // Nasty polling via select().
-    while (s_active_thread_count > 0) {
-        locker.unlock();
+    while (s_spawn_requests.acquire().value.thread_count > 0) {
         if (iothread_wait_for_pending_completions(1000)) {
             iothread_service_completion();
         }
-        locker.lock();
     }
 #if TIME_DRAIN
     double after = timef();
-    printf("(Waited %.02f msec for %d thread(s) to drain)\n", 1000 * (after - now), thread_count);
+    fwprintf(stdout, L"(Waited %.02f msec for %d thread(s) to drain)\n", 1000 * (after - now),
+             thread_count);
 #endif
 }
 
@@ -285,19 +272,19 @@ static void iothread_service_main_thread_requests(void) {
     ASSERT_IS_MAIN_THREAD();
 
     // Move the queue to a local variable.
-    std::queue request_queue;
+    std::queue request_queue;
     {
         scoped_lock queue_lock(s_main_thread_request_q_lock);
-        std::swap(request_queue, s_main_thread_request_queue);
+        request_queue.swap(s_main_thread_request_queue);
     }
 
     if (!request_queue.empty()) {
         // Perform each of the functions. Note we are NOT responsible for deleting these. They are
         // stack allocated in their respective threads!
         while (!request_queue.empty()) {
-            MainThreadRequest_t *req = request_queue.front();
+            main_thread_request_t *req = request_queue.front();
             request_queue.pop();
-            req->handlerResult = req->handler(req->context);
+            req->func();
             req->done = true;
         }
 
@@ -315,38 +302,31 @@ static void iothread_service_main_thread_requests(void) {
     }
 }
 
-/* Service the queue of results */
+// Service the queue of results
 static void iothread_service_result_queue() {
     // Move the queue to a local variable.
-    std::queue result_queue;
-    {
-        scoped_lock queue_lock(s_result_queue_lock);
-        std::swap(result_queue, s_result_queue);
-    }
+    std::queue result_queue;
+    s_result_queue.acquire().value.swap(result_queue);
 
-    // Perform each completion in order. We are responsibile for cleaning them up.
+    // Perform each completion in order
     while (!result_queue.empty()) {
-        SpawnRequest_t *req = result_queue.front();
+        spawn_request_t req = std::move(result_queue.front());
         result_queue.pop();
-        if (req->completionCallback) {
-            req->completionCallback(req->context, req->handlerResult);
+        // ensure we don't invoke empty functions, that raises an exception
+        if (req.completion != nullptr) {
+            req.completion();
         }
-        delete req;
     }
 }
 
-int iothread_perform_on_main_base(int (*handler)(void *), void *context) {
-    // If this is the main thread, just do it.
+void iothread_perform_on_main(void_function_t &&func) {
     if (is_main_thread()) {
-        return handler(context);
+        func();
+        return;
     }
 
     // Make a new request. Note we are synchronous, so this can be stack allocated!
-    MainThreadRequest_t req;
-    req.handler = handler;
-    req.context = context;
-    req.handlerResult = 0;
-    req.done = false;
+    main_thread_request_t req(std::move(func));
 
     // Append it. Do not delete the nested scope as it is crucial to the proper functioning of this
     // code by virtue of the lock management.
@@ -370,5 +350,4 @@ int iothread_perform_on_main_base(int (*handler)(void *), void *context) {
 
     // Ok, the request must now be done.
     assert(req.done);
-    return req.handlerResult;
 }
diff --git a/src/iothread.h b/src/iothread.h
index ec57be683..b890c4430 100644
--- a/src/iothread.h
+++ b/src/iothread.h
@@ -2,6 +2,8 @@
 #ifndef FISH_IOTHREAD_H
 #define FISH_IOTHREAD_H
 
+#include 
+
 /// Runs a command on a thread.
 ///
 /// \param handler The function to execute on a background thread. Accepts an arbitrary context
@@ -24,27 +26,52 @@ void iothread_service_completion(void);
 /// Waits for all iothreads to terminate.
 void iothread_drain_all(void);
 
+// Internal implementation
+int iothread_perform_impl(std::function &&func, std::function &&completion);
+
+// Template helpers
+// This is the glue part of the handler-completion handoff
+// In general we can just allocate an object, move the result of the handler into it,
+// and then call the completion with that object. However if our type is void,
+// this won't work (new void() fails!). So we have to use this template.
+// The type T is the return type of HANDLER and the argument to COMPLETION
+template 
+struct _iothread_trampoline {
+    template 
+    static int perform(const HANDLER &handler, const COMPLETION &completion) {
+        T *result = new T();  // TODO: placement new?
+        return iothread_perform_impl([=]() { *result = handler(); },
+                                     [=]() {
+                                         completion(std::move(*result));
+                                         delete result;
+                                     });
+    }
+};
+
+// Void specialization
+template <>
+struct _iothread_trampoline {
+    template 
+    static int perform(const HANDLER &handler, const COMPLETION &completion) {
+        return iothread_perform_impl(handler, completion);
+    }
+};
+
+// iothread_perform invokes a handler on a background thread, and then a completion function
+// on the main thread. The value returned from the handler is passed to the completion.
+// In other words, this is like COMPLETION(HANDLER()) except the handler part is invoked
+// on a background thread.
+template 
+int iothread_perform(const HANDLER &handler, const COMPLETION &completion) {
+    return _iothread_trampoline::perform(handler, completion);
+}
+
+// variant of iothread_perform without a completion handler
+inline int iothread_perform(std::function &&func) {
+    return iothread_perform_impl(std::move(func), std::function());
+}
+
 /// Performs a function on the main thread, blocking until it completes.
-int iothread_perform_on_main_base(int (*handler)(void *), void *context);
-
-/// Helper templates.
-template 
-int iothread_perform(int (*handler)(T *), void (*completionCallback)(T *, int), T *context) {
-    return iothread_perform_base((int (*)(void *))handler,
-                                 (void (*)(void *, int))completionCallback,
-                                 static_cast(context));
-}
-
-// Variant that takes no completion callback.
-template 
-int iothread_perform(int (*handler)(T *), T *context) {
-    return iothread_perform_base((int (*)(void *))handler, (void (*)(void *, int))0,
-                                 static_cast(context));
-}
-
-template 
-int iothread_perform_on_main(int (*handler)(T *), T *context) {
-    return iothread_perform_on_main_base((int (*)(void *))handler, (void *)(context));
-}
+void iothread_perform_on_main(std::function &&func);
 
 #endif
diff --git a/src/lru.h b/src/lru.h
index 4a7c2dcff..4dcc1f314 100644
--- a/src/lru.h
+++ b/src/lru.h
@@ -4,194 +4,335 @@
 
 #include 
 #include 
-#include 
 #include 
-#include 
 
 #include "common.h"
 
-/// A predicate to compare dereferenced pointers.
-struct dereference_less_t {
-    template 
-    bool operator()(ptr_t p1, ptr_t p2) const {
-        return *p1 < *p2;
-    }
-};
-
-class lru_node_t {
-    template 
-    friend class lru_cache_t;
-
-    /// Our linked list pointer.
-    lru_node_t *prev, *next;
-
-   public:
-    /// The key used to look up in the cache.
-    const wcstring key;
-
-    /// Constructor.
-    explicit lru_node_t(const wcstring &pkey) : prev(NULL), next(NULL), key(pkey) {}
-
-    /// Virtual destructor that does nothing for classes that inherit lru_node_t.
-    virtual ~lru_node_t() {}
-
-    /// operator< for std::set
-    bool operator<(const lru_node_t &other) const { return key < other.key; }
-};
-
-template 
+// Least-recently-used cache class.
+//
+// This a map from wcstring to CONTENTS, that will evict entries when the count exceeds the maximum.
+// It uses CRTP to inform clients when entries are evicted. This uses the classic LRU cache
+// structure: a dictionary mapping keys to nodes, where the nodes also form a linked list. Our
+// linked list is circular and has a sentinel node (the "mouth" - picture a snake swallowing its
+// tail). This simplifies the logic: no pointer is ever NULL! It also works well with C++'s iterator
+// since the sentinel node is a natural value for end(). Our nodes also have the unusual property of
+// having a "back pointer": they store an iterator to the entry in the map containing the node. This
+// allows us, given a node, to immediately locate the node and its key in the dictionary. This
+// allows us to avoid duplicating the key in the node.
+template 
 class lru_cache_t {
-   private:
-    /// Max node count. This may be (transiently) exceeded by add_node_without_eviction, which is
-    /// used from background threads.
+    struct lru_node_t;
+    typedef typename std::map::iterator node_iter_t;
+
+    struct lru_link_t {
+        // Our doubly linked list
+        // The base class is used for the mouth only
+        lru_link_t *prev = NULL;
+        lru_link_t *next = NULL;
+    };
+
+    // The node type in our LRU cache
+    struct lru_node_t : public lru_link_t {
+        // No copying
+        lru_node_t(const lru_node_t &) = delete;
+        lru_node_t &operator=(const lru_node_t &) = delete;
+        lru_node_t(lru_node_t &&) = default;
+
+        // Our location in the map!
+        node_iter_t iter;
+
+        // The value from the client
+        CONTENTS value;
+
+        explicit lru_node_t(CONTENTS v) : value(std::move(v)) {}
+    };
+
+    // Max node count. This may be (transiently) exceeded by add_node_without_eviction, which is
+    // used from background threads.
     const size_t max_node_count;
 
-    /// Count of nodes.
-    size_t node_count;
+    // All of our nodes
+    // Note that our linked list contains pointers to these nodes in the map
+    // We are dependent on the iterator-noninvalidation guarantees of std::map
+    std::map node_map;
 
-    /// The set of nodes.
-    typedef std::set node_set_t;
-    node_set_t node_set;
+    // Head of the linked list
+    // The list is circular!
+    // If "empty" the mouth just points at itself.
+    lru_link_t mouth;
 
-    void promote_node(node_type_t *node) {
-        // We should never promote the mouth.
+    // Take a node and move it to the front of the list
+    void promote_node(lru_node_t *node) {
         assert(node != &mouth);
 
-        // First unhook us.
+        // First unhook us
         node->prev->next = node->next;
         node->next->prev = node->prev;
 
-        // Put us after the mouth.
+        // Put us after the mouth
         node->next = mouth.next;
         node->next->prev = node;
         node->prev = &mouth;
         mouth.next = node;
     }
 
-    void evict_node(node_type_t *condemned_node) {
+    // Remove the node
+    void evict_node(lru_node_t *node) {
+        assert(node != &mouth);
+
         // We should never evict the mouth.
-        assert(condemned_node != NULL && condemned_node != &mouth);
+        assert(node != NULL && node->iter != this->node_map.end());
 
         // Remove it from the linked list.
-        condemned_node->prev->next = condemned_node->next;
-        condemned_node->next->prev = condemned_node->prev;
+        node->prev->next = node->next;
+        node->next->prev = node->prev;
 
-        // Remove us from the set.
-        node_set.erase(condemned_node);
-        node_count--;
+        // Pull out our key and value
+        wcstring key = std::move(node->iter->first);
+        CONTENTS value(std::move(node->value));
 
-        // Tell ourselves.
-        this->node_was_evicted(condemned_node);
+        // Remove us from the map. This deallocates node!
+        node_map.erase(node->iter);
+        node = NULL;
+
+        // Tell ourselves what we did
+        DERIVED *dthis = static_cast(this);
+        dthis->entry_was_evicted(std::move(key), std::move(value));
     }
 
-    void evict_last_node(void) { evict_node((node_type_t *)mouth.prev); }
+    // Evicts the last node
+    void evict_last_node() {
+        assert(mouth.prev != &mouth);
+        evict_node(static_cast(mouth.prev));
+    }
 
-    static lru_node_t *get_previous(lru_node_t *node) { return node->prev; }
+    // CRTP callback for when a node is evicted.
+    // Clients can implement this
+    void entry_was_evicted(wcstring key, CONTENTS value) {
+        USE(key);
+        USE(value);
+    }
 
-   protected:
-    /// Head of the linked list.
-    lru_node_t mouth;
+    // Implementation of merge step for mergesort
+    // Given two singly linked lists left and right,
+    // and a binary func F implementing less-than, return
+    // the list in sorted order
+    template 
+    static lru_link_t *merge(lru_link_t *left, size_t left_len,
+                             lru_link_t *right, size_t right_len,
+                             const F &func) {
+        assert(left_len > 0 && right_len > 0);
 
-    /// Overridable callback for when a node is evicted.
-    virtual void node_was_evicted(node_type_t *node) { UNUSED(node); }
+        auto popleft = [&](){
+            lru_link_t *ret = left;
+            left = left->next;
+            left_len--;
+            return ret;
+        };
+
+        auto popright = [&](){
+            lru_link_t *ret = right;
+            right = right->next;
+            right_len--;
+            return ret;
+        };
+
+        lru_link_t *head;
+        lru_link_t **cursor = &head;
+        while (left_len && right_len) {
+            bool goleft = ! func(static_cast(left)->value,
+                                 static_cast(right)->value);
+            *cursor = goleft ? popleft() : popright();
+            cursor = &(*cursor)->next;
+        }
+        while (left_len || right_len) {
+            *cursor = left_len ? popleft() : popright();
+            cursor = &(*cursor)->next;
+        }
+        return head;
+    }
+
+    // mergesort the given list of the given length
+    // This only sets the next pointers, not the prev ones
+    template
+    static lru_link_t *mergesort(lru_link_t *node, size_t length, const F &func) {
+        if (length <= 1) {
+            return node;
+        }
+        // divide us into two lists, left and right
+        const size_t left_len = length / 2;
+        const size_t right_len = length - left_len;
+        lru_link_t *left = node;
+
+        lru_link_t *right = node;
+        for (size_t i=0; i < left_len; i++) {
+            right = right->next;
+        }
+
+        // Recursive sorting
+        left = mergesort(left, left_len, func);
+        right = mergesort(right, right_len, func);
+
+        // Merge them
+        return merge(left, left_len, right, right_len, func);
+    }
 
    public:
-    /// Constructor
-    explicit lru_cache_t(size_t max_size = 1024)
-        : max_node_count(max_size), node_count(0), mouth(wcstring()) {
-        // Hook up the mouth to itself: a one node circularly linked list!
-        mouth.prev = mouth.next = &mouth;
+
+    // Constructor
+    // Note our linked list is always circular!
+    explicit lru_cache_t(size_t max_size = 1024) : max_node_count(max_size) {
+        mouth.next = mouth.prev = &mouth;
     }
 
-    /// Note that we do not evict nodes in our destructor (even though they typically need to be
-    /// deleted by their creator).
-    virtual ~lru_cache_t() {}
-
-    /// Returns the node for a given key, or NULL.
-    node_type_t *get_node(const wcstring &key) {
-        node_type_t *result = NULL;
-
-        // Construct a fake node as our key.
-        lru_node_t node_key(key);
-
-        // Look for it in the set.
-        node_set_t::iterator iter = node_set.find(&node_key);
-
-        // If we found a node, promote and return it.
-        if (iter != node_set.end()) {
-            result = static_cast(*iter);
-            promote_node(result);
+    // Returns the value for a given key, or NULL.
+    // This counts as a "use" and so promotes the node
+    CONTENTS *get(const wcstring &key) {
+        auto where = this->node_map.find(key);
+        if (where == this->node_map.end()) {
+            // not found
+            return NULL;
         }
-        return result;
+        promote_node(&where->second);
+        return &where->second.value;
     }
 
-    /// Evicts the node for a given key, returning true if a node was evicted.
+    // Evicts the node for a given key, returning true if a node was evicted.
     bool evict_node(const wcstring &key) {
-        // Construct a fake node as our key.
-        lru_node_t node_key(key);
-
-        // Look for it in the set.
-        node_set_t::iterator iter = node_set.find(&node_key);
-        if (iter == node_set.end()) return false;
-
-        // Evict the given node.
-        evict_node(static_cast(*iter));
+        auto where = this->node_map.find(key);
+        if (where == this->node_map.end()) return false;
+        evict_node(&where->second);
         return true;
     }
 
-    /// Adds a node under the given key. Returns true if the node was added, false if the node was
-    /// not because a node with that key is already in the set.
-    bool add_node(node_type_t *node) {
-        // Add our node without eviction.
-        if (!this->add_node_without_eviction(node)) return false;
+    // Adds a node under the given key. Returns true if the node was added, false if the node was
+    // not because a node with that key is already in the set.
+    bool insert(wcstring key, CONTENTS value) {
+        if (!this->insert_no_eviction(std::move(key), std::move(value))) {
+            return false;
+        }
 
-        while (node_count > max_node_count) evict_last_node();  // evict
+        while (this->node_map.size() > max_node_count) {
+            evict_last_node();
+        }
         return true;
     }
 
-    /// Adds a node under the given key without triggering eviction. Returns true if the node was
-    /// added, false if the node was not because a node with that key is already in the set.
-    bool add_node_without_eviction(node_type_t *node) {
-        assert(node != NULL && node != &mouth);
-
+    // Adds a node under the given key without triggering eviction. Returns true if the node was
+    // added, false if the node was not because a node with that key is already in the set.
+    bool insert_no_eviction(wcstring key, CONTENTS value) {
         // Try inserting; return false if it was already in the set.
-        if (!node_set.insert(node).second) return false;
+        auto iter_inserted = this->node_map.emplace(std::move(key), lru_node_t(std::move(value)));
+        if (!iter_inserted.second) {
+            // already present - so promote it
+            promote_node(&iter_inserted.first->second);
+            return false;
+        }
+
+        // Tell the node where it is in the map
+        node_iter_t iter = iter_inserted.first;
+        lru_node_t *node = &iter->second;
+        node->iter = iter;
 
-        // Add the node after the mouth.
         node->next = mouth.next;
         node->next->prev = node;
         node->prev = &mouth;
         mouth.next = node;
-
-        // Update the count. This may push us over the maximum node count.
-        node_count++;
         return true;
     }
 
-    /// Counts nodes.
-    size_t size(void) { return node_count; }
+    // Number of entries
+    size_t size() const {
+        return this->node_map.size();
+    }
+
+    // Sorting support
+    // Given a binary function F implementing less-than on the contents, place the nodes in sorted order
+    template
+    void stable_sort(const F &func) {
+        // Perform the sort. This sets forward pointers only
+        size_t length = this->size();
+        if (length <= 1) {
+            return;
+        }
+
+        lru_link_t *sorted = mergesort(this->mouth.next, length, func);
+        mouth.next = sorted;
+        // Go through and set back back pointers
+        lru_link_t *cursor = sorted;
+        lru_link_t *prev = &mouth;
+        for (size_t i=0; i < length; i++) {
+            cursor->prev = prev;
+            prev = cursor;
+            cursor = cursor->next;
+        }
+        // prev is now last element in list
+        // make the list circular
+        prev->next = &mouth;
+        mouth.prev = prev;
+    }
 
-    /// Evicts all nodes.
     void evict_all_nodes(void) {
-        while (node_count > 0) {
+        while (this->size() > 0) {
             evict_last_node();
         }
     }
 
-    /// Iterator for walking nodes, from least recently used to most.
+    // Iterator for walking nodes, from least recently used to most.
     class iterator {
-        lru_node_t *node;
+        const lru_link_t *node;
 
        public:
-        explicit iterator(lru_node_t *val) : node(val) {}
-        void operator++() { node = lru_cache_t::get_previous(node); }
+        typedef std::pair value_type;
+
+        explicit iterator(const lru_link_t *val) : node(val) {}
+        void operator++() { node = node->prev; }
         bool operator==(const iterator &other) { return node == other.node; }
         bool operator!=(const iterator &other) { return !(*this == other); }
-        node_type_t *operator*() { return static_cast(node); }
+        value_type operator*() const {
+            const lru_node_t *dnode = static_cast(node);
+            const wcstring &key = dnode->iter->first;
+            return {key, dnode->value};
+        }
     };
 
-    iterator begin() { return iterator(mouth.prev); }
-    iterator end() { return iterator(&mouth); }
+    iterator begin() const { return iterator(mouth.prev); };
+    iterator end() const { return iterator(&mouth); };
+
+    void check_sanity() const {
+        // Check linked list sanity
+        size_t expected_count = this->size();
+        const lru_link_t *prev = &mouth;
+        const lru_link_t *cursor = mouth.next;
+
+        size_t max = 1024 * 1024 * 64;
+        size_t count = 0;
+        while (cursor != &mouth) {
+            if (cursor->prev != prev) {
+                assert(0 && "Node busted previous link");
+            }
+            prev = cursor;
+            cursor = cursor->next;
+            if (count++ > max) {
+                assert(0 && "LRU cache unable to re-reach the mouth - not circularly linked?");
+            }
+        }
+        if (mouth.prev != prev) {
+            assert(0 && "mouth.prev does not connect to last node");
+        }
+        if (count != expected_count) {
+            assert(0 && "Linked list count mismatch from map count");
+        }
+
+        // Count iterators
+        size_t iter_dist = 0;
+        for (const auto &p : *this) {
+            iter_dist++;
+        }
+        if (iter_dist != count) {
+            assert(0 && "Linked list iterator mismatch from map count");
+        }
+    }
 };
 
 #endif
diff --git a/src/output.cpp b/src/output.cpp
index 707a922aa..061b8dff9 100644
--- a/src/output.cpp
+++ b/src/output.cpp
@@ -79,9 +79,9 @@ static bool write_color_escape(char *todo, unsigned char idx, bool is_fg) {
         // with what we do here, will make the brights actually work for virtual consoles/ancient
         // emulators.
         if (max_colors == 8 && idx > 8) idx -= 8;
-        snprintf(buff, sizeof buff, "\x1b[%dm", ((idx > 7) ? 82 : 30) + idx + !is_fg * 10);
+        snprintf(buff, sizeof buff, "\e[%dm", ((idx > 7) ? 82 : 30) + idx + !is_fg * 10);
     } else {
-        snprintf(buff, sizeof buff, "\x1b[%d;5;%dm", is_fg ? 38 : 48, idx);
+        snprintf(buff, sizeof buff, "\e[%d;5;%dm", is_fg ? 38 : 48, idx);
     }
 
     int (*writer)(char) = output_get_writer();
@@ -127,7 +127,7 @@ bool write_color(rgb_color_t color, bool is_fg) {
     // Background: ^[48;2;;;m
     color24_t rgb = color.to_color24();
     char buff[128];
-    snprintf(buff, sizeof buff, "\x1b[%d;2;%u;%u;%um", is_fg ? 38 : 48, rgb.rgb[0], rgb.rgb[1],
+    snprintf(buff, sizeof buff, "\e[%d;2;%u;%u;%um", is_fg ? 38 : 48, rgb.rgb[0], rgb.rgb[1],
              rgb.rgb[2]);
     int (*writer)(char) = output_get_writer();
     if (writer) {
@@ -173,9 +173,15 @@ void set_color(rgb_color_t c, rgb_color_t c2) {
     static rgb_color_t last_color2 = rgb_color_t::normal();
     static bool was_bold = false;
     static bool was_underline = false;
+    static bool was_italics = false;
+    static bool was_dim = false;
+    static bool was_reverse = false;
     bool bg_set = false, last_bg_set = false;
     bool is_bold = false;
     bool is_underline = false;
+    bool is_italics = false;
+    bool is_dim = false;
+    bool is_reverse = false;
 
     // Test if we have at least basic support for setting fonts, colors and related bits - otherwise
     // just give up...
@@ -189,10 +195,22 @@ void set_color(rgb_color_t c, rgb_color_t c2) {
     is_underline |= c.is_underline();
     is_underline |= c2.is_underline();
 
+    is_italics |= c.is_italics();
+    is_italics |= c2.is_italics();
+
+    is_dim |= c.is_dim();
+    is_dim |= c2.is_dim();
+
+    is_reverse |= c.is_reverse();
+    is_reverse |= c2.is_reverse();
+
     if (c.is_reset() || c2.is_reset()) {
         c = c2 = normal;
         was_bold = false;
         was_underline = false;
+        was_italics = false;
+        was_dim = false;
+        was_reverse = false;
         // If we exit attibute mode, we must first set a color, or previously coloured text might
         // lose it's color. Terminals are weird...
         write_foreground_color(0);
@@ -207,6 +225,33 @@ void set_color(rgb_color_t c, rgb_color_t c2) {
         last_color2 = normal;
         was_bold = false;
         was_underline = false;
+        was_italics = false;
+        was_dim = false;
+        was_reverse = false;
+    }
+
+    if (was_dim && !is_dim) {
+        // Only way to exit dim mode is a reset of all attributes.
+        writembs(exit_attribute_mode);
+        last_color = normal;
+        last_color2 = normal;
+        was_bold = false;
+        was_underline = false;
+        was_italics = false;
+        was_dim = false;
+        was_reverse = false;
+    }
+
+    if (was_reverse && !is_reverse) {
+        // Only way to exit reverse mode is a reset of all attributes.
+        writembs(exit_attribute_mode);
+        last_color = normal;
+        last_color2 = normal;
+        was_bold = false;
+        was_underline = false;
+        was_italics = false;
+        was_dim = false;
+        was_reverse = false;
     }
 
     if (!last_color2.is_normal() && !last_color2.is_reset()) {
@@ -231,6 +276,9 @@ void set_color(rgb_color_t c, rgb_color_t c2) {
             writembs(exit_attribute_mode);
             was_bold = false;
             was_underline = false;
+            was_italics = false;
+            was_dim = false;
+            was_reverse = false;
             // We don't know if exit_attribute_mode resets colors, so we set it to something known.
             if (write_foreground_color(0)) {
                 last_color = rgb_color_t::black();
@@ -246,6 +294,9 @@ void set_color(rgb_color_t c, rgb_color_t c2) {
             last_color2 = rgb_color_t::normal();
             was_bold = false;
             was_underline = false;
+            was_italics = false;
+            was_dim = false;
+            was_reverse = false;
         } else if (!c.is_special()) {
             write_color(c, true /* foreground */);
         }
@@ -264,6 +315,9 @@ void set_color(rgb_color_t c, rgb_color_t c2) {
 
             was_bold = false;
             was_underline = false;
+            was_italics = false;
+            was_dim = false;
+            was_reverse = false;
             last_color2 = c2;
         } else if (!c2.is_special()) {
             write_color(c2, false /* not foreground */);
@@ -271,7 +325,7 @@ void set_color(rgb_color_t c, rgb_color_t c2) {
         }
     }
 
-    // Lastly, we set bold mode and underline mode correctly.
+    // Lastly, we set bold, underline, italics, dim, and reverse modes correctly.
     if (is_bold && !was_bold && enter_bold_mode && strlen(enter_bold_mode) > 0 && !bg_set) {
         writembs(tparm(enter_bold_mode));
         was_bold = is_bold;
@@ -285,6 +339,32 @@ void set_color(rgb_color_t c, rgb_color_t c2) {
         writembs(enter_underline_mode);
     }
     was_underline = is_underline;
+
+    if (was_italics && !is_italics && enter_italics_mode && strlen(enter_italics_mode) > 0) {
+        writembs(exit_italics_mode);
+        was_italics = is_italics;
+    }
+
+    if (!was_italics && is_italics && enter_italics_mode && strlen(enter_italics_mode) > 0) {
+        writembs(enter_italics_mode);
+        was_italics = is_italics;
+    }
+
+    if (is_dim && !was_dim && enter_dim_mode && strlen(enter_dim_mode) > 0) {
+        writembs(enter_dim_mode);
+        was_dim = is_dim;
+    }
+
+    if (is_reverse && !was_reverse) {
+        // Some terms do not have a reverse mode set, so standout mode is a fallback.
+        if (enter_reverse_mode && strlen(enter_reverse_mode) > 0) {
+            writembs(enter_reverse_mode);
+            was_reverse = is_reverse;
+        } else if (enter_standout_mode && strlen(enter_standout_mode) > 0) {
+            writembs(enter_standout_mode);
+            was_reverse = is_reverse;
+        }
+    }
 }
 
 /// Default output method, simply calls write() on stdout.
@@ -301,7 +381,11 @@ int writeb(tputs_arg_t b) {
     return 0;
 }
 
-/// Write a wide character using the output method specified using output_set_writer().
+/// Write a wide character using the output method specified using output_set_writer(). This should
+/// only be used when writing characters from user supplied strings. This is needed due to our use
+/// of the ENCODE_DIRECT_BASE mechanism to allow the user to specify arbitrary byte values to be
+/// output. Such as in a `printf` invocation that includes literal byte values such as `\x1B`.
+/// This should not be used for writing non-user supplied characters.
 int writech(wint_t ch) {
     char buff[MB_LEN_MAX + 1];
     size_t len;
@@ -328,15 +412,16 @@ int writech(wint_t ch) {
     return 0;
 }
 
-/// Write a wide character string to FD 1.
+/// Write a wide character string to stdout. This should not be used to output things like warning
+/// messages; just use debug() or fwprintf() for that. It should only be used to output user
+/// supplied strings that might contain literal bytes; e.g., "\342\224\214" from issue #1894. This
+/// is needed because those strings may contain chars specially encoded using ENCODE_DIRECT_BASE.
 void writestr(const wchar_t *str) {
     CHECK(str, );
 
-    if (MB_CUR_MAX == 1)  // single-byte locale (C/POSIX/ISO-8859)
-    {
-        while (*str) {
-            writech(*str++);
-        }
+    if (MB_CUR_MAX == 1) {
+        // Single-byte locale (C/POSIX/ISO-8859).
+        while (*str) writech(*str++);
         return;
     }
 
@@ -349,11 +434,11 @@ void writestr(const wchar_t *str) {
     // Convert the string.
     len++;
     char *buffer, static_buffer[256];
-    if (len <= sizeof static_buffer)
+    if (len <= sizeof static_buffer) {
         buffer = static_buffer;
-    else
+    } else {
         buffer = new char[len];
-
+    }
     wcstombs(buffer, str, len);
 
     // Write the string.
@@ -400,6 +485,9 @@ rgb_color_t best_color(const std::vector &candidates, color_support
 rgb_color_t parse_color(const wcstring &val, bool is_background) {
     int is_bold = 0;
     int is_underline = 0;
+    int is_italics = 0;
+    int is_dim = 0;
+    int is_reverse = 0;
 
     std::vector candidates;
 
@@ -420,6 +508,12 @@ rgb_color_t parse_color(const wcstring &val, bool is_background) {
                 is_bold = true;
             else if (next == L"--underline" || next == L"-u")
                 is_underline = true;
+            else if (next == L"--italics" || next == L"-i")
+                is_italics = true;
+            else if (next == L"--dim" || next == L"-d")
+                is_dim = true;
+            else if (next == L"--reverse" || next == L"-r")
+                is_reverse = true;
             else
                 color_name = next;
         }
@@ -437,11 +531,14 @@ rgb_color_t parse_color(const wcstring &val, bool is_background) {
 
     result.set_bold(is_bold);
     result.set_underline(is_underline);
+    result.set_italics(is_italics);
+    result.set_dim(is_dim);
+    result.set_reverse(is_reverse);
 
 #if 0
     wcstring desc = result.description();
-    printf("Parsed %ls from %ls (%s)\n", desc.c_str(), val.c_str(),
-           is_background ? "background" : "foreground");
+    fwprintf(stdout, L"Parsed %ls from %ls (%s)\n", desc.c_str(), val.c_str(),
+             is_background ? "background" : "foreground");
 #endif
 
     return result;
diff --git a/src/pager.cpp b/src/pager.cpp
index 4a952c205..70373b0af 100644
--- a/src/pager.cpp
+++ b/src/pager.cpp
@@ -3,10 +3,10 @@
 // IWYU pragma: no_include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "common.h"
@@ -26,6 +26,9 @@ typedef std::vector comp_info_list_t;
 /// The minimum width (in characters) the terminal must to show completions at all.
 #define PAGER_MIN_WIDTH 16
 
+/// Minimum height to show completions
+#define PAGER_MIN_HEIGHT 4
+
 /// The maximum number of columns of completion to attempt to fit onto the screen.
 #define PAGER_MAX_COLS 6
 
@@ -44,17 +47,6 @@ static size_t divide_round_up(size_t numer, size_t denom) {
     return numer / denom + (has_rem ? 1 : 0);
 }
 
-/// This function calculates the minimum width for each completion entry in the specified
-/// array_list. This width depends on the terminal size, so this function should be called when the
-/// terminal changes size.
-void pager_t::recalc_min_widths(comp_info_list_t *lst) const {
-    for (size_t i = 0; i < lst->size(); i++) {
-        comp_t *c = &lst->at(i);
-        c->min_width = mini(c->desc_width, maxi((size_t)0, available_term_width / 3 - 2)) +
-                       mini(c->desc_width, maxi((size_t)0, available_term_width / 5 - 4)) + 4;
-    }
-}
-
 /// Print the specified string, but use at most the specified amount of space. If the whole string
 /// can't be fitted, ellipsize it.
 ///
@@ -62,47 +54,68 @@ void pager_t::recalc_min_widths(comp_info_list_t *lst) const {
 /// \param color the color to apply to every printed character
 /// \param max the maximum space that may be used for printing
 /// \param has_more if this flag is true, this is not the entire string, and the string should be
-/// ellisiszed even if the string fits but takes up the whole space.
-static int print_max(const wcstring &str, highlight_spec_t color, int max, bool has_more,
-                     line_t *line) {
-    int written = 0;
+/// ellipsized even if the string fits but takes up the whole space.
+static size_t print_max(const wcstring &str, highlight_spec_t color, size_t max, bool has_more,
+                        line_t *line) {
+    size_t remaining = max;
     for (size_t i = 0; i < str.size(); i++) {
         wchar_t c = str.at(i);
+        int iwidth_c = fish_wcwidth(c);
+        if (iwidth_c < 0) {
+            // skip non-printable characters
+            continue;
+        }
+        size_t width_c = size_t(iwidth_c);
 
-        if (written + fish_wcwidth(c) > max) break;
-        if ((written + fish_wcwidth(c) == max) && (has_more || i + 1 < str.size())) {
+        if (width_c > remaining) break;
+
+        if ((width_c == remaining) && (has_more || i + 1 < str.size())) {
             line->append(ellipsis_char, color);
-            written += fish_wcwidth(ellipsis_char);
+            int ellipsis_width = fish_wcwidth(ellipsis_char);
+            remaining -= std::min(remaining, size_t(ellipsis_width));
             break;
         }
 
         line->append(c, color);
-        written += fish_wcwidth(c);
+        assert(remaining >= width_c);
+        remaining -= width_c;
     }
-    return written;
+
+    // return how much we consumed
+    assert(remaining <= max);
+    return max - remaining;
 }
 
 /// Print the specified item using at the specified amount of space.
 line_t pager_t::completion_print_item(const wcstring &prefix, const comp_t *c, size_t row,
-                                      size_t column, int width, bool secondary, bool selected,
+                                      size_t column, size_t width, bool secondary, bool selected,
                                       page_rendering_t *rendering) const {
     UNUSED(column);
     UNUSED(row);
     UNUSED(rendering);
-    int comp_width, desc_width;
+    size_t comp_width, desc_width;
     line_t line_data;
 
-    if (c->pref_width <= width) {
+    if (c->preferred_width() <= width) {
         // The entry fits, we give it as much space as it wants.
         comp_width = c->comp_width;
         desc_width = c->desc_width;
     } else {
         // The completion and description won't fit on the allocated space. Give a maximum of 2/3 of
-        // the space to the completion, and whatever is left to the description.
-        int desc_all = c->desc_width ? c->desc_width + 4 : 0;
+        // the space to the completion, and whatever is left to the description
+        // This expression is an overflow-safe way of calculating (width-4)*2/3
+        size_t width_minus_spacer = width - std::min(width, size_t(4));
+        size_t two_thirds_width = (width_minus_spacer / 3) * 2 + ((width_minus_spacer % 3) * 2) / 3;
+        comp_width = std::min(c->comp_width, two_thirds_width);
 
-        comp_width = maxi(mini((int)c->comp_width, 2 * (width - 4) / 3), width - desc_all);
-        desc_width = c->desc_width ? width - 4 - comp_width : 0;
+        // If the description is short, give the completion the remaining space
+        size_t desc_punct_width = c->description_punctuated_width();
+        if (width > desc_punct_width) {
+            comp_width = std::max(comp_width, width - desc_punct_width);
+        }
+
+        // The description gets what's left
+        assert(comp_width <= width);
     }
 
     int bg_color = secondary ? highlight_spec_pager_secondary : highlight_spec_normal;
@@ -110,38 +123,48 @@ line_t pager_t::completion_print_item(const wcstring &prefix, const comp_t *c, s
         bg_color = highlight_spec_search_match;
     }
 
-    int written = 0;
+    // Print the completion part
+    size_t comp_remaining = comp_width;
     for (size_t i = 0; i < c->comp.size(); i++) {
         const wcstring &comp = c->comp.at(i);
+        if (i > 0) {
+            comp_remaining -= print_max(PAGER_SPACER_STRING, highlight_spec_normal, comp_remaining,
+                                        true /* has_more */, &line_data);
+        }
 
-        if (i != 0)
-            written += print_max(PAGER_SPACER_STRING, highlight_spec_normal, comp_width - written,
-                                 true /* has_more */, &line_data);
-
-        int packed_color = highlight_spec_pager_prefix | highlight_make_background(bg_color);
-        written += print_max(prefix, packed_color, comp_width - written, !comp.empty(), &line_data);
+        highlight_spec_t packed_color =
+            highlight_spec_pager_prefix | highlight_make_background(bg_color);
+        comp_remaining -=
+            print_max(prefix, packed_color, comp_remaining, !comp.empty(), &line_data);
 
         packed_color = highlight_spec_pager_completion | highlight_make_background(bg_color);
-        written +=
-            print_max(comp, packed_color, comp_width - written, i + 1 < c->comp.size(), &line_data);
+        comp_remaining -=
+            print_max(comp, packed_color, comp_remaining, i + 1 < c->comp.size(), &line_data);
     }
 
-    if (desc_width) {
-        int packed_color = highlight_spec_pager_description | highlight_make_background(bg_color);
-        while (written < (width - desc_width - 2))  // the 2 here refers to the parenthesis below
-        {
-            written += print_max(L" ", packed_color, 1, false, &line_data);
+    size_t desc_remaining = width - comp_width + comp_remaining;
+    if (c->desc_width > 0 && desc_remaining > 4) {
+        highlight_spec_t desc_color =
+            highlight_spec_pager_description | highlight_make_background(bg_color);
+        highlight_spec_t punct_color =
+            highlight_spec_pager_completion | highlight_make_background(bg_color);
+
+        // always have at least two spaces to separate completion and description
+        desc_remaining -= print_max(L"  ", punct_color, 2, false, &line_data);
+
+        // right-justify the description by adding spaces
+        // the 2 here refers to the parenthesis below
+        while (desc_remaining > c->desc_width + 2) {
+            desc_remaining -= print_max(L" ", punct_color, 1, false, &line_data);
         }
-        // hack - this just works around the issue
-        print_max(L"(", highlight_spec_pager_completion | highlight_make_background(bg_color), 1,
-                  false, &line_data);
-        print_max(c->desc, packed_color, desc_width, false, &line_data);
-        print_max(L")", highlight_spec_pager_completion | highlight_make_background(bg_color), 1,
-                  false, &line_data);
+
+        assert(desc_remaining >= 2);
+        desc_remaining -= print_max(L"(", punct_color, 1, false, &line_data);
+        desc_remaining -= print_max(c->desc, desc_color, desc_remaining - 1, false, &line_data);
+        desc_remaining -= print_max(L")", punct_color, 1, false, &line_data);
     } else {
-        while (written < width) {
-            written += print_max(L" ", 0, 1, false, &line_data);
-        }
+        // No description, or it won't fit. Just add spaces.
+        print_max(wcstring(desc_remaining, L' '), 0, desc_remaining, false, &line_data);
     }
 
     return line_data;
@@ -151,28 +174,25 @@ line_t pager_t::completion_print_item(const wcstring &prefix, const comp_t *c, s
 /// style.
 ///
 /// \param cols number of columns to print in
-/// \param width_per_column An array specifying the width of each column
+/// \param width_by_column An array specifying the width of each column
 /// \param row_start The first row to print
 /// \param row_stop the row after the last row to print
 /// \param prefix The string to print before each completion
 /// \param lst The list of completions to print
-void pager_t::completion_print(size_t cols, int *width_per_column, size_t row_start,
+void pager_t::completion_print(size_t cols, const size_t *width_by_column, size_t row_start,
                                size_t row_stop, const wcstring &prefix, const comp_info_list_t &lst,
                                page_rendering_t *rendering) const {
     // Teach the rendering about the rows it printed.
-    assert(row_start >= 0);
     assert(row_stop >= row_start);
     rendering->row_start = row_start;
     rendering->row_end = row_stop;
 
-    size_t rows = (lst.size() - 1) / cols + 1;
+    size_t rows = divide_round_up(lst.size(), cols);
 
     size_t effective_selected_idx = this->visual_selected_completion_index(rows, cols);
 
     for (size_t row = row_start; row < row_stop; row++) {
         for (size_t col = 0; col < cols; col++) {
-            int is_last = (col == (cols - 1));
-
             if (lst.size() <= col * rows + row) continue;
 
             size_t idx = col * rows + row;
@@ -180,10 +200,8 @@ void pager_t::completion_print(size_t cols, int *width_per_column, size_t row_st
             bool is_selected = (idx == effective_selected_idx);
 
             // Print this completion on its own "line".
-            line_t line = completion_print_item(
-                prefix, el, row, col,
-                width_per_column[col] - (is_last ? 0 : PAGER_SPACER_STRING_WIDTH), row % 2,
-                is_selected, rendering);
+            line_t line = completion_print_item(prefix, el, row, col, width_by_column[col], row % 2,
+                                                is_selected, rendering);
 
             // If there's more to come, append two spaces.
             if (col + 1 < cols) {
@@ -294,12 +312,7 @@ void pager_t::measure_completion_infos(comp_info_list_t *infos, const wcstring &
 
         // Compute desc_width.
         comp->desc_width = fish_wcswidth(comp->desc.c_str());
-
-        // Compute preferred width.
-        comp->pref_width = comp->comp_width + comp->desc_width + (comp->desc_width ? 4 : 0);
     }
-
-    recalc_min_widths(infos);
 }
 
 // Indicates if the given completion info passes any filtering we have.
@@ -360,23 +373,21 @@ void pager_t::set_term_size(int w, int h) {
     assert(h > 0);
     available_term_width = w;
     available_term_height = h;
-    recalc_min_widths(&completion_infos);
 }
 
-/// Try to print the list of completions l with the prefix prefix using cols as the number of
+/// Try to print the list of completions lst with the prefix prefix using cols as the number of
 /// columns. Return true if the completion list was printed, false if the terminal is too narrow for
 /// the specified number of columns. Always succeeds if cols is 1.
 bool pager_t::completion_try_print(size_t cols, const wcstring &prefix, const comp_info_list_t &lst,
                                    page_rendering_t *rendering, size_t suggested_start_row) const {
+    assert(cols > 0);
     // The calculated preferred width of each column.
-    int pref_width[PAGER_MAX_COLS] = {0};
-    // The calculated minimum width of each column.
-    int min_width[PAGER_MAX_COLS] = {0};
-    // If the list can be printed with this width, width will contain the width of each column.
-    int *width = pref_width;
+    size_t width_by_column[PAGER_MAX_COLS] = {0};
 
-    // Set to one if the list should be printed at this width.
-    bool print = false;
+    // Skip completions on tiny terminals.
+    if (this->available_term_width < PAGER_MIN_WIDTH ||
+        this->available_term_height < PAGER_MIN_HEIGHT)
+        return true;
 
     // Compute the effective term width and term height, accounting for disclosure.
     size_t term_width = this->available_term_width;
@@ -399,52 +410,34 @@ bool pager_t::completion_try_print(size_t cols, const wcstring &prefix, const co
 
     // If we have only one row remaining to disclose, then squelch the comment row. This prevents us
     // from consuming a line to show "...and 1 more row".
-    if (!this->fully_disclosed && rendering->remaining_to_disclose == 1) {
+    if (rendering->remaining_to_disclose == 1) {
         term_height += 1;
         rendering->remaining_to_disclose = 0;
     }
 
-    size_t pref_tot_width = 0;
-    size_t min_tot_width = 0;
-
-    // Skip completions on tiny terminals.
-    if (term_width < PAGER_MIN_WIDTH) return true;
-
     // Calculate how wide the list would be.
     for (size_t col = 0; col < cols; col++) {
         for (size_t row = 0; row < row_count; row++) {
-            int pref, min;
-            const comp_t *c;
-            if (lst.size() <= col * row_count + row) continue;
-
-            c = &lst.at(col * row_count + row);
-            pref = c->pref_width;
-            min = c->min_width;
-
-            if (col != cols - 1) {
-                pref += 2;
-                min += 2;
-            }
-            min_width[col] = maxi(min_width[col], min);
-            pref_width[col] = maxi(pref_width[col], pref);
+            const size_t comp_idx = col * row_count + row;
+            if (comp_idx >= lst.size()) continue;
+            const comp_t &c = lst.at(comp_idx);
+            width_by_column[col] = std::max(width_by_column[col], c.preferred_width());
         }
-        min_tot_width += min_width[col];
-        pref_tot_width += pref_width[col];
     }
 
+    bool print;
+    assert(cols >= 1);
     // Force fit if one column.
     if (cols == 1) {
-        if (pref_tot_width > term_width) {
-            pref_width[0] = term_width;
-        }
-        width = pref_width;
-        print = true;
-    } else if (pref_tot_width <= term_width) {
-        // Terminal is wide enough. Print the list!
-        width = pref_width;
+        width_by_column[0] = std::min(width_by_column[0], term_width);
         print = true;
+    } else {
+        // Compute total preferred width, plus spacing
+        assert(cols > 0);
+        size_t total_width_needed = std::accumulate(width_by_column, width_by_column + cols, 0);
+        total_width_needed += (cols - 1) * PAGER_SPACER_STRING_WIDTH;
+        print = (total_width_needed <= term_width);
     }
-
     if (!print) {
         return false;  // no need to continue
     }
@@ -462,24 +455,23 @@ bool pager_t::completion_try_print(size_t cols, const wcstring &prefix, const co
         size_t last_starting_row = row_count - term_height;
         start_row = mini(suggested_start_row, last_starting_row);
         stop_row = start_row + term_height;
-        assert(start_row >= 0 && start_row <= last_starting_row);
+        assert(start_row <= last_starting_row);
     }
 
     assert(stop_row >= start_row);
     assert(stop_row <= row_count);
     assert(stop_row - start_row <= term_height);
-    completion_print(cols, width, start_row, stop_row, prefix, lst, rendering);
+    completion_print(cols, width_by_column, start_row, stop_row, prefix, lst, rendering);
 
     // Ellipsis helper string. Either empty or containing the ellipsis char.
     const wchar_t ellipsis_string[] = {ellipsis_char == L'\x2026' ? L'\x2026' : L'\0', L'\0'};
 
     // Add the progress line. It's a "more to disclose" line if necessary, or a row listing if
     // it's scrollable; otherwise ignore it.
+    // We should never have one row remaining to disclose (else we would have just disclosed it)
     wcstring progress_text;
-    if (rendering->remaining_to_disclose == 1) {
-        // I don't expect this case to ever happen.
-        progress_text = format_string(_(L"%lsand 1 more row"), ellipsis_string);
-    } else if (rendering->remaining_to_disclose > 1) {
+    assert(rendering->remaining_to_disclose != 1);
+    if (rendering->remaining_to_disclose > 1) {
         progress_text = format_string(_(L"%lsand %lu more rows"), ellipsis_string,
                                       (unsigned long)rendering->remaining_to_disclose);
     } else if (start_row > 0 || stop_row < row_count) {
@@ -495,9 +487,9 @@ bool pager_t::completion_try_print(size_t cols, const wcstring &prefix, const co
 
     if (!progress_text.empty()) {
         line_t &line = rendering->screen_data.add_line();
-        print_max(progress_text, highlight_spec_pager_progress |
-                                     highlight_make_background(highlight_spec_pager_progress),
-                  term_width, true /* has_more */, &line);
+        highlight_spec_t spec = highlight_spec_pager_progress |
+                                highlight_make_background(highlight_spec_pager_progress);
+        print_max(progress_text, spec, term_width, true /* has_more */, &line);
     }
 
     if (search_field_shown) {
@@ -510,10 +502,12 @@ bool pager_t::completion_try_print(size_t cols, const wcstring &prefix, const co
         line_t *search_field = &rendering->screen_data.insert_line_at_index(0);
 
         // We limit the width to term_width - 1.
-        int search_field_written = print_max(SEARCH_FIELD_PROMPT, highlight_spec_normal,
-                                             term_width - 1, false, search_field);
-        print_max(search_field_text, highlight_modifier_force_underline,
-                  term_width - search_field_written - 1, false, search_field);
+        size_t search_field_remaining = term_width - 1;
+        search_field_remaining -= print_max(SEARCH_FIELD_PROMPT, highlight_spec_normal,
+                                            search_field_remaining, false, search_field);
+
+        search_field_remaining -= print_max(search_field_text, highlight_modifier_force_underline,
+                                            search_field_remaining, false, search_field);
     }
 
     return true;
diff --git a/src/pager.h b/src/pager.h
index 1376e51e7..74b9e9ce0 100644
--- a/src/pager.h
+++ b/src/pager.h
@@ -43,8 +43,6 @@ class page_rendering_t {
 #define PAGER_UNDISCLOSED_MAX_ROWS 4
 
 typedef std::vector completion_list_t;
-page_rendering_t render_completions(const completion_list_t &raw_completions,
-                                    const wcstring &prefix);
 
 class pager_t {
     size_t available_term_width;
@@ -76,19 +74,24 @@ class pager_t {
         size_t comp_width;
         /// On-screen width of the description information.
         size_t desc_width;
-        /// Preferred total width.
-        size_t pref_width;
         /// Minimum acceptable width.
-        size_t min_width;
+        // size_t min_width;
 
-        comp_t()
-            : comp(),
-              desc(),
-              representative(L""),
-              comp_width(0),
-              desc_width(0),
-              pref_width(0),
-              min_width(0) {}
+        comp_t() : comp(), desc(), representative(L""), comp_width(0), desc_width(0) {}
+
+        // Our text looks like this:
+        // completion  (description)
+        // Two spaces separating, plus parens, yields 4 total extra space
+        // but only if we have a description of course
+        size_t description_punctuated_width() const {
+            return this->desc_width + (this->desc_width ? 4 : 0);
+        }
+
+        // Returns the preferred width, containing the sum of the
+        // width of the completion, separator, description
+        size_t preferred_width() const {
+            return this->comp_width + this->description_punctuated_width();
+        }
     };
 
    private:
@@ -110,11 +113,11 @@ class pager_t {
 
     bool completion_info_passes_filter(const comp_t &info) const;
 
-    void completion_print(size_t cols, int *width_per_column, size_t row_start, size_t row_stop,
-                          const wcstring &prefix, const comp_info_list_t &lst,
+    void completion_print(size_t cols, const size_t *width_per_column, size_t row_start,
+                          size_t row_stop, const wcstring &prefix, const comp_info_list_t &lst,
                           page_rendering_t *rendering) const;
     line_t completion_print_item(const wcstring &prefix, const comp_t *c, size_t row, size_t column,
-                                 int width, bool secondary, bool selected,
+                                 size_t width, bool secondary, bool selected,
                                  page_rendering_t *rendering) const;
 
    public:
diff --git a/src/parse_constants.h b/src/parse_constants.h
index 2ee6287b7..72b1a0089 100644
--- a/src/parse_constants.h
+++ b/src/parse_constants.h
@@ -2,20 +2,19 @@
 #ifndef FISH_PARSE_CONSTANTS_H
 #define FISH_PARSE_CONSTANTS_H
 
+#include "common.h"
 #include "config.h"
 
 #define PARSE_ASSERT(a) assert(a)
-#define PARSER_DIE()                        \
-    do {                                    \
-        fprintf(stderr, "Parser dying!\n"); \
-        exit_without_destructors(-1);       \
+#define PARSER_DIE()                  \
+    do {                              \
+        debug(0, "Parser dying!");    \
+        exit_without_destructors(-1); \
     } while (0)
 
-// IMPORTANT: If the following enum is modified you must update the corresponding parser_token_types
-// array in parse_tree.cpp.
+// IMPORTANT: If the following enum table is modified you must also update token_enum_map below.
 enum parse_token_type_t {
-    token_type_invalid,
-
+    token_type_invalid = 1,
     // Non-terminal tokens
     symbol_job_list,
     symbol_job,
@@ -27,71 +26,97 @@ enum parse_token_type_t {
     symbol_while_header,
     symbol_begin_header,
     symbol_function_header,
-
     symbol_if_statement,
     symbol_if_clause,
     symbol_else_clause,
     symbol_else_continuation,
-
     symbol_switch_statement,
     symbol_case_item_list,
     symbol_case_item,
-
     symbol_boolean_statement,
     symbol_decorated_statement,
     symbol_plain_statement,
     symbol_arguments_or_redirections_list,
     symbol_argument_or_redirection,
-
     symbol_andor_job_list,
-
     symbol_argument_list,
-
-    // Freestanding argument lists are parsed from the argument list supplied to 'complete -a'
+    // Freestanding argument lists are parsed from the argument list supplied to 'complete -a'.
     // They are not generated by parse trees rooted in symbol_job_list.
     symbol_freestanding_argument_list,
-
     symbol_argument,
     symbol_redirection,
-
     symbol_optional_background,
-
     symbol_end_command,
-
     // Terminal types.
     parse_token_type_string,
     parse_token_type_pipe,
     parse_token_type_redirection,
     parse_token_type_background,
     parse_token_type_end,
-
     // Special terminal type that means no more tokens forthcoming.
     parse_token_type_terminate,
-
     // Very special terminal types that don't appear in the production list.
     parse_special_type_parse_error,
     parse_special_type_tokenizer_error,
     parse_special_type_comment,
-    LAST_TOKEN_TYPE = parse_special_type_comment,
 
+    LAST_TOKEN_TYPE = parse_special_type_comment,
     FIRST_TERMINAL_TYPE = parse_token_type_string,
     LAST_TERMINAL_TYPE = parse_token_type_terminate,
-
     LAST_TOKEN_OR_SYMBOL = parse_token_type_terminate,
-
     FIRST_PARSE_TOKEN_TYPE = parse_token_type_string,
     LAST_PARSE_TOKEN_TYPE = parse_token_type_end
 } __packed;
-// Array of strings corresponding to the enums above instantiated in parse_tree.cpp.
-extern const wchar_t *const parser_token_types[];
 
-// These must be maintained in sorted order (except for none, which isn't a keyword). This enables
-// us to do binary search.
+const enum_map token_enum_map[] = {
+    {parse_special_type_comment, L"parse_special_type_comment"},
+    {parse_special_type_parse_error, L"parse_special_type_parse_error"},
+    {parse_special_type_tokenizer_error, L"parse_special_type_tokenizer_error"},
+    {parse_token_type_background, L"parse_token_type_background"},
+    {parse_token_type_end, L"parse_token_type_end"},
+    {parse_token_type_pipe, L"parse_token_type_pipe"},
+    {parse_token_type_redirection, L"parse_token_type_redirection"},
+    {parse_token_type_string, L"parse_token_type_string"},
+    {parse_token_type_terminate, L"parse_token_type_terminate"},
+    {symbol_andor_job_list, L"symbol_andor_job_list"},
+    {symbol_argument, L"symbol_argument"},
+    {symbol_argument_list, L"symbol_argument_list"},
+    {symbol_argument_or_redirection, L"symbol_argument_or_redirection"},
+    {symbol_arguments_or_redirections_list, L"symbol_arguments_or_redirections_list"},
+    {symbol_begin_header, L"symbol_begin_header"},
+    {symbol_block_header, L"symbol_block_header"},
+    {symbol_block_statement, L"symbol_block_statement"},
+    {symbol_boolean_statement, L"symbol_boolean_statement"},
+    {symbol_case_item, L"symbol_case_item"},
+    {symbol_case_item_list, L"symbol_case_item_list"},
+    {symbol_decorated_statement, L"symbol_decorated_statement"},
+    {symbol_else_clause, L"symbol_else_clause"},
+    {symbol_else_continuation, L"symbol_else_continuation"},
+    {symbol_end_command, L"symbol_end_command"},
+    {symbol_for_header, L"symbol_for_header"},
+    {symbol_freestanding_argument_list, L"symbol_freestanding_argument_list"},
+    {symbol_function_header, L"symbol_function_header"},
+    {symbol_if_clause, L"symbol_if_clause"},
+    {symbol_if_statement, L"symbol_if_statement"},
+    {symbol_job, L"symbol_job"},
+    {symbol_job_continuation, L"symbol_job_continuation"},
+    {symbol_job_list, L"symbol_job_list"},
+    {symbol_optional_background, L"symbol_optional_background"},
+    {symbol_plain_statement, L"symbol_plain_statement"},
+    {symbol_redirection, L"symbol_redirection"},
+    {symbol_statement, L"symbol_statement"},
+    {symbol_switch_statement, L"symbol_switch_statement"},
+    {symbol_while_header, L"symbol_while_header"},
+    {token_type_invalid, L"token_type_invalid"},
+    {token_type_invalid, NULL}};
+#define token_enum_map_len (sizeof token_enum_map / sizeof *token_enum_map)
+
+// IMPORTANT: If the following enum is modified you must update the corresponding keyword_enum_map
+// array below.
 //
-// IMPORTANT: If the following enum is modified you must update the corresponding keyword_map array
-// in parse_tree.cpp.
+// IMPORTANT: These enums must start at zero.
 enum parse_keyword_t {
-    parse_keyword_none,
+    parse_keyword_none = 0,
     parse_keyword_and,
     parse_keyword_begin,
     parse_keyword_builtin,
@@ -108,9 +133,20 @@ enum parse_keyword_t {
     parse_keyword_or,
     parse_keyword_switch,
     parse_keyword_while,
-    LAST_KEYWORD = parse_keyword_while
 } __packed;
 
+const enum_map keyword_enum_map[] = {
+    {parse_keyword_and, L"and"},         {parse_keyword_begin, L"begin"},
+    {parse_keyword_builtin, L"builtin"}, {parse_keyword_case, L"case"},
+    {parse_keyword_command, L"command"}, {parse_keyword_else, L"else"},
+    {parse_keyword_end, L"end"},         {parse_keyword_exec, L"exec"},
+    {parse_keyword_for, L"for"},         {parse_keyword_function, L"function"},
+    {parse_keyword_if, L"if"},           {parse_keyword_in, L"in"},
+    {parse_keyword_not, L"not"},         {parse_keyword_or, L"or"},
+    {parse_keyword_switch, L"switch"},   {parse_keyword_while, L"while"},
+    {parse_keyword_none, NULL}};
+#define keyword_enum_map_len (sizeof keyword_enum_map / sizeof *keyword_enum_map)
+
 // Node tag values.
 
 // Statement decorations, stored in node tag.
diff --git a/src/parse_execution.cpp b/src/parse_execution.cpp
index b18514ef2..55110d885 100644
--- a/src/parse_execution.cpp
+++ b/src/parse_execution.cpp
@@ -75,10 +75,9 @@ static wcstring profiling_cmd_name_for_redirectable_block(const parse_node_t &no
     return result;
 }
 
-parse_execution_context_t::parse_execution_context_t(moved_ref t,
-                                                     const wcstring &s, parser_t *p,
-                                                     int initial_eval_level)
-    : tree(t),
+parse_execution_context_t::parse_execution_context_t(parse_node_tree_t t, const wcstring &s,
+                                                     parser_t *p, int initial_eval_level)
+    : tree(std::move(t)),
       src(s),
       parser(p),
       eval_level(initial_eval_level),
@@ -103,7 +102,6 @@ node_offset_t parse_execution_context_t::get_offset(const parse_node_t &node) co
     const parse_node_t *addr = &node;
     const parse_node_t *base = &this->tree.at(0);
     assert(addr >= base);
-    assert(addr - base < SOURCE_OFFSET_INVALID);
     node_offset_t offset = static_cast(addr - base);
     assert(offset < this->tree.size());
     assert(&tree.at(offset) == &node);
@@ -220,13 +218,12 @@ parse_execution_context_t::cancellation_reason(const block_t *block) const {
     if (parser && parser->cancellation_requested) {
         return execution_cancellation_skip;
     }
-    if (block && block->loop_status != LOOP_NORMAL) {
-        // Nasty hack - break and continue set the 'skip' flag as well as the loop status flag.
-        return execution_cancellation_loop_control;
-    }
     if (block && block->skip) {
         return execution_cancellation_skip;
     }
+    if (block && block->loop_status != LOOP_NORMAL) {
+        return execution_cancellation_loop_control;
+    }
     return execution_cancellation_none;
 }
 
@@ -267,9 +264,8 @@ parse_execution_result_t parse_execution_context_t::run_if_statement(
     assert(statement.type == symbol_if_statement);
 
     // Push an if block.
-    if_block_t *ib = new if_block_t();
+    if_block_t *ib = parser->push_block();
     ib->node_offset = this->get_offset(statement);
-    parser->push_block(ib);
 
     parse_execution_result_t result = parse_execution_success;
 
@@ -349,14 +345,9 @@ parse_execution_result_t parse_execution_context_t::run_begin_statement(
     assert(header.type == symbol_begin_header);
     assert(contents.type == symbol_job_list);
 
-    // Basic begin/end block. Push a scope block.
-    scope_block_t *sb = new scope_block_t(BEGIN);
-    parser->push_block(sb);
-
-    // Run the job list.
+    // Basic begin/end block. Push a scope block, run jobs, pop it
+    scope_block_t *sb = parser->push_block(BEGIN);
     parse_execution_result_t ret = run_job_list(contents, sb);
-
-    // Pop the block.
     parser->pop_block(sb);
 
     return ret;
@@ -399,7 +390,7 @@ parse_execution_result_t parse_execution_context_t::run_function_statement(
     wcstring error_str;
     io_streams_t streams;
     int err = builtin_function(*parser, streams, argument_list, contents_str,
-                                definition_line_offset, &error_str);
+                               definition_line_offset, &error_str);
     proc_set_last_status(err);
 
     if (!error_str.empty()) {
@@ -441,7 +432,7 @@ parse_execution_result_t parse_execution_context_t::run_block_statement(
             break;
         }
         default: {
-            fprintf(stderr, "Unexpected block header: %ls\n", header.describe().c_str());
+            debug(0, L"Unexpected block header: %ls\n", header.describe().c_str());
             PARSER_DIE();
             break;
         }
@@ -471,8 +462,7 @@ parse_execution_result_t parse_execution_context_t::run_for_statement(
         return ret;
     }
 
-    for_block_t *fb = new for_block_t();
-    parser->push_block(fb);
+    for_block_t *fb = parser->push_block();
 
     // Now drive the for loop.
     const size_t arg_count = argument_sequence.size();
@@ -485,7 +475,6 @@ parse_execution_result_t parse_execution_context_t::run_for_statement(
         const wcstring &val = argument_sequence.at(i);
         env_set(for_var_name, val.c_str(), ENV_LOCAL);
         fb->loop_status = LOOP_NORMAL;
-        fb->skip = 0;
 
         this->run_job_list(block_contents, fb);
 
@@ -494,7 +483,6 @@ parse_execution_result_t parse_execution_context_t::run_for_statement(
             if (fb->loop_status == LOOP_CONTINUE) {
                 // Reset the loop state.
                 fb->loop_status = LOOP_NORMAL;
-                fb->skip = false;
                 continue;
             } else if (fb->loop_status == LOOP_BREAK) {
                 break;
@@ -555,8 +543,7 @@ parse_execution_result_t parse_execution_context_t::run_switch_statement(
 
     const wcstring &switch_value_expanded = switch_values_expanded.at(0).completion;
 
-    switch_block_t *sb = new switch_block_t();
-    parser->push_block(sb);
+    switch_block_t *sb = parser->push_block();
 
     // Expand case statements.
     const parse_node_t *case_item_list = get_child(statement, 3, symbol_case_item_list);
@@ -619,9 +606,8 @@ parse_execution_result_t parse_execution_context_t::run_while_statement(
     assert(block_contents.type == symbol_job_list);
 
     // Push a while block.
-    while_block_t *wb = new while_block_t();
+    while_block_t *wb = parser->push_block();
     wb->node_offset = this->get_offset(header);
-    parser->push_block(wb);
 
     parse_execution_result_t ret = parse_execution_success;
 
@@ -656,7 +642,6 @@ parse_execution_result_t parse_execution_context_t::run_while_statement(
             if (wb->loop_status == LOOP_CONTINUE) {
                 // Reset the loop state.
                 wb->loop_status = LOOP_NORMAL;
-                wb->skip = false;
                 continue;
             } else if (wb->loop_status == LOOP_BREAK) {
                 break;
@@ -670,9 +655,8 @@ parse_execution_result_t parse_execution_context_t::run_while_statement(
         }
     }
 
-    /* Done */
+    // Done
     parser->pop_block(wb);
-
     return ret;
 }
 
@@ -700,7 +684,7 @@ parse_execution_result_t parse_execution_context_t::report_errors(
     const parse_error_list_t &error_list) const {
     if (!parser->cancellation_requested) {
         if (error_list.empty()) {
-            fprintf(stderr, "Bug: Error reported but no error text found.");
+            debug(0, "Error reported but no error text found.");
         }
 
         // Get a backtrace.
@@ -708,7 +692,9 @@ parse_execution_result_t parse_execution_context_t::report_errors(
         parser->get_backtrace(src, error_list, &backtrace_and_desc);
 
         // Print it.
-        fprintf(stderr, "%ls", backtrace_and_desc.c_str());
+        if (!should_suppress_stderr_for_tests()) {
+            fwprintf(stderr, L"%ls", backtrace_and_desc.c_str());
+        }
     }
     return parse_execution_errored;
 }
@@ -832,6 +818,7 @@ parse_execution_result_t parse_execution_context_t::populate_plain_process(
     bool expanded = expand_one(cmd, EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_VARIABLES, NULL);
     if (!expanded) {
         report_error(statement, ILLEGAL_CMD_ERR_MSG, cmd.c_str());
+        proc_set_last_status(STATUS_ILLEGAL_CMD);
         return parse_execution_errored;
     }
 
@@ -959,14 +946,11 @@ parse_execution_result_t parse_execution_context_t::determine_arguments(
             }
         }
 
-        // Now copy over any expanded arguments. Do it using swap() to avoid extra allocations; this
+        // Now copy over any expanded arguments. Use std::move() to avoid extra allocations; this
         // is called very frequently.
-        size_t old_arg_count = out_arguments->size();
-        size_t new_arg_count = arg_expanded.size();
-        out_arguments->resize(old_arg_count + new_arg_count);
-        for (size_t i = 0; i < new_arg_count; i++) {
-            wcstring &new_arg = arg_expanded.at(i).completion;
-            out_arguments->at(old_arg_count + i).swap(new_arg);
+        out_arguments->reserve(out_arguments->size() + arg_expanded.size());
+        for (completion_t &new_arg : arg_expanded) {
+            out_arguments->push_back(std::move(new_arg.completion));
         }
     }
 
@@ -1010,10 +994,8 @@ bool parse_execution_context_t::determine_io_chain(const parse_node_t &statement
                 if (target == L"-") {
                     new_io.reset(new io_close_t(source_fd));
                 } else {
-                    wchar_t *end = NULL;
-                    errno = 0;
-                    int old_fd = fish_wcstoi(target.c_str(), &end, 10);
-                    if (old_fd < 0 || errno || *end) {
+                    int old_fd = fish_wcstoi(target.c_str());
+                    if (errno || old_fd < 0) {
                         errored =
                             report_error(redirect_node, _(L"Requested redirection to '%ls', which "
                                                           L"is not a valid file descriptor"),
@@ -1035,8 +1017,7 @@ bool parse_execution_context_t::determine_io_chain(const parse_node_t &statement
             }
             default: {
                 // Should be unreachable.
-                fprintf(stderr, "Unexpected redirection type %ld. aborting.\n",
-                        (long)redirect_type);
+                debug(0, "Unexpected redirection type %ld.", (long)redirect_type);
                 PARSER_DIE();
                 break;
             }
@@ -1049,7 +1030,7 @@ bool parse_execution_context_t::determine_io_chain(const parse_node_t &statement
     }
 
     if (out_chain && !errored) {
-        out_chain->swap(result);
+        *out_chain = std::move(result);
     }
     return !errored;
 }
@@ -1072,7 +1053,7 @@ parse_execution_result_t parse_execution_context_t::populate_boolean_process(
         }
         case parse_bool_not: {
             // NOT. Negate it.
-            job_set_flag(job, JOB_NEGATE, !job_get_flag(job, JOB_NEGATE));
+            job->set_flag(JOB_NEGATE, !job->get_flag(JOB_NEGATE));
             break;
         }
     }
@@ -1134,8 +1115,8 @@ parse_execution_result_t parse_execution_context_t::populate_job_process(
             break;
         }
         default: {
-            fprintf(stderr, "'%ls' not handled by new parser yet\n",
-                    specific_statement.describe().c_str());
+            debug(0, L"'%ls' not handled by new parser yet.",
+                  specific_statement.describe().c_str());
             PARSER_DIE();
             break;
         }
@@ -1160,9 +1141,9 @@ parse_execution_result_t parse_execution_context_t::populate_job_from_job_node(
     parse_execution_result_t result = parse_execution_success;
 
     // Create processes. Each one may fail.
-    std::vector processes;
-    processes.push_back(new process_t());
-    result = this->populate_job_process(j, processes.back(), *statement_node);
+    process_list_t processes;
+    processes.emplace_back(new process_t());
+    result = this->populate_job_process(j, processes.back().get(), *statement_node);
 
     // Construct process_ts for job continuations (pipelines), by walking the list until we hit the
     // terminal (empty) job continuation.
@@ -1185,29 +1166,23 @@ parse_execution_result_t parse_execution_context_t::populate_job_from_job_node(
         assert(statement_node != NULL);
 
         // Store the new process (and maybe with an error).
-        processes.push_back(new process_t());
-        result = this->populate_job_process(j, processes.back(), *statement_node);
+        processes.emplace_back(new process_t());
+        result = this->populate_job_process(j, processes.back().get(), *statement_node);
 
         // Get the next continuation.
         job_cont = get_child(*job_cont, 2, symbol_job_continuation);
         assert(job_cont != NULL);
     }
 
+    // Inform our processes of who is first and last
+    processes.front()->is_first_in_job = true;
+    processes.back()->is_last_in_job = true;
+
     // Return what happened.
     if (result == parse_execution_success) {
         // Link up the processes.
         assert(!processes.empty());  //!OCLINT(multiple unary operator)
-        j->first_process = processes.at(0);
-        for (size_t i = 1; i < processes.size(); i++) {
-            processes.at(i - 1)->next = processes.at(i);
-        }
-    } else {
-        // Clean up processes.
-        for (size_t i = 0; i < processes.size(); i++) {
-            const process_t *proc = processes.at(i);
-            processes.at(i) = NULL;
-            delete proc;
-        }
+        j->processes = std::move(processes);
     }
     return result;
 }
@@ -1285,34 +1260,32 @@ parse_execution_result_t parse_execution_context_t::run_1_job(const parse_node_t
         return result;
     }
 
-    job_t *j = new job_t(acquire_job_id(), block_io);
-    j->tmodes = tmodes;
-    job_set_flag(j, JOB_CONTROL,
-                 (job_control_mode == JOB_CONTROL_ALL) ||
-                     ((job_control_mode == JOB_CONTROL_INTERACTIVE) && (shell_is_interactive())));
+    shared_ptr job = std::make_shared(acquire_job_id(), block_io);
+    job->tmodes = tmodes;
+    job->set_flag(JOB_CONTROL,
+                  (job_control_mode == JOB_CONTROL_ALL) ||
+                      ((job_control_mode == JOB_CONTROL_INTERACTIVE) && shell_is_interactive()));
 
-    job_set_flag(j, JOB_FOREGROUND, !tree.job_should_be_backgrounded(job_node));
+    job->set_flag(JOB_FOREGROUND, !tree.job_should_be_backgrounded(job_node));
 
-    job_set_flag(j, JOB_TERMINAL, job_get_flag(j, JOB_CONTROL) && !is_subshell && !is_event);
+    job->set_flag(JOB_TERMINAL, job->get_flag(JOB_CONTROL) && !is_subshell && !is_event);
 
-    job_set_flag(j, JOB_SKIP_NOTIFICATION,
-                 is_subshell || is_block || is_event || !shell_is_interactive());
+    job->set_flag(JOB_SKIP_NOTIFICATION,
+                  is_subshell || is_block || is_event || !shell_is_interactive());
 
     // Tell the current block what its job is. This has to happen before we populate it (#1394).
-    parser->current_block()->job = j;
+    parser->current_block()->job = job;
 
     // Populate the job. This may fail for reasons like command_not_found. If this fails, an error
     // will have been printed.
     parse_execution_result_t pop_result =
-        this->populate_job_from_job_node(j, job_node, associated_block);
+        this->populate_job_from_job_node(job.get(), job_node, associated_block);
 
     // Clean up the job on failure or cancellation.
     bool populated_job = (pop_result == parse_execution_success);
     if (!populated_job || this->should_cancel_execution(associated_block)) {
-        assert(parser->current_block()->job == j);
+        assert(parser->current_block()->job == job);
         parser->current_block()->job = NULL;
-        delete j;
-        j = NULL;
         populated_job = false;
     }
 
@@ -1323,11 +1296,11 @@ parse_execution_result_t parse_execution_context_t::run_1_job(const parse_node_t
 
     if (populated_job) {
         // Success. Give the job to the parser - it will clean it up.
-        parser->job_add(j);
+        parser->job_add(job);
 
         // Check to see if this contained any external commands.
         bool job_contained_external_command = false;
-        for (const process_t *proc = j->first_process; proc != NULL; proc = proc->next) {
+        for (const auto &proc : job->processes) {
             if (proc->type == EXTERNAL) {
                 job_contained_external_command = true;
                 break;
@@ -1335,7 +1308,7 @@ parse_execution_result_t parse_execution_context_t::run_1_job(const parse_node_t
         }
 
         // Actually execute the job.
-        exec_job(*this->parser, j);
+        exec_job(*this->parser, job.get());
 
         // Only external commands require a new fishd barrier.
         if (job_contained_external_command) {
@@ -1348,7 +1321,7 @@ parse_execution_result_t parse_execution_context_t::run_1_job(const parse_node_t
         profile_item->level = eval_level;
         profile_item->parse = (int)(parse_time - start_time);
         profile_item->exec = (int)(exec_time - parse_time);
-        profile_item->cmd = j ? j->command() : wcstring();
+        profile_item->cmd = job ? job->command() : wcstring();
         profile_item->skipped = !populated_job;
     }
 
@@ -1427,8 +1400,7 @@ parse_execution_result_t parse_execution_context_t::eval_node_at_offset(
         default: {
             // In principle, we could support other node types. However we never expect to be passed
             // them - see above.
-            fprintf(stderr, "Unexpected node %ls found in %s\n", node.describe().c_str(),
-                    __FUNCTION__);
+            debug(0, "Unexpected node %ls found in %s", node.describe().c_str(), __FUNCTION__);
             PARSER_DIE();
             break;
         }
diff --git a/src/parse_execution.h b/src/parse_execution.h
index 23d27e506..7e6867fd7 100644
--- a/src/parse_execution.h
+++ b/src/parse_execution.h
@@ -127,7 +127,7 @@ class parse_execution_context_t {
     int line_offset_of_character_at_offset(size_t char_idx);
 
    public:
-    parse_execution_context_t(moved_ref t, const wcstring &s, parser_t *p,
+    parse_execution_context_t(parse_node_tree_t t, const wcstring &s, parser_t *p,
                               int initial_eval_level);
 
     /// Returns the current eval level.
diff --git a/src/parse_productions.cpp b/src/parse_productions.cpp
index b3d976905..ffd998e11 100644
--- a/src/parse_productions.cpp
+++ b/src/parse_productions.cpp
@@ -21,34 +21,41 @@ using namespace parse_productions;
 // Productions are generally a static const array, and we return a pointer to the array (yes,
 // really).
 
-#define RESOLVE(sym)                          \
-    static const production_t *resolve_##sym( \
+#define RESOLVE(sym)                                  \
+    static const production_element_t *resolve_##sym( \
         const parse_token_t &token1, const parse_token_t &token2, parse_node_tag_t *out_tag)
 
-// Hacktastic?
-#define RESOLVE_ONLY(sym)                                                                      \
-    extern const production_t sym##_only;                                                      \
-    static const production_t *resolve_##sym(                                                  \
+// This is a shorthand for symbols which always resolve to the same production sequence. Using this
+// avoids repeating a lot of boilerplate code below.
+#define RESOLVE_ONLY(sym, tokens...)                                                           \
+    extern const production_element_t sym##_only[];                                            \
+    static const production_element_t *resolve_##sym(                                          \
         const parse_token_t &token1, const parse_token_t &token2, parse_node_tag_t *out_tag) { \
         UNUSED(token1);                                                                        \
         UNUSED(token2);                                                                        \
         UNUSED(out_tag);                                                                       \
-        return &sym##_only;                                                                    \
+        return sym##_only;                                                                     \
     }                                                                                          \
-    const production_t sym##_only
+    const production_element_t sym##_only[] = {tokens, token_type_invalid}
 
-#define KEYWORD(x) ((x) + LAST_TOKEN_OR_SYMBOL + 1)
+// Convert a parse_keyword_t enum to a parse_token_type_t enum.
+#define KEYWORD(keyword) (keyword + LAST_TOKEN_OR_SYMBOL + 1)
 
-/// Helper macro to define an array.
-#define P static const production_t
+/// Helper macro to define a production sequence. Note that such sequences must always end with
+/// enum `token_type_invalid`.
+#define P(production_name, tokens...) \
+    static const production_element_t production_name[] = {tokens, token_type_invalid}
+
+/// The empty production is used often enough it's worth definining once at module scope.
+static const production_element_t empty[] = {token_type_invalid};
 
 /// A job_list is a list of jobs, separated by semicolons or newlines.
 RESOLVE(job_list) {
     UNUSED(token2);
     UNUSED(out_tag);
-    P list_end = {};
-    P normal = {symbol_job, symbol_job_list};
-    P empty_line = {parse_token_type_end, symbol_job_list};
+    P(normal, symbol_job, symbol_job_list);
+    P(empty_line, parse_token_type_end, symbol_job_list);
+
     switch (token1.type) {
         case parse_token_type_string: {
             // Some keywords are special.
@@ -56,23 +63,23 @@ RESOLVE(job_list) {
                 case parse_keyword_end:
                 case parse_keyword_else:
                 case parse_keyword_case: {
-                    return &list_end;  // end this job list
+                    return empty;  // end this job list
                 }
                 default: {
-                    return &normal;  // normal string
+                    return normal;  // normal string
                 }
             }
         }
         case parse_token_type_pipe:
         case parse_token_type_redirection:
         case parse_token_type_background: {
-            return &normal;
+            return normal;
         }
         case parse_token_type_end: {
-            return &empty_line;
+            return empty_line;
         }
         case parse_token_type_terminate: {
-            return &list_end;  // no more commands, just transition to empty
+            return empty;  // no more commands, just transition to empty
         }
         default: { return NO_PRODUCTION; }
     }
@@ -81,20 +88,19 @@ RESOLVE(job_list) {
 // A job is a non-empty list of statements, separated by pipes. (Non-empty is useful for cases like
 // if statements, where we require a command). To represent "non-empty", we require a statement,
 // followed by a possibly empty job_continuation.
-
-RESOLVE_ONLY(job) = {symbol_statement, symbol_job_continuation, symbol_optional_background};
+RESOLVE_ONLY(job, symbol_statement, symbol_job_continuation, symbol_optional_background);
 
 RESOLVE(job_continuation) {
     UNUSED(token2);
     UNUSED(out_tag);
-    P empty = {};
-    P piped = {parse_token_type_pipe, symbol_statement, symbol_job_continuation};
+    P(piped, parse_token_type_pipe, symbol_statement, symbol_job_continuation);
+
     switch (token1.type) {
         case parse_token_type_pipe: {
-            return &piped;  // pipe, continuation
+            return piped;  // pipe, continuation
         }
         default: {
-            return ∅  // not a pipe, no job continuation
+            return empty;  // not a pipe, no job continuation
         }
     }
 }
@@ -102,11 +108,12 @@ RESOLVE(job_continuation) {
 // A statement is a normal command, or an if / while / and etc.
 RESOLVE(statement) {
     UNUSED(out_tag);
-    P boolean = {symbol_boolean_statement};
-    P block = {symbol_block_statement};
-    P ifs = {symbol_if_statement};
-    P switchs = {symbol_switch_statement};
-    P decorated = {symbol_decorated_statement};
+    P(boolean, symbol_boolean_statement);
+    P(block, symbol_block_statement);
+    P(ifs, symbol_if_statement);
+    P(switchs, symbol_switch_statement);
+    P(decorated, symbol_decorated_statement);
+
     // The only block-like builtin that takes any parameters is 'function' So go to decorated
     // statements if the subsequent token looks like '--'. The logic here is subtle:
     //
@@ -118,9 +125,9 @@ RESOLVE(statement) {
         // If we are a function, then look for help arguments. Otherwise, if the next token looks
         // like an option (starts with a dash), then parse it as a decorated statement.
         if (token1.keyword == parse_keyword_function && token2.is_help_argument) {
-            return &decorated;
+            return decorated;
         } else if (token1.keyword != parse_keyword_function && token2.has_dash_prefix) {
-            return &decorated;
+            return decorated;
         }
 
         // Likewise if the next token doesn't look like an argument at all. This corresponds to e.g.
@@ -129,7 +136,7 @@ RESOLVE(statement) {
             (token1.keyword != parse_keyword_begin && token1.keyword != parse_keyword_end);
         if (naked_invocation_invokes_help &&
             (token2.type == parse_token_type_end || token2.type == parse_token_type_terminate)) {
-            return &decorated;
+            return decorated;
         }
     }
 
@@ -139,28 +146,28 @@ RESOLVE(statement) {
                 case parse_keyword_and:
                 case parse_keyword_or:
                 case parse_keyword_not: {
-                    return &boolean;
+                    return boolean;
                 }
                 case parse_keyword_for:
                 case parse_keyword_while:
                 case parse_keyword_function:
                 case parse_keyword_begin: {
-                    return █
+                    return block;
                 }
                 case parse_keyword_if: {
-                    return &ifs;
+                    return ifs;
                 }
                 case parse_keyword_else: {
                     return NO_PRODUCTION;
                 }
                 case parse_keyword_switch: {
-                    return &switchs;
+                    return switchs;
                 }
                 case parse_keyword_end: {
                     return NO_PRODUCTION;
                 }
                 // All other keywords fall through to decorated statement.
-                default: { return &decorated; }
+                default: { return decorated; }
             }
             break;
         }
@@ -169,277 +176,274 @@ RESOLVE(statement) {
         case parse_token_type_background:
         case parse_token_type_terminate: {
             return NO_PRODUCTION;
-            // parse_error(L"statement", token);
         }
         default: { return NO_PRODUCTION; }
     }
 }
 
-RESOLVE_ONLY(if_statement) = {symbol_if_clause, symbol_else_clause, symbol_end_command,
-                              symbol_arguments_or_redirections_list};
-RESOLVE_ONLY(if_clause) = {KEYWORD(parse_keyword_if), symbol_job, parse_token_type_end,
-                           symbol_andor_job_list, symbol_job_list};
+RESOLVE_ONLY(if_statement, symbol_if_clause, symbol_else_clause, symbol_end_command,
+             symbol_arguments_or_redirections_list);
+RESOLVE_ONLY(if_clause, KEYWORD(parse_keyword_if), symbol_job, parse_token_type_end,
+             symbol_andor_job_list, symbol_job_list);
 
 RESOLVE(else_clause) {
     UNUSED(token2);
     UNUSED(out_tag);
-    P empty = {};
-    P else_cont = {KEYWORD(parse_keyword_else), symbol_else_continuation};
+    P(else_cont, KEYWORD(parse_keyword_else), symbol_else_continuation);
+
     switch (token1.keyword) {
         case parse_keyword_else: {
-            return &else_cont;
+            return else_cont;
         }
-        default: { return ∅ }
+        default: { return empty; }
     }
 }
 
 RESOLVE(else_continuation) {
     UNUSED(token2);
     UNUSED(out_tag);
-    P elseif = {symbol_if_clause, symbol_else_clause};
-    P elseonly = {parse_token_type_end, symbol_job_list};
+    P(elseif, symbol_if_clause, symbol_else_clause);
+    P(elseonly, parse_token_type_end, symbol_job_list);
 
     switch (token1.keyword) {
         case parse_keyword_if: {
-            return &elseif;
+            return elseif;
         }
-        default: { return &elseonly; }
+        default: { return elseonly; }
     }
 }
 
-RESOLVE_ONLY(switch_statement) = {
-    KEYWORD(parse_keyword_switch), symbol_argument,    parse_token_type_end,
-    symbol_case_item_list,         symbol_end_command, symbol_arguments_or_redirections_list};
+RESOLVE_ONLY(switch_statement, KEYWORD(parse_keyword_switch), symbol_argument, parse_token_type_end,
+             symbol_case_item_list, symbol_end_command, symbol_arguments_or_redirections_list);
 
 RESOLVE(case_item_list) {
     UNUSED(token2);
     UNUSED(out_tag);
-    P empty = {};
-    P case_item = {symbol_case_item, symbol_case_item_list};
-    P blank_line = {parse_token_type_end, symbol_case_item_list};
+    P(case_item, symbol_case_item, symbol_case_item_list);
+    P(blank_line, parse_token_type_end, symbol_case_item_list);
+
     if (token1.keyword == parse_keyword_case)
-        return &case_item;
+        return case_item;
     else if (token1.type == parse_token_type_end)
-        return &blank_line;
+        return blank_line;
     else
-        return ∅
+        return empty;
 }
 
-RESOLVE_ONLY(case_item) = {KEYWORD(parse_keyword_case), symbol_argument_list, parse_token_type_end,
-                           symbol_job_list};
+RESOLVE_ONLY(case_item, KEYWORD(parse_keyword_case), symbol_argument_list, parse_token_type_end,
+             symbol_job_list);
 
 RESOLVE(andor_job_list) {
     UNUSED(out_tag);
-    P list_end = {};
-    P andor_job = {symbol_job, symbol_andor_job_list};
-    P empty_line = {parse_token_type_end, symbol_andor_job_list};
+    P(andor_job, symbol_job, symbol_andor_job_list);
+    P(empty_line, parse_token_type_end, symbol_andor_job_list);
 
     if (token1.type == parse_token_type_end) {
-        return &empty_line;
+        return empty_line;
     } else if (token1.keyword == parse_keyword_and || token1.keyword == parse_keyword_or) {
         // Check that the argument to and/or is a string that's not help. Otherwise it's either 'and
         // --help' or a naked 'and', and not part of this list.
         if (token2.type == parse_token_type_string && !token2.is_help_argument) {
-            return &andor_job;
+            return andor_job;
         }
     }
     // All other cases end the list.
-    return &list_end;
+    return empty;
 }
 
 RESOLVE(argument_list) {
     UNUSED(token2);
     UNUSED(out_tag);
-    P empty = {};
-    P arg = {symbol_argument, symbol_argument_list};
+    P(arg, symbol_argument, symbol_argument_list);
     switch (token1.type) {
         case parse_token_type_string: {
-            return &arg;
+            return arg;
         }
-        default: { return ∅ }
+        default: { return empty; }
     }
 }
 
 RESOLVE(freestanding_argument_list) {
     UNUSED(token2);
     UNUSED(out_tag);
-    P empty = {};
-    P arg = {symbol_argument, symbol_freestanding_argument_list};
-    P semicolon = {parse_token_type_end, symbol_freestanding_argument_list};
+    P(arg, symbol_argument, symbol_freestanding_argument_list);
+    P(semicolon, parse_token_type_end, symbol_freestanding_argument_list);
 
     switch (token1.type) {
         case parse_token_type_string: {
-            return &arg;
+            return arg;
         }
         case parse_token_type_end: {
-            return &semicolon;
+            return semicolon;
         }
-        default: { return ∅ }
+        default: { return empty; }
     }
 }
 
-RESOLVE_ONLY(block_statement) = {symbol_block_header, symbol_job_list, symbol_end_command,
-                                 symbol_arguments_or_redirections_list};
+RESOLVE_ONLY(block_statement, symbol_block_header, symbol_job_list, symbol_end_command,
+             symbol_arguments_or_redirections_list);
 
 RESOLVE(block_header) {
     UNUSED(token2);
     UNUSED(out_tag);
-    P forh = {symbol_for_header};
-    P whileh = {symbol_while_header};
-    P funch = {symbol_function_header};
-    P beginh = {symbol_begin_header};
+    P(forh, symbol_for_header);
+    P(whileh, symbol_while_header);
+    P(funch, symbol_function_header);
+    P(beginh, symbol_begin_header);
 
     switch (token1.keyword) {
         case parse_keyword_for: {
-            return &forh;
+            return forh;
         }
         case parse_keyword_while: {
-            return &whileh;
+            return whileh;
         }
         case parse_keyword_function: {
-            return &funch;
+            return funch;
         }
         case parse_keyword_begin: {
-            return &beginh;
+            return beginh;
         }
         default: { return NO_PRODUCTION; }
     }
 }
 
-RESOLVE_ONLY(for_header) = {KEYWORD(parse_keyword_for), parse_token_type_string,
-                            KEYWORD(parse_keyword_in), symbol_argument_list, parse_token_type_end};
-RESOLVE_ONLY(while_header) = {KEYWORD(parse_keyword_while), symbol_job, parse_token_type_end,
-                              symbol_andor_job_list};
-RESOLVE_ONLY(begin_header) = {KEYWORD(parse_keyword_begin)};
-RESOLVE_ONLY(function_header) = {KEYWORD(parse_keyword_function), symbol_argument,
-                                 symbol_argument_list, parse_token_type_end};
+RESOLVE_ONLY(for_header, KEYWORD(parse_keyword_for), parse_token_type_string,
+             KEYWORD(parse_keyword_in), symbol_argument_list, parse_token_type_end);
+RESOLVE_ONLY(while_header, KEYWORD(parse_keyword_while), symbol_job, parse_token_type_end,
+             symbol_andor_job_list);
+RESOLVE_ONLY(begin_header, KEYWORD(parse_keyword_begin));
+RESOLVE_ONLY(function_header, KEYWORD(parse_keyword_function), symbol_argument,
+             symbol_argument_list, parse_token_type_end);
 
 // A boolean statement is AND or OR or NOT.
 RESOLVE(boolean_statement) {
     UNUSED(token2);
-    P ands = {KEYWORD(parse_keyword_and), symbol_statement};
-    P ors = {KEYWORD(parse_keyword_or), symbol_statement};
-    P nots = {KEYWORD(parse_keyword_not), symbol_statement};
+    P(ands, KEYWORD(parse_keyword_and), symbol_statement);
+    P(ors, KEYWORD(parse_keyword_or), symbol_statement);
+    P(nots, KEYWORD(parse_keyword_not), symbol_statement);
 
     switch (token1.keyword) {
         case parse_keyword_and: {
             *out_tag = parse_bool_and;
-            return &ands;
+            return ands;
         }
         case parse_keyword_or: {
             *out_tag = parse_bool_or;
-            return &ors;
+            return ors;
         }
         case parse_keyword_not: {
             *out_tag = parse_bool_not;
-            return ¬s;
+            return nots;
         }
         default: { return NO_PRODUCTION; }
     }
 }
 
 RESOLVE(decorated_statement) {
-    P plains = {symbol_plain_statement};
-    P cmds = {KEYWORD(parse_keyword_command), symbol_plain_statement};
-    P builtins = {KEYWORD(parse_keyword_builtin), symbol_plain_statement};
-    P execs = {KEYWORD(parse_keyword_exec), symbol_plain_statement};
+    P(plains, symbol_plain_statement);
+    P(cmds, KEYWORD(parse_keyword_command), symbol_plain_statement);
+    P(builtins, KEYWORD(parse_keyword_builtin), symbol_plain_statement);
+    P(execs, KEYWORD(parse_keyword_exec), symbol_plain_statement);
 
     // If this is e.g. 'command --help' then the command is 'command' and not a decoration. If the
     // second token is not a string, then this is a naked 'command' and we should execute it as
     // undecorated.
     if (token2.type != parse_token_type_string || token2.has_dash_prefix) {
-        return &plains;
+        return plains;
     }
 
     switch (token1.keyword) {
         case parse_keyword_command: {
             *out_tag = parse_statement_decoration_command;
-            return &cmds;
+            return cmds;
         }
         case parse_keyword_builtin: {
             *out_tag = parse_statement_decoration_builtin;
-            return &builtins;
+            return builtins;
         }
         case parse_keyword_exec: {
             *out_tag = parse_statement_decoration_exec;
-            return &execs;
+            return execs;
         }
         default: {
             *out_tag = parse_statement_decoration_none;
-            return &plains;
+            return plains;
         }
     }
 }
 
-RESOLVE_ONLY(plain_statement) = {parse_token_type_string, symbol_arguments_or_redirections_list};
+RESOLVE_ONLY(plain_statement, parse_token_type_string, symbol_arguments_or_redirections_list);
 
 RESOLVE(arguments_or_redirections_list) {
     UNUSED(token2);
     UNUSED(out_tag);
-    P empty = {};
-    P value = {symbol_argument_or_redirection, symbol_arguments_or_redirections_list};
+    P(value, symbol_argument_or_redirection, symbol_arguments_or_redirections_list);
+
     switch (token1.type) {
         case parse_token_type_string:
         case parse_token_type_redirection: {
-            return &value;
+            return value;
         }
-        default: { return ∅ }
+        default: { return empty; }
     }
 }
 
 RESOLVE(argument_or_redirection) {
     UNUSED(token2);
     UNUSED(out_tag);
-    P arg = {symbol_argument};
-    P redir = {symbol_redirection};
+    P(arg, symbol_argument);
+    P(redir, symbol_redirection);
+
     switch (token1.type) {
         case parse_token_type_string: {
-            return &arg;
+            return arg;
         }
         case parse_token_type_redirection: {
-            return &redir;
+            return redir;
         }
         default: { return NO_PRODUCTION; }
     }
 }
 
-RESOLVE_ONLY(argument) = {parse_token_type_string};
-RESOLVE_ONLY(redirection) = {parse_token_type_redirection, parse_token_type_string};
+RESOLVE_ONLY(argument, parse_token_type_string);
+RESOLVE_ONLY(redirection, parse_token_type_redirection, parse_token_type_string);
 
 RESOLVE(optional_background) {
     UNUSED(token2);
-    P empty = {};
-    P background = {parse_token_type_background};
+    P(background, parse_token_type_background);
+
     switch (token1.type) {
         case parse_token_type_background: {
             *out_tag = parse_background;
-            return &background;
+            return background;
         }
         default: {
             *out_tag = parse_no_background;
-            return ∅
+            return empty;
         }
     }
 }
 
-RESOLVE_ONLY(end_command) = {KEYWORD(parse_keyword_end)};
+RESOLVE_ONLY(end_command, KEYWORD(parse_keyword_end));
 
 #define TEST(sym)                 \
     case (symbol_##sym):          \
         resolver = resolve_##sym; \
         break;
 
-const production_t *parse_productions::production_for_token(parse_token_type_t node_type,
-                                                            const parse_token_t &input1,
-                                                            const parse_token_t &input2,
-                                                            parse_node_tag_t *out_tag) {
+const production_element_t *parse_productions::production_for_token(parse_token_type_t node_type,
+                                                                    const parse_token_t &input1,
+                                                                    const parse_token_t &input2,
+                                                                    parse_node_tag_t *out_tag) {
     debug(5, "Resolving production for %ls with input token <%ls>\n",
           token_type_description(node_type), input1.describe().c_str());
 
     // Fetch the function to resolve the list of productions.
-    const production_t *(*resolver)(const parse_token_t &input1,        //!OCLINT(unused param)
-                                    const parse_token_t &input2,        //!OCLINT(unused param)
-                                    parse_node_tag_t *out_tag) = NULL;  //!OCLINT(unused param)
+    const production_element_t *(*resolver)(const parse_token_t &input1,  //!OCLINT(unused param)
+                                            const parse_token_t &input2,  //!OCLINT(unused param)
+                                            parse_node_tag_t *out_tag) =  //!OCLINT(unused param)
+        NULL;
     switch (node_type) {
         TEST(job_list)
         TEST(job)
@@ -477,28 +481,28 @@ const production_t *parse_productions::production_for_token(parse_token_type_t n
         case parse_token_type_background:
         case parse_token_type_end:
         case parse_token_type_terminate: {
-            fprintf(stderr, "Terminal token type %ls passed to %s\n",
-                    token_type_description(node_type), __FUNCTION__);
+            debug(0, "Terminal token type %ls passed to %s", token_type_description(node_type),
+                  __FUNCTION__);
             PARSER_DIE();
             break;
         }
         case parse_special_type_parse_error:
         case parse_special_type_tokenizer_error:
         case parse_special_type_comment: {
-            fprintf(stderr, "Special type %ls passed to %s\n", token_type_description(node_type),
-                    __FUNCTION__);
+            debug(0, "Special type %ls passed to %s\n", token_type_description(node_type),
+                  __FUNCTION__);
             PARSER_DIE();
             break;
         }
         case token_type_invalid: {
-            fprintf(stderr, "token_type_invalid passed to %s\n", __FUNCTION__);
+            debug(0, "token_type_invalid passed to %s", __FUNCTION__);
             PARSER_DIE();
             break;
         }
     }
     PARSE_ASSERT(resolver != NULL);
 
-    const production_t *result = resolver(input1, input2, out_tag);
+    const production_element_t *result = resolver(input1, input2, out_tag);
     if (result == NULL) {
         debug(5, "Node type '%ls' has no production for input '%ls' (in %s)\n",
               token_type_description(node_type), input1.describe().c_str(), __FUNCTION__);
diff --git a/src/parse_productions.h b/src/parse_productions.h
index 3be0cbaf4..ce1589ebb 100644
--- a/src/parse_productions.h
+++ b/src/parse_productions.h
@@ -10,13 +10,10 @@ struct parse_token_t;
 
 namespace parse_productions {
 
-#define MAX_SYMBOLS_PER_PRODUCTION 6
-
 // A production is an array of unsigned char. Symbols are encoded directly as their symbol value.
 // Keywords are encoded with an offset of LAST_TOKEN_OR_SYMBOL + 1. So essentially we glom together
 // keywords and symbols.
 typedef uint8_t production_element_t;
-typedef production_element_t const production_t[MAX_SYMBOLS_PER_PRODUCTION];
 
 /// Resolve the type from a production element.
 inline parse_token_type_t production_element_type(production_element_t elem) {
@@ -44,8 +41,9 @@ inline bool production_element_is_valid(production_element_t elem) {
 
 /// Fetch a production. We are passed two input tokens. The first input token is guaranteed to not
 /// be invalid; the second token may be invalid if there's no more tokens. We may also set flags.
-const production_t *production_for_token(parse_token_type_t node_type, const parse_token_t &input1,
-                                         const parse_token_t &input2, uint8_t *out_tag);
+const production_element_t *production_for_token(parse_token_type_t node_type,
+                                                 const parse_token_t &input1,
+                                                 const parse_token_t &input2, uint8_t *out_tag);
 }
 
 #endif
diff --git a/src/parse_tree.cpp b/src/parse_tree.cpp
index 3a0ceb168..eda099ac3 100644
--- a/src/parse_tree.cpp
+++ b/src/parse_tree.cpp
@@ -20,53 +20,10 @@
 #include "tokenizer.h"
 #include "wutil.h"  // IWYU pragma: keep
 
-// This array provides strings for each symbol in enum parse_token_type_t in parse_constants.h.
-const wchar_t *const token_type_map[] = {
-    L"token_type_invalid",
-    L"symbol_job_list",
-    L"symbol_job",
-    L"symbol_job_continuation",
-    L"symbol_statement",
-    L"symbol_block_statement",
-    L"symbol_block_header",
-    L"symbol_for_header",
-    L"symbol_while_header",
-    L"symbol_begin_header",
-    L"symbol_function_header",
-    L"symbol_if_statement",
-    L"symbol_if_clause",
-    L"symbol_else_clause",
-    L"symbol_else_continuation",
-    L"symbol_switch_statement",
-    L"symbol_case_item_list",
-    L"symbol_case_item",
-    L"symbol_boolean_statement",
-    L"symbol_decorated_statement",
-    L"symbol_plain_statement",
-    L"symbol_arguments_or_redirections_list",
-    L"symbol_argument_or_redirection",
-    L"symbol_andor_job_list",
-    L"symbol_argument_list",
-    L"symbol_freestanding_argument_list",
-    L"symbol_argument",
-    L"symbol_redirection",
-    L"symbol_optional_background",
-    L"symbol_end_command",
-    L"parse_token_type_string",
-    L"parse_token_type_pipe",
-    L"parse_token_type_redirection",
-    L"parse_token_type_background",
-    L"parse_token_type_end",
-    L"parse_token_type_terminate",
-    L"parse_special_type_parse_error",
-    L"parse_special_type_tokenizer_error",
-    L"parse_special_type_comment",
-};
-
 using namespace parse_productions;
 
-static bool production_is_empty(const production_t *production) {
-    return (*production)[0] == token_type_invalid;
+static bool production_is_empty(const production_element_t *production) {
+    return *production == token_type_invalid;
 }
 
 /// Returns a string description of this parse error.
@@ -164,52 +121,15 @@ void parse_error_offset_source_start(parse_error_list_t *errors, size_t amt) {
 
 /// Returns a string description for the given token type.
 const wchar_t *token_type_description(parse_token_type_t type) {
-    if (type >= 0 && type <= LAST_TOKEN_TYPE) return token_type_map[type];
-
-    // This leaks memory but it should never be run unless we have a bug elsewhere in the code.
-    const wcstring d = format_string(L"unknown_token_type_%ld", static_cast(type));
-    wchar_t *d2 = new wchar_t[d.size() + 1];
-    // cppcheck-suppress memleak
-    return std::wcscpy(d2, d.c_str());
+    const wchar_t *description = enum_to_str(type, token_enum_map);
+    if (description) return description;
+    return L"unknown_token_type";
 }
 
-#define LONGIFY(x) L##x
-#define KEYWORD_MAP(x) \
-    { parse_keyword_##x, LONGIFY(#x) }
-static const struct {
-    const parse_keyword_t keyword;
-    const wchar_t *const name;
-}
-keyword_map[] =
-{
-    // Note that these must be sorted (except for the first), so that we can do binary search.
-    KEYWORD_MAP(none),
-    KEYWORD_MAP(and),
-    KEYWORD_MAP(begin),
-    KEYWORD_MAP(builtin),
-    KEYWORD_MAP(case),
-    KEYWORD_MAP(command),
-    KEYWORD_MAP(else),
-    KEYWORD_MAP(end),
-    KEYWORD_MAP(exec),
-    KEYWORD_MAP(for),
-    KEYWORD_MAP(function),
-    KEYWORD_MAP(if),
-    KEYWORD_MAP(in),
-    KEYWORD_MAP(not),
-    KEYWORD_MAP(or),
-    KEYWORD_MAP(switch),
-    KEYWORD_MAP(while)
-};
-
 const wchar_t *keyword_description(parse_keyword_t type) {
-    if (type >= 0 && type <= LAST_KEYWORD) return keyword_map[type].name;
-
-    // This leaks memory but it should never be run unless we have a bug elsewhere in the code.
-    const wcstring d = format_string(L"unknown_keyword_%ld", static_cast(type));
-    wchar_t *d2 = new wchar_t[d.size() + 1];
-    // cppcheck-suppress memleak
-    return std::wcscpy(d2, d.c_str());
+    const wchar_t *keyword = enum_to_str(type, keyword_enum_map);
+    if (keyword) return keyword;
+    return L"unknown_keyword";
 }
 
 static wcstring token_type_user_presentable_description(
@@ -330,8 +250,7 @@ static inline parse_token_type_t parse_token_type_from_tokenizer_token(
             break;
         }
         default: {
-            fprintf(stderr, "Bad token type %d passed to %s\n", (int)tokenizer_token_type,
-                    __FUNCTION__);
+            debug(0, "Bad token type %d passed to %s", (int)tokenizer_token_type, __FUNCTION__);
             DIE("bad token type");
             break;
         }
@@ -487,23 +406,22 @@ class parse_ll_t {
     }
 
     /// Pop from the top of the symbol stack, then push the given production, updating node counts.
-    /// Note that production_t has type "pointer to array" so some care is required.
-    inline void symbol_stack_pop_push_production(const production_t *production) {
+    /// Note that production_element_t has type "pointer to array" so some care is required.
+    inline void symbol_stack_pop_push_production(const production_element_t *production) {
         bool logit = false;
         if (logit) {
-            size_t count = 0;
-            fprintf(stderr, "Applying production:\n");
-            for (size_t i = 0; i < MAX_SYMBOLS_PER_PRODUCTION; i++) {
-                production_element_t elem = (*production)[i];
-                if (production_element_is_valid(elem)) {
-                    parse_token_type_t type = production_element_type(elem);
-                    parse_keyword_t keyword = production_element_keyword(elem);
-                    fprintf(stderr, "\t%ls <%ls>\n", token_type_description(type),
-                            keyword_description(keyword));
-                    count++;
-                }
+            int count = 0;
+            fwprintf(stderr, L"Applying production:\n");
+            for (int i = 0;; i++) {
+                production_element_t elem = production[i];
+                if (!production_element_is_valid(elem)) break;  // all done, bail out
+                parse_token_type_t type = production_element_type(elem);
+                parse_keyword_t keyword = production_element_keyword(elem);
+                fwprintf(stderr, L"\t%ls <%ls>\n", token_type_description(type),
+                         keyword_description(keyword));
+                count++;
             }
-            if (!count) fprintf(stderr, "\t\n");
+            if (!count) fwprintf(stderr, L"\t\n");
         }
 
         // Get the parent index. But we can't get the parent parse node yet, since it may be made
@@ -522,12 +440,9 @@ class parse_ll_t {
         representative_child.parent = parent_node_idx;
 
         node_offset_t child_count = 0;
-        for (size_t i = 0; i < MAX_SYMBOLS_PER_PRODUCTION; i++) {
-            production_element_t elem = (*production)[i];
-            if (!production_element_is_valid(elem)) {
-                break;  // all done, bail out
-            }
-
+        for (int i = 0;; i++) {
+            production_element_t elem = production[i];
+            if (!production_element_is_valid(elem)) break;  // all done, bail out
             // Append the parse node.
             representative_child.type = production_element_type(elem);
             nodes.push_back(representative_child);
@@ -550,7 +465,7 @@ class parse_ll_t {
         symbol_stack.reserve(symbol_stack.size() + child_count);
         node_offset_t idx = child_count;
         while (idx--) {
-            production_element_t elem = (*production)[idx];
+            production_element_t elem = production[idx];
             PARSE_ASSERT(production_element_is_valid(elem));
             symbol_stack.push_back(parse_stack_element_t(elem, child_start + idx));
         }
@@ -613,9 +528,9 @@ void parse_ll_t::dump_stack(void) const {
         }
     }
 
-    fprintf(stderr, "Stack dump (%zu elements):\n", symbol_stack.size());
+    fwprintf(stderr, L"Stack dump (%zu elements):\n", symbol_stack.size());
     for (size_t idx = 0; idx < stack_lines.size(); idx++) {
-        fprintf(stderr, "    %ls\n", stack_lines.at(idx).c_str());
+        fwprintf(stderr, L"    %ls\n", stack_lines.at(idx).c_str());
     }
 }
 #endif
@@ -678,15 +593,11 @@ void parse_ll_t::determine_node_ranges(void) {
 
 void parse_ll_t::acquire_output(parse_node_tree_t *output, parse_error_list_t *errors) {
     if (output != NULL) {
-        output->swap(this->nodes);
+        *output = std::move(this->nodes);
     }
-    this->nodes.clear();
-
     if (errors != NULL) {
-        errors->swap(this->errors);
+        *errors = std::move(this->errors);
     }
-    this->errors.clear();
-    this->symbol_stack.clear();
 }
 
 void parse_ll_t::parse_error(parse_token_t token, parse_error_code_t code, const wchar_t *fmt,
@@ -1003,7 +914,7 @@ bool parse_ll_t::top_node_handle_terminal_types(parse_token_t token) {
 void parse_ll_t::accept_tokens(parse_token_t token1, parse_token_t token2) {
     bool logit = false;
     if (logit) {
-        fprintf(stderr, "Accept token %ls\n", token1.describe().c_str());
+        fwprintf(stderr, L"Accept token %ls\n", token1.describe().c_str());
     }
     PARSE_ASSERT(token1.type >= FIRST_PARSE_TOKEN_TYPE);
 
@@ -1040,7 +951,7 @@ void parse_ll_t::accept_tokens(parse_token_t token1, parse_token_t token2) {
 
         if (top_node_handle_terminal_types(token1)) {
             if (logit) {
-                fprintf(stderr, "Consumed token %ls\n", token1.describe().c_str());
+                fwprintf(stderr, L"Consumed token %ls\n", token1.describe().c_str());
             }
             // consumed = true;
             break;
@@ -1053,7 +964,7 @@ void parse_ll_t::accept_tokens(parse_token_t token1, parse_token_t token2) {
         parse_stack_element_t &stack_elem = symbol_stack.back();
         parse_node_t &node = nodes.at(stack_elem.node_idx);
         parse_node_tag_t tag = 0;
-        const production_t *production =
+        const production_element_t *production =
             production_for_token(stack_elem.type, token1, token2, &tag);
         node.tag = tag;
         if (production == NULL) {
@@ -1088,23 +999,8 @@ void parse_ll_t::accept_tokens(parse_token_t token1, parse_token_t token2) {
 }
 
 // Given an expanded string, returns any keyword it matches.
-static parse_keyword_t keyword_with_name(const wchar_t *name) {
-    // Binary search on keyword_map. Start at 1 since 0 is keyword_none.
-    parse_keyword_t result = parse_keyword_none;
-    size_t left = 1, right = sizeof keyword_map / sizeof *keyword_map;
-    while (left < right) {
-        size_t mid = left + (right - left) / 2;
-        int cmp = wcscmp(name, keyword_map[mid].name);
-        if (cmp < 0) {
-            right = mid;  // name was smaller than mid
-        } else if (cmp > 0) {
-            left = mid + 1;  // name was larger than mid
-        } else {
-            result = keyword_map[mid].keyword;  // found it
-            break;
-        }
-    }
-    return result;
+static inline parse_keyword_t keyword_with_name(const wchar_t *name) {
+    return str_to_enum(name, keyword_enum_map, keyword_enum_map_len);
 }
 
 static bool is_keyword_char(wchar_t c) {
@@ -1275,8 +1171,8 @@ bool parse_tree_from_string(const wcstring &str, parse_tree_flags_t parse_flags,
 
 #if 0
     //wcstring result = dump_tree(this->parser->nodes, str);
-    //fprintf(stderr, "Tree (%ld nodes):\n%ls", this->parser->nodes.size(), result.c_str());
-    fprintf(stderr, "%lu nodes, node size %lu, %lu bytes\n", output->size(), sizeof(parse_node_t),
+    //fwprintf(stderr, L"Tree (%ld nodes):\n%ls", this->parser->nodes.size(), result.c_str());
+    fwprintf(stderr, L"%lu nodes, node size %lu, %lu bytes\n", output->size(), sizeof(parse_node_t),
             output->size() * sizeof(parse_node_t));
 #endif
 
@@ -1420,10 +1316,12 @@ bool parse_node_tree_t::argument_list_is_root(const parse_node_t &node) const {
 enum parse_statement_decoration_t parse_node_tree_t::decoration_for_plain_statement(
     const parse_node_t &node) const {
     assert(node.type == symbol_plain_statement);
+    parse_statement_decoration_t decoration = parse_statement_decoration_none;
     const parse_node_t *decorated_statement = this->get_parent(node, symbol_decorated_statement);
-    parse_node_tag_t tag =
-        decorated_statement ? decorated_statement->tag : parse_statement_decoration_none;
-    return static_cast(tag);
+    if (decorated_statement) {
+        decoration = static_cast(decorated_statement->tag);
+    }
+    return decoration;
 }
 
 bool parse_node_tree_t::command_for_plain_statement(const parse_node_t &node, const wcstring &src,
diff --git a/src/parse_tree.h b/src/parse_tree.h
index 0582fc947..c5652cff0 100644
--- a/src/parse_tree.h
+++ b/src/parse_tree.h
@@ -20,7 +20,7 @@ typedef uint32_t node_offset_t;
 
 typedef uint32_t source_offset_t;
 
-#define SOURCE_OFFSET_INVALID (static_cast(-1))
+constexpr source_offset_t SOURCE_OFFSET_INVALID = static_cast(-1);
 
 /// A struct representing the token type that we use internally.
 struct parse_token_t {
@@ -140,8 +140,10 @@ class parse_node_t {
 class parse_node_tree_t : public std::vector {
    public:
     parse_node_tree_t() {}
-
-    parse_node_tree_t(moved_ref t) { this->swap(t.val); }
+    parse_node_tree_t(parse_node_tree_t &&) = default;
+    parse_node_tree_t &operator=(parse_node_tree_t &&) = default;
+    parse_node_tree_t(const parse_node_tree_t &) = delete;             // no copying
+    parse_node_tree_t &operator=(const parse_node_tree_t &) = delete;  // no copying
 
     // Get the node corresponding to a child of the given node, or NULL if there is no such child.
     // If expected_type is provided, assert that the node has that type.
diff --git a/src/parse_util.cpp b/src/parse_util.cpp
index 5e84f2fcf..f0a6177c8 100644
--- a/src/parse_util.cpp
+++ b/src/parse_util.cpp
@@ -204,9 +204,9 @@ static int parse_util_locate_brackets_range(const wcstring &str, size_t *inout_c
     // The command substitutions must not be NULL and must be in the valid pointer range, and
     // the end must be bigger than the beginning.
     assert(bracket_range_begin != NULL && bracket_range_begin >= valid_range_start &&
-            bracket_range_begin <= valid_range_end);
+           bracket_range_begin <= valid_range_end);
     assert(bracket_range_end != NULL && bracket_range_end > bracket_range_begin &&
-            bracket_range_end >= valid_range_start && bracket_range_end <= valid_range_end);
+           bracket_range_end >= valid_range_start && bracket_range_end <= valid_range_end);
 
     // Assign the substring to the out_contents.
     const wchar_t *interior_begin = bracket_range_begin + 1;
@@ -347,8 +347,6 @@ void parse_util_token_extent(const wchar_t *buff, size_t cursor_pos, const wchar
 
     CHECK(buff, );
 
-    assert(cursor_pos >= 0);
-
     const wchar_t *cmdsubst_begin, *cmdsubst_end;
     parse_util_cmdsubst_extent(buff, cursor_pos, &cmdsubst_begin, &cmdsubst_end);
 
@@ -492,7 +490,7 @@ void parse_util_get_parameter_info(const wcstring &cmd, const size_t pos, wchar_
     bool finished = cmdlen != 0;
     if (finished) {
         finished = (quote == NULL);
-        if (finished && wcschr(L" \t\n\r", cmd_tmp[cmdlen - 1]) != L'\0') {
+        if (finished && wcschr(L" \t\n\r", cmd_tmp[cmdlen - 1])) {
             finished = cmdlen > 1 && cmd_tmp[cmdlen - 2] == L'\\';
         }
     }
@@ -834,20 +832,18 @@ void parse_util_expand_variable_error(const wcstring &token, size_t global_token
 
     switch (char_after_dollar) {
         case BRACKET_BEGIN:
-        case L'{':
-
-        {
+        case L'{': {
             // The BRACKET_BEGIN is for unquoted, the { is for quoted. Anyways we have (possible
             // quoted) ${. See if we have a }, and the stuff in between is variable material. If so,
             // report a bracket error. Otherwise just complain about the ${.
             bool looks_like_variable = false;
             size_t closing_bracket =
-                token.find(char_after_dollar == L'{' ? L'}' : BRACKET_END, dollar_pos + 2);
+                token.find(char_after_dollar == L'{' ? L'}' : wchar_t(BRACKET_END), dollar_pos + 2);
             wcstring var_name;
             if (closing_bracket != wcstring::npos) {
                 size_t var_start = dollar_pos + 2, var_end = closing_bracket;
                 var_name = wcstring(token, var_start, var_end - var_start);
-                looks_like_variable = !var_name.empty() && wcsvarname(var_name.c_str()) == NULL;
+                looks_like_variable = wcsvarname(var_name) == NULL;
             }
             if (looks_like_variable) {
                 append_syntax_error(
@@ -859,7 +855,6 @@ void parse_util_expand_variable_error(const wcstring &token, size_t global_token
             }
             break;
         }
-
         case INTERNAL_SEPARATOR: {
             // e.g.: echo foo"$"baz
             // These are only ever quotes, not command substitutions. Command substitutions are
@@ -867,7 +862,6 @@ void parse_util_expand_variable_error(const wcstring &token, size_t global_token
             append_syntax_error(errors, global_dollar_pos, ERROR_NO_VAR_NAME);
             break;
         }
-
         case '(': {
             // e.g.: 'echo "foo$(bar)baz"
             // Try to determine what's in the parens.
@@ -888,12 +882,10 @@ void parse_util_expand_variable_error(const wcstring &token, size_t global_token
                                 truncate_string(token_after_parens).c_str());
             break;
         }
-
         case L'\0': {
             append_syntax_error(errors, global_dollar_pos, ERROR_NO_VAR_NAME);
             break;
         }
-
         default: {
             wchar_t token_stop_char = char_after_dollar;
             // Unescape (see issue #50).
@@ -971,12 +963,10 @@ parser_test_error_bits_t parse_util_detect_errors_in_argument(const parse_node_t
                 }
                 return err;
             }
-
             case 0: {
                 do_loop = 0;
                 break;
             }
-
             case 1: {
                 const wcstring subst(paran_begin + 1, paran_end);
 
@@ -1040,13 +1030,12 @@ parser_test_error_bits_t parse_util_detect_errors_in_argument(const parse_node_t
             if (out_errors) {
                 // We have something like $$$^....  Back up until we reach the first $.
                 size_t first_dollar = idx;
-                while (first_dollar > 0 &&
-                        (unesc.at(first_dollar - 1) == VARIABLE_EXPAND ||
-                        unesc.at(first_dollar - 1) == VARIABLE_EXPAND_SINGLE)) {
+                while (first_dollar > 0 && (unesc.at(first_dollar - 1) == VARIABLE_EXPAND ||
+                                            unesc.at(first_dollar - 1) == VARIABLE_EXPAND_SINGLE)) {
                     first_dollar--;
                 }
                 parse_util_expand_variable_error(unesc, node.source_start, first_dollar,
-                                                    out_errors);
+                                                 out_errors);
             }
         }
     }
@@ -1174,13 +1163,13 @@ parser_test_error_bits_t parse_util_detect_errors(const wcstring &buff_src,
                             parse_bool_statement_type_t bool_type =
                                 parse_node_tree_t::statement_boolean_type(*spec_statement);
                             if (bool_type == parse_bool_and) {  // this is not allowed
-                                    errored = append_syntax_error(
-                                        &parse_errors, spec_statement->source_start,
-                                        BOOL_AFTER_BACKGROUND_ERROR_MSG, L"and");
+                                errored =
+                                    append_syntax_error(&parse_errors, spec_statement->source_start,
+                                                        BOOL_AFTER_BACKGROUND_ERROR_MSG, L"and");
                             } else if (bool_type == parse_bool_or) {  // this is not allowed
-                                    errored = append_syntax_error(
-                                        &parse_errors, spec_statement->source_start,
-                                        BOOL_AFTER_BACKGROUND_ERROR_MSG, L"or");
+                                errored =
+                                    append_syntax_error(&parse_errors, spec_statement->source_start,
+                                                        BOOL_AFTER_BACKGROUND_ERROR_MSG, L"or");
                             }
                             break;
                         }
@@ -1302,11 +1291,11 @@ parser_test_error_bits_t parse_util_detect_errors(const wcstring &buff_src,
     if (has_unclosed_block || has_unclosed_quote) res |= PARSER_TEST_INCOMPLETE;
 
     if (out_errors != NULL) {
-        out_errors->swap(parse_errors);
+        *out_errors = std::move(parse_errors);
     }
 
     if (out_tree != NULL) {
-        out_tree->swap(node_tree);
+        *out_tree = std::move(node_tree);
     }
 
     return res;
diff --git a/src/parser.cpp b/src/parser.cpp
index 914fcf036..0a3194cc2 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -3,7 +3,6 @@
 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -42,9 +41,6 @@ class io_chain_t;
 /// If block description.
 #define IF_BLOCK N_(L"'if' conditional block")
 
-/// Function definition block description.
-#define FUNCTION_DEF_BLOCK N_(L"function definition block")
-
 /// Function invocation block description.
 #define FUNCTION_CALL_BLOCK N_(L"function invocation block")
 
@@ -54,9 +50,6 @@ class io_chain_t;
 /// Switch block description.
 #define SWITCH_BLOCK N_(L"'switch' block")
 
-/// Fake block description.
-#define FAKE_BLOCK N_(L"unexecutable block")
-
 /// Top block description.
 #define TOP_BLOCK N_(L"global root block")
 
@@ -90,11 +83,9 @@ static const struct block_lookup_entry block_lookup[] = {
     {WHILE, L"while", WHILE_BLOCK},
     {FOR, L"for", FOR_BLOCK},
     {IF, L"if", IF_BLOCK},
-    {FUNCTION_DEF, L"function", FUNCTION_DEF_BLOCK},
     {FUNCTION_CALL, 0, FUNCTION_CALL_BLOCK},
     {FUNCTION_CALL_NO_SHADOW, 0, FUNCTION_CALL_NO_SHADOW_BLOCK},
     {SWITCH, L"switch", SWITCH_BLOCK},
-    {FAKE, 0, FAKE_BLOCK},
     {TOP, 0, TOP_BLOCK},
     {SUBST, 0, SUBST_BLOCK},
     {BEGIN, L"begin", BEGIN_BLOCK},
@@ -110,17 +101,15 @@ static wcstring user_presentable_path(const wcstring &path) {
 
 parser_t::parser_t() : cancellation_requested(false), is_within_fish_initialization(false) {}
 
-/// A pointer to the principal parser (which is a static local).
-static parser_t *s_principal_parser = NULL;
+// Out of line destructor to enable forward declaration of parse_execution_context_t
+parser_t::~parser_t() {}
+
+static parser_t s_principal_parser;
 
 parser_t &parser_t::principal_parser(void) {
     ASSERT_IS_NOT_FORKED_CHILD();
     ASSERT_IS_MAIN_THREAD();
-    static parser_t parser;
-    if (!s_principal_parser) {
-        s_principal_parser = &parser;
-    }
-    return parser;
+    return s_principal_parser;
 }
 
 void parser_t::set_is_within_fish_initialization(bool flag) {
@@ -129,17 +118,12 @@ void parser_t::set_is_within_fish_initialization(bool flag) {
 
 void parser_t::skip_all_blocks(void) {
     // Tell all blocks to skip.
-    if (s_principal_parser) {
-        s_principal_parser->cancellation_requested = true;
-
-        // write(2, "Cancelling blocks\n", strlen("Cancelling blocks\n"));
-        for (size_t i = 0; i < s_principal_parser->block_count(); i++) {
-            s_principal_parser->block_at_index(i)->skip = true;
-        }
-    }
+    // This may be called from a signal handler!
+    s_principal_parser.cancellation_requested = true;
 }
 
-void parser_t::push_block(block_t *new_current) {
+// Given a new-allocated block, push it onto our block stack, acquiring ownership
+void parser_t::push_block_int(block_t *new_current) {
     const enum block_type_t type = new_current->type();
     new_current->src_lineno = parser_t::get_lineno();
 
@@ -148,61 +132,52 @@ void parser_t::push_block(block_t *new_current) {
         new_current->src_filename = intern(filename);
     }
 
+    // New blocks should be skipped if the outer block is skipped, except TOP and SUBST block, which
+    // open up new environments.
     const block_t *old_current = this->current_block();
-    if (old_current && old_current->skip) {
-        new_current->skip = true;
-    }
-
-    // New blocks should be skipped if the outer block is skipped, except TOP ans SUBST block, which
-    // open up new environments. Fake blocks should always be skipped. Rather complicated... :-(
-    new_current->skip = old_current ? old_current->skip : 0;
+    new_current->skip = old_current && old_current->skip;
 
     // Type TOP and SUBST are never skipped.
     if (type == TOP || type == SUBST) {
-        new_current->skip = 0;
+        new_current->skip = false;
     }
 
-    // Fake blocks and function definition blocks are never executed.
-    if (type == FAKE || type == FUNCTION_DEF) {
-        new_current->skip = 1;
-    }
-
-    new_current->job = 0;
+    new_current->job = nullptr;
     new_current->loop_status = LOOP_NORMAL;
 
-    this->block_stack.push_back(new_current);
+    // Push it onto our stack. This acquires ownership because of unique_ptr.
+    this->block_stack.emplace_back(new_current);
 
     // Types TOP and SUBST are not considered blocks for the purposes of `status -b`.
     if (type != TOP && type != SUBST) {
         is_block = 1;
     }
 
-    if ((new_current->type() != FUNCTION_DEF) && (new_current->type() != FAKE) &&
-        (new_current->type() != TOP)) {
+    if (new_current->type() != TOP) {
         env_push(type == FUNCTION_CALL);
         new_current->wants_pop_env = true;
     }
 }
 
-void parser_t::pop_block() {
+void parser_t::pop_block(const block_t *expected) {
+    assert(expected == this->current_block());
     if (block_stack.empty()) {
         debug(1, L"function %s called on empty block stack.", __func__);
         bugreport();
         return;
     }
 
-    block_t *old = block_stack.back();
+    // acquire ownership out of the block stack
+    // this will trigger deletion when it goes out of scope
+    std::unique_ptr old = std::move(block_stack.back());
     block_stack.pop_back();
 
     if (old->wants_pop_env) env_pop();
 
-    delete old;
-
     // Figure out if `status -b` should consider us to be in a block now.
     int new_is_block = 0;
-    for (std::vector::const_iterator it = block_stack.begin(), end = block_stack.end();
-         it != end; ++it) {
-        const enum block_type_t type = (*it)->type();
+    for (const auto &b : block_stack) {
+        const enum block_type_t type = b->type();
         if (type != TOP && type != SUBST) {
             new_is_block = 1;
             break;
@@ -211,11 +186,6 @@ void parser_t::pop_block() {
     is_block = new_is_block;
 }
 
-void parser_t::pop_block(const block_t *expected) {
-    assert(expected == this->current_block());
-    this->pop_block();
-}
-
 const wchar_t *parser_t::get_block_desc(int block) const {
     for (size_t i = 0; block_lookup[i].desc; i++) {
         if (block_lookup[i].type == block) {
@@ -248,35 +218,35 @@ wcstring parser_t::block_stack_description() const {
 const block_t *parser_t::block_at_index(size_t idx) const {
     // Zero corresponds to the last element in our vector.
     size_t count = block_stack.size();
-    return idx < count ? block_stack.at(count - idx - 1) : NULL;
+    return idx < count ? block_stack.at(count - idx - 1).get() : NULL;
 }
 
 block_t *parser_t::block_at_index(size_t idx) {
     size_t count = block_stack.size();
-    return idx < count ? block_stack.at(count - idx - 1) : NULL;
+    return idx < count ? block_stack.at(count - idx - 1).get() : NULL;
 }
 
-block_t *parser_t::current_block() { return block_stack.empty() ? NULL : block_stack.back(); }
+block_t *parser_t::current_block() { return block_stack.empty() ? NULL : block_stack.back().get(); }
 
 void parser_t::forbid_function(const wcstring &function) { forbidden_function.push_back(function); }
 
 void parser_t::allow_function() { forbidden_function.pop_back(); }
 
 /// Print profiling information to the specified stream.
-static void print_profile(const std::vector &items, FILE *out) {
+static void print_profile(const std::vector> &items, FILE *out) {
     for (size_t pos = 0; pos < items.size(); pos++) {
         const profile_item_t *me, *prev;
         size_t i;
         int my_time;
 
-        me = items.at(pos);
+        me = items.at(pos).get();
         if (me->skipped) {
             continue;
         }
 
         my_time = me->parse + me->exec;
         for (i = pos + 1; i < items.size(); i++) {
-            prev = items.at(i);
+            prev = items.at(i).get();
             if (prev->skipped) {
                 continue;
             }
@@ -510,7 +480,7 @@ wcstring parser_t::current_line() {
     if (execution_contexts.empty()) {
         return wcstring();
     }
-    const parse_execution_context_t *context = execution_contexts.back();
+    const parse_execution_context_t *context = execution_contexts.back().get();
     assert(context != NULL);
 
     int source_offset = context->get_current_source_offset();
@@ -553,17 +523,18 @@ wcstring parser_t::current_line() {
     return line_info;
 }
 
-void parser_t::job_add(job_t *job) {
+void parser_t::job_add(shared_ptr job) {
     assert(job != NULL);
-    assert(job->first_process != NULL);
-    this->my_job_list.push_front(job);
+    assert(!job->processes.empty());
+    this->my_job_list.push_front(std::move(job));
 }
 
-bool parser_t::job_remove(job_t *j) {
-    job_list_t::iterator iter = std::find(my_job_list.begin(), my_job_list.end(), j);
-    if (iter != my_job_list.end()) {
-        my_job_list.erase(iter);
-        return true;
+bool parser_t::job_remove(job_t *job) {
+    for (auto iter = my_job_list.begin(); iter != my_job_list.end(); ++iter) {
+        if (iter->get() == job) {
+            my_job_list.erase(iter);
+            return true;
+        }
     }
 
     debug(1, _(L"Job inconsistency"));
@@ -572,7 +543,12 @@ bool parser_t::job_remove(job_t *j) {
 }
 
 void parser_t::job_promote(job_t *job) {
-    job_list_t::iterator loc = std::find(my_job_list.begin(), my_job_list.end(), job);
+    job_list_t::iterator loc;
+    for (loc = my_job_list.begin(); loc != my_job_list.end(); ++loc) {
+        if (loc->get() == job) {
+            break;
+        }
+    }
     assert(loc != my_job_list.end());
 
     // Move the job to the beginning.
@@ -580,10 +556,8 @@ void parser_t::job_promote(job_t *job) {
 }
 
 job_t *parser_t::job_get(job_id_t id) {
-    job_iterator_t jobs(my_job_list);
-    job_t *job;
-    while ((job = jobs.next())) {
-        if (id <= 0 || job->job_id == id) return job;
+    for (const auto &job : my_job_list) {
+        if (id <= 0 || job->job_id == id) return job.get();
     }
     return NULL;
 }
@@ -598,10 +572,10 @@ job_t *parser_t::job_get_from_pid(int pid) {
 }
 
 profile_item_t *parser_t::create_profile_item() {
-    profile_item_t *result = NULL;
+    profile_item_t *result = nullptr;
     if (g_profiling_active) {
-        result = new profile_item_t();
-        profile_items.push_back(result);
+        profile_items.push_back(make_unique());
+        result = profile_items.back().get();
     }
     return result;
 }
@@ -616,19 +590,18 @@ int parser_t::eval(const wcstring &cmd, const io_chain_t &io, enum block_type_t
         this->get_backtrace(cmd, error_list, &backtrace_and_desc);
 
         // Print it.
-        fprintf(stderr, "%ls", backtrace_and_desc.c_str());
-
+        fwprintf(stderr, L"%ls\n", backtrace_and_desc.c_str());
         return 1;
     }
-    return this->eval_acquiring_tree(cmd, io, block_type, moved_ref(tree));
+    return this->eval(cmd, io, block_type, std::move(tree));
 }
 
-int parser_t::eval_acquiring_tree(const wcstring &cmd, const io_chain_t &io,
-                                  enum block_type_t block_type, moved_ref tree) {
+int parser_t::eval(const wcstring &cmd, const io_chain_t &io, enum block_type_t block_type,
+                   parse_node_tree_t tree) {
     CHECK_BLOCK(1);
     assert(block_type == TOP || block_type == SUBST);
 
-    if (tree.val.empty()) {
+    if (tree.empty()) {
         return 0;
     }
 
@@ -640,17 +613,16 @@ int parser_t::eval_acquiring_tree(const wcstring &cmd, const io_chain_t &io,
         (execution_contexts.empty() ? -1 : execution_contexts.back()->current_eval_level());
 
     // Append to the execution context stack.
-    parse_execution_context_t *ctx =
-        new parse_execution_context_t(tree, cmd, this, exec_eval_level);
-    execution_contexts.push_back(ctx);
+    execution_contexts.push_back(
+        make_unique(std::move(tree), cmd, this, exec_eval_level));
+    const parse_execution_context_t *ctx = execution_contexts.back().get();
 
     // Execute the first node.
     this->eval_block_node(0, io, block_type);
 
     // Clean up the execution context stack.
-    assert(!execution_contexts.empty() && execution_contexts.back() == ctx);
+    assert(!execution_contexts.empty() && execution_contexts.back().get() == ctx);
     execution_contexts.pop_back();
-    delete ctx;
 
     return 0;
 }
@@ -661,7 +633,7 @@ int parser_t::eval_block_node(node_offset_t node_idx, const io_chain_t &io,
     // the topmost execution context's tree. What happens if two trees were to be interleaved?
     // Fortunately that cannot happen (yet); in the future we probably want some sort of reference
     // counted trees.
-    parse_execution_context_t *ctx = execution_contexts.back();
+    parse_execution_context_t *ctx = execution_contexts.back().get();
     assert(ctx != NULL);
 
     CHECK_BLOCK(1);
@@ -685,23 +657,10 @@ int parser_t::eval_block_node(node_offset_t node_idx, const io_chain_t &io,
 
     job_reap(0);  // not sure why we reap jobs here
 
-    /* Start it up */
-    const block_t *const start_current_block = current_block();
-    block_t *scope_block = new scope_block_t(block_type);
-    this->push_block(scope_block);
+    // Start it up
+    scope_block_t *scope_block = this->push_block(block_type);
     int result = ctx->eval_node_at_offset(node_idx, scope_block, io);
-
-    // Clean up the block stack.
-    this->pop_block();
-    while (start_current_block != current_block()) {
-        if (current_block() == NULL) {
-            debug(0, _(L"End of block mismatch. Program terminating."));
-            bugreport();
-            FATAL_EXIT();
-            break;
-        }
-        this->pop_block();
-    }
+    this->pop_block(scope_block);
 
     job_reap(0);  // reap again
 
@@ -797,7 +756,7 @@ void parser_t::get_backtrace(const wcstring &src, const parse_error_list_t &erro
 
 block_t::block_t(block_type_t t)
     : block_type(t),
-      skip(),
+      skip(false),
       tok_pos(),
       node_offset(NODE_OFFSET_INVALID),
       loop_status(LOOP_NORMAL),
@@ -824,10 +783,6 @@ wcstring block_t::description() const {
             result.append(L"if");
             break;
         }
-        case FUNCTION_DEF: {
-            result.append(L"function_def");
-            break;
-        }
         case FUNCTION_CALL: {
             result.append(L"function_call");
             break;
@@ -840,10 +795,6 @@ wcstring block_t::description() const {
             result.append(L"switch");
             break;
         }
-        case FAKE: {
-            result.append(L"fake");
-            break;
-        }
         case SUBST: {
             result.append(L"substitution");
             break;
@@ -896,8 +847,6 @@ while_block_t::while_block_t() : block_t(WHILE) {}
 
 switch_block_t::switch_block_t() : block_t(SWITCH) {}
 
-fake_block_t::fake_block_t() : block_t(FAKE) {}
-
 scope_block_t::scope_block_t(block_type_t type) : block_t(type) {
     assert(type == BEGIN || type == TOP || type == SUBST);
 }
diff --git a/src/parser.h b/src/parser.h
index 301665ac1..4baec50b6 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -40,11 +40,9 @@ enum block_type_t {
     WHILE,                    /// While loop block
     FOR,                      /// For loop block
     IF,                       /// If block
-    FUNCTION_DEF,             /// Function definition block
     FUNCTION_CALL,            /// Function invocation block
     FUNCTION_CALL_NO_SHADOW,  /// Function invocation block with no variable shadowing
     SWITCH,                   /// Switch block
-    FAKE,                     /// Fake block
     SUBST,                    /// Command substitution scope
     TOP,                      /// Outermost block
     BEGIN,                    /// Unconditional block
@@ -80,7 +78,7 @@ struct block_t {
     /// Status for the current loop block. Can be any of the values from the loop_status enum.
     enum loop_status_t loop_status;
     /// The job that is currently evaluated in the specified block.
-    job_t *job;
+    shared_ptr job;
     /// Name of file that created this block. This string is intern'd.
     const wchar_t *src_filename;
     /// Line number where this block was created.
@@ -180,17 +178,17 @@ class parser_t {
 
    private:
     /// Indication that we should skip all blocks.
-    bool cancellation_requested;
+    volatile sig_atomic_t cancellation_requested;
     /// Indicates that we are within the process of initializing fish.
     bool is_within_fish_initialization;
-    /// Stack of execution contexts. We own these pointers and must delete them.
-    std::vector execution_contexts;
+    /// Stack of execution contexts.
+    std::vector> execution_contexts;
     /// List of called functions, used to help prevent infinite recursion.
     wcstring_list_t forbidden_function;
     /// The jobs associated with this parser.
     job_list_t my_job_list;
-    /// The list of blocks, allocated with new. It's our responsibility to delete these.
-    std::vector block_stack;
+    /// The list of blocks
+    std::vector> block_stack;
 
 #if 0
 // TODO: Lint says this isn't used (which is true). Should this be removed?
@@ -198,15 +196,18 @@ class parser_t {
     wcstring block_stack_description() const;
 #endif
 
-    /// List of profile items, allocated with new.
-    std::vector profile_items;
+    /// List of profile items
+    /// These are pointers because we return pointers to them to callers,
+    /// who may hold them across blocks (which would cause reallocations internal
+    /// to profile_items)
+    std::vector> profile_items;
 
     // No copying allowed.
     parser_t(const parser_t &);
     parser_t &operator=(const parser_t &);
 
     /// Adds a job to the beginning of the job list.
-    void job_add(job_t *job);
+    void job_add(shared_ptr job);
 
     /// Returns the name of the currently evaluated function if we are currently evaluating a
     /// function, null otherwise. This is tested by moving down the block-scope-stack, checking
@@ -216,6 +217,9 @@ class parser_t {
     /// Helper for stack_trace().
     void stack_trace_internal(size_t block_idx, wcstring *out) const;
 
+    /// Helper for push_block()
+    void push_block_int(block_t *b);
+
    public:
     /// Get the "principal" parser, whatever that is.
     static parser_t &principal_parser();
@@ -240,9 +244,8 @@ class parser_t {
     int eval(const wcstring &cmd, const io_chain_t &io, enum block_type_t block_type);
 
     /// Evaluate the expressions contained in cmd, which has been parsed into the given parse tree.
-    /// This takes ownership of the tree.
-    int eval_acquiring_tree(const wcstring &cmd, const io_chain_t &io, enum block_type_t block_type,
-                            moved_ref t);
+    int eval(const wcstring &cmd, const io_chain_t &io, enum block_type_t block_type,
+             parse_node_tree_t t);
 
     /// Evaluates a block node at the given node offset in the topmost execution context.
     int eval_block_node(node_offset_t node_idx, const io_chain_t &io, enum block_type_t block_type);
@@ -283,11 +286,15 @@ class parser_t {
     // know whether it's run during initialization or not.
     void set_is_within_fish_initialization(bool flag);
 
-    /// Pushes the block. pop_block will call delete on it.
-    void push_block(block_t *newv);
-
-    /// Remove the outermost block namespace.
-    void pop_block();
+    /// Pushes a new block created with the given arguments
+    /// Returns a pointer to the block. The pointer is valid
+    /// until the call to pop_block()
+    template 
+    BLOCKTYPE *push_block(Args &&... args) {
+        BLOCKTYPE *ret = new BLOCKTYPE(std::forward(args)...);
+        this->push_block_int(ret);
+        return ret;
+    }
 
     /// Remove the outermost block, asserting it's the given one.
     void pop_block(const block_t *b);
@@ -302,7 +309,7 @@ class parser_t {
     void job_promote(job_t *job);
 
     /// Return the job with the specified job id. If id is 0 or less, return the last job used.
-    job_t *job_get(int job_id);
+    job_t *job_get(job_id_t job_id);
 
     /// Returns the job with the given pid.
     job_t *job_get_from_pid(int pid);
@@ -336,6 +343,8 @@ class parser_t {
 
     /// Return a string representing the current stack trace.
     wcstring stack_trace() const;
+
+    ~parser_t();
 };
 
 #endif
diff --git a/src/path.cpp b/src/path.cpp
index e4775cec5..1aa0056ea 100644
--- a/src/path.cpp
+++ b/src/path.cpp
@@ -5,9 +5,12 @@
 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
+
 #include 
 #include 
 
@@ -69,7 +72,7 @@ static bool path_get_path_core(const wcstring &cmd, wcstring *out_path,
                 continue;
             }
             if (S_ISREG(buff.st_mode)) {
-                if (out_path) out_path->swap(nxt_path);
+                if (out_path) *out_path = std::move(nxt_path);
                 return true;
             }
             err = EACCES;
@@ -213,78 +216,101 @@ wcstring path_apply_working_directory(const wcstring &path, const wcstring &work
     return new_path;
 }
 
-static wcstring path_create_config() {
-    bool done = false;
-    wcstring res;
+/// We separate this from path_create() for two reasons. First it's only caused if there is a
+/// problem, and thus is not central to the behavior of that function. Second, we only want to issue
+/// the message once. If the current shell starts a new fish shell (e.g., by running `fish -c` from
+/// a function) we don't want that subshell to issue the same warnings.
+static void maybe_issue_path_warning(const wcstring &which_dir, const wcstring &custom_error_msg,
+                                     bool using_xdg, const wcstring &xdg_var, const wcstring &path,
+                                     int saved_errno) {
+    wcstring warning_var_name = L"_FISH_WARNED_" + which_dir;
+    if (env_exist(warning_var_name.c_str(), ENV_GLOBAL | ENV_EXPORT)) {
+        return;
+    }
+    env_set(warning_var_name, L"1", ENV_GLOBAL | ENV_EXPORT);
 
-    const env_var_t xdg_dir = env_get_string(L"XDG_CONFIG_HOME");
-    if (!xdg_dir.missing()) {
-        res = xdg_dir + L"/fish";
-        if (!create_directory(res)) {
-            done = true;
-        }
+    debug(0, custom_error_msg.c_str());
+    if (path.empty()) {
+        debug(0, _(L"Unable to locate the %ls directory."), which_dir.c_str());
+        debug(0, _(L"Please set the %ls or HOME environment variable "
+                   L"before starting fish."),
+              xdg_var.c_str());
     } else {
-        const env_var_t home = env_get_string(L"HOME");
-        if (!home.missing()) {
-            res = home + L"/.config/fish";
-            if (!create_directory(res)) {
-                done = true;
-            }
-        }
+        const wchar_t *env_var = using_xdg ? xdg_var.c_str() : L"HOME";
+        debug(0, _(L"Unable to locate %ls directory derived from $%ls: '%ls'."), which_dir.c_str(),
+              env_var, path.c_str());
+        debug(0, _(L"The error was '%s'."), strerror(saved_errno));
+        debug(0, _(L"Please set $%ls to a directory where you have write access."), env_var);
     }
-
-    if (!done) {
-        res.clear();
-
-        debug(0, _(L"Unable to create a configuration directory for fish. Your personal settings "
-                   L"will not be saved. Please set the $XDG_CONFIG_HOME variable to a directory "
-                   L"where the current user has write access."));
-    }
-    return res;
+    fputwc(L'\n', stderr);
 }
 
-static wcstring path_create_data() {
-    bool done = false;
-    wcstring res;
+static void path_create(wcstring &path, const wcstring &xdg_var, const wcstring &which_dir,
+                        const wcstring &custom_error_msg) {
+    bool path_done = false;
+    bool using_xdg = false;
+    int saved_errno = 0;
 
-    const env_var_t xdg_dir = env_get_string(L"XDG_DATA_HOME");
-    if (!xdg_dir.missing()) {
-        res = xdg_dir + L"/fish";
-        if (!create_directory(res)) {
-            done = true;
+    // The vars we fetch must be exported. Allowing them to be universal doesn't make sense and
+    // allowing that creates a lock inversion that deadlocks the shell since we're called before
+    // uvars are available.
+    const env_var_t xdg_dir = env_get_string(xdg_var, ENV_GLOBAL | ENV_EXPORT);
+    if (!xdg_dir.missing_or_empty()) {
+        using_xdg = true;
+        path = xdg_dir + L"/fish";
+        if (create_directory(path) != -1) {
+            path_done = true;
+        } else {
+            saved_errno = errno;
         }
     } else {
-        const env_var_t home = env_get_string(L"HOME");
-        if (!home.missing()) {
-            res = home + L"/.local/share/fish";
-            if (!create_directory(res)) {
-                done = true;
+        const env_var_t home = env_get_string(L"HOME", ENV_GLOBAL | ENV_EXPORT);
+        if (!home.missing_or_empty()) {
+            path = home + (which_dir == L"config" ? L"/.config/fish" : L"/.local/share/fish");
+            if (create_directory(path) != -1) {
+                path_done = true;
+            } else {
+                saved_errno = errno;
             }
         }
     }
 
-    if (!done) {
-        res.clear();
-
-        debug(0, _(L"Unable to create a data directory for fish. Your history will not be saved. "
-                   L"Please set the $XDG_DATA_HOME variable to a directory where the current user "
-                   L"has write access."));
+    if (!path_done) {
+        maybe_issue_path_warning(which_dir, custom_error_msg, using_xdg, xdg_var, path,
+                                 saved_errno);
+        path.clear();
     }
-    return res;
+
+    return;
 }
 
 /// Cache the config path.
 bool path_get_config(wcstring &path) {
-    static const wcstring result = path_create_config();
-    path = result;
-    return !result.empty();
+    static bool config_path_done = false;
+    static wcstring config_path(L"");
+
+    if (!config_path_done) {
+        path_create(config_path, L"XDG_CONFIG_HOME", L"config",
+                    _(L"Your personal settings will not be saved."));
+        config_path_done = true;
+    }
+
+    path = config_path;
+    return !config_path.empty();
 }
 
 /// Cache the data path.
 bool path_get_data(wcstring &path) {
-    static const wcstring result = path_create_data();
-    path = result;
-    return !result.empty();
+    static bool data_path_done = false;
+    static wcstring data_path(L"");
+
+    if (!data_path_done) {
+        data_path_done = true;
+        path_create(data_path, L"XDG_DATA_HOME", L"data", _(L"Your history will not be saved."));
+    }
+
+    path = data_path;
+    return !data_path.empty();
 }
 
 void path_make_canonical(wcstring &path) {
diff --git a/src/postfork.cpp b/src/postfork.cpp
index 792ee2917..8b6c0c24a 100644
--- a/src/postfork.cpp
+++ b/src/postfork.cpp
@@ -11,6 +11,7 @@
 #if FISH_USE_POSIX_SPAWN
 #include 
 #endif
+#include 
 
 #include "common.h"
 #include "exec.h"
@@ -58,10 +59,17 @@ static void debug_safe_int(int level, const char *format, int val) {
     debug_safe(level, format, buff);
 }
 
-int set_child_group(job_t *j, process_t *p, int print_errors) {
-    int res = 0;
+/// This function should be called by both the parent process and the child right after fork() has
+/// been called. If job control is enabled, the child is put in the jobs group, and if the child is
+/// also in the foreground, it is also given control of the terminal. When called in the parent
+/// process, this function may fail, since the child might have already finished and called exit.
+/// The parent process may safely ignore the exit status of this call.
+///
+/// Returns true on sucess, false on failiure.
+bool set_child_group(job_t *j, process_t *p, int print_errors) {
+    bool retval = true;
 
-    if (job_get_flag(j, JOB_CONTROL)) {
+    if (j->get_flag(JOB_CONTROL)) {
         if (!j->pgid) {
             j->pgid = p->pid;
         }
@@ -89,27 +97,35 @@ int set_child_group(job_t *j, process_t *p, int print_errors) {
                     pid_buff, argv0, job_id_buff, command, getpgid_buff, job_pgid_buff);
 
                 safe_perror("setpgid");
-                res = -1;
+                retval = false;
             }
         }
     } else {
         j->pgid = getpid();
     }
 
-    if (job_get_flag(j, JOB_TERMINAL) && job_get_flag(j, JOB_FOREGROUND)) {
-        int result = tcsetpgrp(0, j->pgid);
-        if (result == -1 && print_errors) {
-            char job_id_buff[64];
-            char command_buff[64];
-            format_long_safe(job_id_buff, j->job_id);
-            narrow_string_safe(command_buff, j->command_wcstr());
-            debug_safe(1, "Could not send job %s ('%s') to foreground", job_id_buff, command_buff);
-            safe_perror("tcsetpgrp");
-            res = -1;
+    if (j->get_flag(JOB_TERMINAL) && j->get_flag(JOB_FOREGROUND)) {  //!OCLINT(early exit)
+        int result = -1;
+        errno = EINTR;
+        while (result == -1 && errno == EINTR) {
+            result = tcsetpgrp(STDIN_FILENO, j->pgid);
+        }
+        if (result == -1) {
+            if (errno == ENOTTY) redirect_tty_output();
+            if (print_errors) {
+                char job_id_buff[64];
+                char command_buff[64];
+                format_long_safe(job_id_buff, j->job_id);
+                narrow_string_safe(command_buff, j->command_wcstr());
+                debug_safe(1, "Could not send job %s ('%s') to foreground", job_id_buff,
+                           command_buff);
+                safe_perror("tcsetpgrp");
+                retval = false;
+            }
         }
     }
 
-    return res;
+    return retval;
 }
 
 /// Set up a childs io redirections. Should only be called by setup_child_process(). Does the
@@ -130,7 +146,7 @@ static int handle_child_io(const io_chain_t &io_chain) {
 
         switch (io->io_mode) {
             case IO_CLOSE: {
-                if (log_redirections) fprintf(stderr, "%d: close %d\n", getpid(), io->fd);
+                if (log_redirections) fwprintf(stderr, L"%d: close %d\n", getpid(), io->fd);
                 if (close(io->fd)) {
                     debug_safe_int(0, "Failed to close file descriptor %s", io->fd);
                     safe_perror("close");
@@ -169,7 +185,7 @@ static int handle_child_io(const io_chain_t &io_chain) {
             case IO_FD: {
                 int old_fd = static_cast(io)->old_fd;
                 if (log_redirections)
-                    fprintf(stderr, "%d: fd dup %d to %d\n", getpid(), old_fd, io->fd);
+                    fwprintf(stderr, L"%d: fd dup %d to %d\n", getpid(), old_fd, io->fd);
 
                 // This call will sometimes fail, but that is ok, this is just a precausion.
                 close(io->fd);
@@ -189,14 +205,14 @@ static int handle_child_io(const io_chain_t &io_chain) {
                 // fd). If it's 1, we're connecting to the write end (second pipe fd).
                 unsigned int write_pipe_idx = (io_pipe->is_input ? 0 : 1);
 #if 0
-                debug( 0, L"%ls %ls on fd %d (%d %d)", write_pipe?L"write":L"read",
-                        (io->io_mode == IO_BUFFER)?L"buffer":L"pipe", io->fd, io->pipe_fd[0],
-                        io->pipe_fd[1]);
+                debug(0, L"%ls %ls on fd %d (%d %d)", write_pipe?L"write":L"read",
+                      (io->io_mode == IO_BUFFER)?L"buffer":L"pipe", io->fd, io->pipe_fd[0],
+                      io->pipe_fd[1]);
 #endif
                 if (log_redirections)
-                    fprintf(stderr, "%d: %s dup %d to %d\n", getpid(),
-                            io->io_mode == IO_BUFFER ? "buffer" : "pipe",
-                            io_pipe->pipe_fd[write_pipe_idx], io->fd);
+                    fwprintf(stderr, L"%d: %s dup %d to %d\n", getpid(),
+                             io->io_mode == IO_BUFFER ? "buffer" : "pipe",
+                             io_pipe->pipe_fd[write_pipe_idx], io->fd);
                 if (dup2(io_pipe->pipe_fd[write_pipe_idx], io->fd) != io->fd) {
                     debug_safe(1, LOCAL_PIPE_ERROR);
                     safe_perror("dup2");
@@ -217,7 +233,7 @@ int setup_child_process(job_t *j, process_t *p, const io_chain_t &io_chain) {
     bool ok = true;
 
     if (p) {
-        ok = (0 == set_child_group(j, p, 1));
+        ok = set_child_group(j, p, 1);
     }
 
     if (ok) {
@@ -301,7 +317,7 @@ bool fork_actions_make_spawn_properties(posix_spawnattr_t *attr,
 
     bool should_set_parent_group_id = false;
     int desired_parent_group_id = 0;
-    if (job_get_flag(j, JOB_CONTROL)) {
+    if (j->get_flag(JOB_CONTROL)) {
         should_set_parent_group_id = true;
 
         // PCA: I'm quite fuzzy on process groups, but I believe that the default value of 0 means
@@ -487,15 +503,23 @@ void safe_report_exec_error(int err, const char *actual_cmd, const char *const *
 /// Perform output from builtins. May be called from a forked child, so don't do anything that may
 /// allocate memory, etc.
 bool do_builtin_io(const char *out, size_t outlen, const char *err, size_t errlen) {
+    int saved_errno = 0;
     bool success = true;
     if (out && outlen && write_loop(STDOUT_FILENO, out, outlen) < 0) {
-        int e = errno;
-        debug_safe(0, "Error while writing to stdout");
-        safe_perror("write_loop");
+        saved_errno = errno;
+        if (errno != EPIPE) {
+            debug_safe(0, "Error while writing to stdout");
+            errno = saved_errno;
+            safe_perror("write_loop");
+        }
         success = false;
-        errno = e;
     }
 
-    if (err && errlen && write_loop(STDERR_FILENO, err, errlen) < 0) success = false;
+    if (err && errlen && write_loop(STDERR_FILENO, err, errlen) < 0) {
+        saved_errno = errno;
+        success = false;
+    }
+
+    errno = saved_errno;
     return success;
 }
diff --git a/src/postfork.h b/src/postfork.h
index c12053200..df0a74cba 100644
--- a/src/postfork.h
+++ b/src/postfork.h
@@ -17,14 +17,7 @@ class io_chain_t;
 class job_t;
 class process_t;
 
-/// This function should be called by both the parent process and the child right after fork() has
-/// been called. If job control is enabled, the child is put in the jobs group, and if the child is
-/// also in the foreground, it is also given control of the terminal. When called in the parent
-/// process, this function may fail, since the child might have already finished and called exit.
-/// The parent process may safely ignore the exit status of this call.
-///
-/// Returns 0 on sucess, -1 on failiure.
-int set_child_group(job_t *j, process_t *p, int print_errors);
+bool set_child_group(job_t *j, process_t *p, int print_errors);
 
 /// Initialize a new child process. This should be called right away after forking in the child
 /// process. If job control is enabled for this job, the process is put in the process group of the
diff --git a/src/proc.cpp b/src/proc.cpp
index 42850f6b7..a24d1d779 100644
--- a/src/proc.cpp
+++ b/src/proc.cpp
@@ -80,9 +80,9 @@ void print_jobs(void)
     job_iterator_t jobs;
     job_t *j;
     while (j = jobs.next()) {
-        printf("%p -> %ls -> (foreground %d, complete %d, stopped %d, constructed %d)\n",
-                j, j->command_wcstr(), job_get_flag(j, JOB_FOREGROUND), job_is_completed(j),
-                job_is_stopped(j), job_get_flag(j, JOB_CONSTRUCTED));
+        fwprintf(stdout, L"%p -> %ls -> (foreground %d, complete %d, stopped %d, constructed %d)\n",
+                 j, j->command_wcstr(), j->get_flag(JOB_FOREGROUND), job_is_completed(j),
+                 job_is_stopped(j), j->get_flag(JOB_CONSTRUCTED));
     }
 }
 #endif
@@ -138,18 +138,12 @@ void job_promote(job_t *job) {
     parser_t::principal_parser().job_promote(job);
 }
 
-/// Remove job from the job list and free all memory associated with it.
-void job_free(job_t *j) {
-    job_remove(j);
-    delete j;
-}
-
 void proc_destroy() {
     job_list_t &jobs = parser_t::principal_parser().job_list();
     while (!jobs.empty()) {
-        job_t *job = jobs.front();
+        job_t *job = jobs.front().get();
         debug(2, L"freeing leaked job %ls", job->command_wcstr());
-        job_free(job);
+        job_remove(job);
     }
 }
 
@@ -162,11 +156,11 @@ int proc_get_last_status() { return last_status; }
 
 // Basic thread safe job IDs. The vector consumed_job_ids has a true value wherever the job ID
 // corresponding to that slot is in use. The job ID corresponding to slot 0 is 1.
-static pthread_mutex_t job_id_lock = PTHREAD_MUTEX_INITIALIZER;
-static std::vector consumed_job_ids;
+static owning_lock> locked_consumed_job_ids;
 
 job_id_t acquire_job_id(void) {
-    scoped_lock locker(job_id_lock);
+    auto locker = locked_consumed_job_ids.acquire();
+    std::vector &consumed_job_ids = locker.value;
 
     // Find the index of the first 0 slot.
     std::vector::iterator slot =
@@ -185,7 +179,8 @@ job_id_t acquire_job_id(void) {
 
 void release_job_id(job_id_t jid) {
     assert(jid > 0);
-    scoped_lock locker(job_id_lock);
+    auto locker = locked_consumed_job_ids.acquire();
+    std::vector &consumed_job_ids = locker.value;
     size_t slot = (size_t)(jid - 1), count = consumed_job_ids.size();
 
     // Make sure this slot is within our vector and is currently set to consumed.
@@ -214,9 +209,7 @@ job_t *job_get_from_pid(int pid) {
 ///
 /// \param j the job to test
 int job_is_stopped(const job_t *j) {
-    process_t *p;
-
-    for (p = j->first_process; p; p = p->next) {
+    for (const process_ptr_t &p : j->processes) {
         if (!p->completed && !p->stopped) {
             return 0;
         }
@@ -228,9 +221,9 @@ int job_is_stopped(const job_t *j) {
 ///
 /// \param j the job to test
 bool job_is_completed(const job_t *j) {
-    assert(j->first_process != NULL);
+    assert(!j->processes.empty());
     bool result = true;
-    for (process_t *p = j->first_process; p != NULL; p = p->next) {
+    for (const process_ptr_t &p : j->processes) {
         if (!p->completed) {
             result = false;
             break;
@@ -239,15 +232,15 @@ bool job_is_completed(const job_t *j) {
     return result;
 }
 
-void job_set_flag(job_t *j, unsigned int flag, int set) {
+void job_t::set_flag(job_flag_t flag, bool set) {
     if (set) {
-        j->flags |= flag;
+        this->flags |= flag;
     } else {
-        j->flags &= ~flag;
+        this->flags &= ~flag;
     }
 }
 
-int job_get_flag(const job_t *j, unsigned int flag) { return static_cast(j->flags & flag); }
+bool job_t::get_flag(job_flag_t flag) const { return !!(this->flags & flag); }
 
 int job_signal(job_t *j, int signal) {
     pid_t my_pid = getpid();
@@ -256,7 +249,7 @@ int job_signal(job_t *j, int signal) {
     if (j->pgid != my_pid) {
         res = killpg(j->pgid, signal);
     } else {
-        for (process_t *p = j->first_process; p; p = p->next) {
+        for (const process_ptr_t &p : j->processes) {
             if (!p->completed && p->pid && kill(p->pid, signal)) {
                 res = -1;
                 break;
@@ -280,16 +273,19 @@ static void mark_process_status(process_t *p, int status) {
     } else {
         // This should never be reached.
         p->completed = 1;
-        fprintf(stderr, "Process %ld exited abnormally\n", (long)p->pid);
+        debug(1, "Process %ld exited abnormally", (long)p->pid);
     }
 }
 
-void job_mark_process_as_failed(const job_t *job, process_t *p) {
+void job_mark_process_as_failed(job_t *job, const process_t *failed_proc) {
     // The given process failed to even lift off (e.g. posix_spawn failed) and so doesn't have a
-    // valid pid. Mark it as dead.
-    UNUSED(job);
-    for (process_t *cursor = p; cursor != NULL; cursor = cursor->next) {
-        cursor->completed = 1;
+    // valid pid. Mark it and everything after it as dead.
+    bool found = false;
+    for (process_ptr_t &p : job->processes) {
+        found = found || (p.get() == failed_proc);
+        if (found) {
+            p->completed = true;
+        }
     }
 }
 
@@ -298,23 +294,22 @@ void job_mark_process_as_failed(const job_t *job, process_t *p) {
 /// \param pid the pid of the process whose status changes
 /// \param status the status as returned by wait
 static void handle_child_status(pid_t pid, int status) {
-    bool found_proc = false;
-    const job_t *j = NULL;
-    process_t *p = NULL;
+    job_t *j = NULL;
+    const process_t *found_proc = NULL;
 
     job_iterator_t jobs;
     while (!found_proc && (j = jobs.next())) {
-        process_t *prev = 0;
-        for (p = j->first_process; p; p = p->next) {
+        process_t *prev = NULL;
+        for (process_ptr_t &p : j->processes) {
             if (pid == p->pid) {
-                mark_process_status(p, status);
+                mark_process_status(p.get(), status);
                 if (p->completed && prev && !prev->completed && prev->pid) {
                     kill(prev->pid, SIGPIPE);
                 }
-                found_proc = true;
+                found_proc = p.get();
                 break;
             }
-            prev = p;
+            prev = p.get();
         }
     }
 
@@ -326,7 +321,7 @@ static void handle_child_status(pid_t pid, int status) {
     if (is_interactive_session) {
         // In an interactive session, tell the principal parser to skip all blocks we're executing
         // so control-C returns control to the user.
-        if (p && found_proc) parser_t::skip_all_blocks();
+        if (found_proc) parser_t::skip_all_blocks();
     } else {
         // Deliver the SIGINT or SIGQUIT signal to ourself since we're not interactive.
         struct sigaction act;
@@ -350,7 +345,9 @@ static void handle_child_status(pid_t pid, int status) {
 }
 
 process_t::process_t()
-    : type(),  // gets set later
+    : is_first_in_job(),
+      is_last_in_job(),
+      type(),  // gets set later
       internal_block_node(NODE_OFFSET_INVALID),
       pid(0),
       pipe_write_fd(0),
@@ -358,8 +355,7 @@ process_t::process_t()
       completed(0),
       stopped(0),
       status(0),
-      count_help_magic(0),
-      next(NULL)
+      count_help_magic(0)
 #ifdef HAVE__PROC_SELF_STAT
       ,
       last_time(),
@@ -368,20 +364,15 @@ process_t::process_t()
 {
 }
 
-process_t::~process_t() { delete this->next; }
-
 job_t::job_t(job_id_t jobid, const io_chain_t &bio)
-    : block_io(bio), first_process(NULL), pgid(0), tmodes(), job_id(jobid), flags(0) {}
+    : block_io(bio), pgid(0), tmodes(), job_id(jobid), flags(0) {}
 
-job_t::~job_t() {
-    delete first_process;
-    release_job_id(job_id);
-}
+job_t::~job_t() { release_job_id(job_id); }
 
 /// Return all the IO redirections. Start with the block IO, then walk over the processes.
 io_chain_t job_t::all_io_redirections() const {
     io_chain_t result = this->block_io;
-    for (process_t *p = this->first_process; p != NULL; p = p->next) {
+    for (const process_ptr_t &p : this->processes) {
         result.append(p->io_chain());
     }
     return result;
@@ -506,7 +497,7 @@ static void format_job_info(const job_t *j, const wchar_t *status, size_t job_co
     if (cur_term != NULL)
         tputs(clr_eol, 1, &writeb);
     else
-        fwprintf(stdout, L"\x1b[K");
+        fwprintf(stdout, L"\e[K");
     fwprintf(stdout, L"\n");
 }
 
@@ -552,12 +543,12 @@ int job_reap(bool allow_interactive) {
 
         // If we are reaping only jobs who do not need status messages sent to the console, do not
         // consider reaping jobs that need status messages.
-        if ((!job_get_flag(j, JOB_SKIP_NOTIFICATION)) && (!interactive) &&
-            (!job_get_flag(j, JOB_FOREGROUND))) {
+        if ((!j->get_flag(JOB_SKIP_NOTIFICATION)) && (!interactive) &&
+            (!j->get_flag(JOB_FOREGROUND))) {
             continue;
         }
 
-        for (process_t *p = j->first_process; p; p = p->next) {
+        for (const process_ptr_t &p : j->processes) {
             int s;
             if (!p->completed) continue;
 
@@ -575,9 +566,9 @@ int job_reap(bool allow_interactive) {
             }
 
             // Handle signals other than SIGPIPE.
-            int proc_is_job = ((p == j->first_process) && (p->next == 0));
-            if (proc_is_job) job_set_flag(j, JOB_NOTIFIED, 1);
-            if (job_get_flag(j, JOB_SKIP_NOTIFICATION)) {
+            int proc_is_job = (p->is_first_in_job && p->is_last_in_job);
+            if (proc_is_job) j->set_flag(JOB_NOTIFIED, true);
+            if (j->get_flag(JOB_SKIP_NOTIFICATION)) {
                 continue;
             }
 
@@ -590,7 +581,7 @@ int job_reap(bool allow_interactive) {
             // signals. If echoctl is on, then the terminal will have written ^C to the console.
             // If off, it won't have. We don't echo ^C either way, so as to respect the user's
             // preference.
-            if (WTERMSIG(p->status) != SIGINT || !job_get_flag(j, JOB_FOREGROUND)) {
+            if (WTERMSIG(p->status) != SIGINT || !j->get_flag(JOB_FOREGROUND)) {
                 if (proc_is_job) {
                     // We want to report the job number, unless it's the only job, in which case
                     // we don't need to.
@@ -613,7 +604,7 @@ int job_reap(bool allow_interactive) {
                 if (cur_term != NULL) {
                     tputs(clr_eol, 1, &writeb);
                 } else {
-                    fwprintf(stdout, L"\x1b[K");  // no term set up - do clr_eol manually
+                    fwprintf(stdout, L"\e[K");  // no term set up - do clr_eol manually
                 }
                 fwprintf(stdout, L"\n");
             }
@@ -624,22 +615,22 @@ int job_reap(bool allow_interactive) {
         // If all processes have completed, tell the user the job has completed and delete it from
         // the active job list.
         if (job_is_completed(j)) {
-            if (!job_get_flag(j, JOB_FOREGROUND) && !job_get_flag(j, JOB_NOTIFIED) &&
-                !job_get_flag(j, JOB_SKIP_NOTIFICATION)) {
+            if (!j->get_flag(JOB_FOREGROUND) && !j->get_flag(JOB_NOTIFIED) &&
+                !j->get_flag(JOB_SKIP_NOTIFICATION)) {
                 format_job_info(j, _(L"ended"), job_count);
                 found = 1;
             }
             proc_fire_event(L"JOB_EXIT", EVENT_EXIT, -j->pgid, 0);
             proc_fire_event(L"JOB_EXIT", EVENT_JOB_ID, j->job_id, 0);
 
-            job_free(j);
-        } else if (job_is_stopped(j) && !job_get_flag(j, JOB_NOTIFIED)) {
+            job_remove(j);
+        } else if (job_is_stopped(j) && !j->get_flag(JOB_NOTIFIED)) {
             // Notify the user about newly stopped jobs.
-            if (!job_get_flag(j, JOB_SKIP_NOTIFICATION)) {
+            if (!j->get_flag(JOB_SKIP_NOTIFICATION)) {
                 format_job_info(j, _(L"stopped"), job_count);
                 found = 1;
             }
-            job_set_flag(j, JOB_NOTIFIED, 1);
+            j->set_flag(JOB_NOTIFIED, true);
         }
     }
 
@@ -695,13 +686,12 @@ unsigned long proc_get_jiffies(process_t *p) {
 /// Update the CPU time for all jobs.
 void proc_update_jiffies() {
     job_t *job;
-    process_t *p;
     job_iterator_t j;
 
     for (job = j.next(); job; job = j.next()) {
-        for (p = job->first_process; p; p = p->next) {
+        for (process_ptr_t &p : job->processes) {
             gettimeofday(&p->last_time, 0);
-            p->last_jiffies = proc_get_jiffies(p);
+            p->last_jiffies = proc_get_jiffies(p.get());
         }
     }
 }
@@ -792,33 +782,49 @@ static void read_try(job_t *j) {
 /// \param cont If this variable is set, we are giving back control to a job that has previously
 /// been stopped. In that case, we need to set the terminal attributes to those saved in the job.
 static bool terminal_give_to_job(job_t *j, int cont) {
-    if (tcsetpgrp(0, j->pgid)) {
+    int result = -1;
+    errno = EINTR;
+    while (result == -1 && errno == EINTR) {
+        result = tcsetpgrp(STDIN_FILENO, j->pgid);
+    }
+    if (result == -1) {
+        if (errno == ENOTTY) redirect_tty_output();
         debug(1, _(L"Could not send job %d ('%ls') to foreground"), j->job_id, j->command_wcstr());
         wperror(L"tcsetpgrp");
         return false;
     }
 
-    if (cont && tcsetattr(0, TCSADRAIN, &j->tmodes)) {
-        debug(1, _(L"Could not send job %d ('%ls') to foreground"), j->job_id, j->command_wcstr());
-        wperror(L"tcsetattr");
-        return false;
+    if (cont) {
+        int result = -1;
+        errno = EINTR;
+        while (result == -1 && errno == EINTR) {
+            result = tcsetattr(STDIN_FILENO, TCSADRAIN, &j->tmodes);
+        }
+        if (result == -1) {
+            if (errno == ENOTTY) redirect_tty_output();
+            debug(1, _(L"terminal_give_to_job(): Could not send job %d ('%ls') to foreground"),
+                  j->job_id, j->command_wcstr());
+            wperror(L"tcsetattr");
+            return false;
+        }
     }
+
     return true;
 }
 
 /// Returns control of the terminal to the shell, and saves the terminal attribute state to the job,
 /// so that we can restore the terminal ownership to the job at a later time.
 static int terminal_return_from_job(job_t *j) {
-    if (tcsetpgrp(0, getpgrp())) {
+    if (tcsetpgrp(STDIN_FILENO, getpgrp()) == -1) {
+        if (errno == ENOTTY) redirect_tty_output();
         debug(1, _(L"Could not return shell to foreground"));
         wperror(L"tcsetpgrp");
         return 0;
     }
 
-    /*
-       Save jobs terminal modes.
-    */
-    if (tcgetattr(0, &j->tmodes)) {
+    // Save jobs terminal modes.
+    if (tcgetattr(STDIN_FILENO, &j->tmodes)) {
+        if (errno == EIO) redirect_tty_output();
         debug(1, _(L"Could not return shell to foreground"));
         wperror(L"tcgetattr");
         return 0;
@@ -830,7 +836,8 @@ static int terminal_return_from_job(job_t *j) {
 // https://github.com/fish-shell/fish-shell/issues/121
 #if 0
     // Restore the shell's terminal modes.
-    if (tcsetattr(0, TCSADRAIN, &shell_modes)) {
+    if (tcsetattr(STDIN_FILENO, TCSADRAIN, &shell_modes) == -1) {
+        if (errno == EIO) redirect_tty_output();
         debug(1, _(L"Could not return shell to foreground"));
         wperror(L"tcsetattr");
         return 0;
@@ -843,7 +850,7 @@ static int terminal_return_from_job(job_t *j) {
 void job_continue(job_t *j, bool cont) {
     // Put job first in the job list.
     job_promote(j);
-    job_set_flag(j, JOB_NOTIFIED, 0);
+    j->set_flag(JOB_NOTIFIED, false);
 
     CHECK_BLOCK();
 
@@ -852,7 +859,7 @@ void job_continue(job_t *j, bool cont) {
           is_interactive ? L"INTERACTIVE" : L"NON-INTERACTIVE");
 
     if (!job_is_completed(j)) {
-        if (job_get_flag(j, JOB_TERMINAL) && job_get_flag(j, JOB_FOREGROUND)) {
+        if (j->get_flag(JOB_TERMINAL) && j->get_flag(JOB_FOREGROUND)) {
             // Put the job into the foreground. Hack: ensure that stdin is marked as blocking first
             // (issue #176).
             make_fd_blocking(STDIN_FILENO);
@@ -868,17 +875,15 @@ void job_continue(job_t *j, bool cont) {
 
         // Send the job a continue signal, if necessary.
         if (cont) {
-            process_t *p;
+            for (process_ptr_t &p : j->processes) p->stopped = false;
 
-            for (p = j->first_process; p; p = p->next) p->stopped = 0;
-
-            if (job_get_flag(j, JOB_CONTROL)) {
+            if (j->get_flag(JOB_CONTROL)) {
                 if (killpg(j->pgid, SIGCONT)) {
                     wperror(L"killpg (SIGCONT)");
                     return;
                 }
             } else {
-                for (p = j->first_process; p; p = p->next) {
+                for (const process_ptr_t &p : j->processes) {
                     if (kill(p->pid, SIGCONT) < 0) {
                         wperror(L"kill (SIGCONT)");
                         return;
@@ -887,7 +892,7 @@ void job_continue(job_t *j, bool cont) {
             }
         }
 
-        if (job_get_flag(j, JOB_FOREGROUND)) {
+        if (j->get_flag(JOB_FOREGROUND)) {
             // Look for finished processes first, to avoid select() if it's already done.
             process_mark_finished_children(false);
 
@@ -924,7 +929,7 @@ void job_continue(job_t *j, bool cont) {
         }
     }
 
-    if (job_get_flag(j, JOB_FOREGROUND)) {
+    if (j->get_flag(JOB_FOREGROUND)) {
         if (job_is_completed(j)) {
             // It's possible that the job will produce output and exit before we've even read from
             // it.
@@ -935,21 +940,20 @@ void job_continue(job_t *j, bool cont) {
             // order!
             read_try(j);
 
-            process_t *p = j->first_process;
-            while (p->next) p = p->next;
+            const std::unique_ptr &p = j->processes.back();
 
             // Mark process status only if we are in the foreground and the last process in a pipe,
             // and it is not a short circuited builtin.
             if ((WIFEXITED(p->status) || WIFSIGNALED(p->status)) && p->pid) {
                 int status = proc_format_status(p->status);
-                // wprintf(L"setting status %d for %ls\n", job_get_flag( j, JOB_NEGATE
+                // fwprintf(stdout, L"setting status %d for %ls\n", job_get_flag( j, JOB_NEGATE
                 // )?!status:status, j->command);
-                proc_set_last_status(job_get_flag(j, JOB_NEGATE) ? !status : status);
+                proc_set_last_status(j->get_flag(JOB_NEGATE) ? !status : status);
             }
         }
 
         // Put the shell back in the foreground.
-        if (job_get_flag(j, JOB_TERMINAL) && job_get_flag(j, JOB_FOREGROUND)) {
+        if (j->get_flag(JOB_TERMINAL) && j->get_flag(JOB_FOREGROUND)) {
             int ok;
 
             signal_block();
@@ -973,20 +977,15 @@ int proc_format_status(int status) {
 }
 
 void proc_sanity_check() {
-    job_t *j;
-    job_t *fg_job = 0;
+    const job_t *fg_job = NULL;
 
     job_iterator_t jobs;
-    while ((j = jobs.next())) {
-        process_t *p;
-
-        if (!job_get_flag(j, JOB_CONSTRUCTED)) continue;
-
-        validate_pointer(j->first_process, _(L"Process list pointer"), 0);
+    while (const job_t *j = jobs.next()) {
+        if (!j->get_flag(JOB_CONSTRUCTED)) continue;
 
         // More than one foreground job?
-        if (job_get_flag(j, JOB_FOREGROUND) && !(job_is_stopped(j) || job_is_completed(j))) {
-            if (fg_job != 0) {
+        if (j->get_flag(JOB_FOREGROUND) && !(job_is_stopped(j) || job_is_completed(j))) {
+            if (fg_job) {
                 debug(0, _(L"More than one job in foreground: job 1: '%ls' job 2: '%ls'"),
                       fg_job->command_wcstr(), j->command_wcstr());
                 sanity_lose();
@@ -994,13 +993,11 @@ void proc_sanity_check() {
             fg_job = j;
         }
 
-        p = j->first_process;
-        while (p) {
+        for (const process_ptr_t &p : j->processes) {
             // Internal block nodes do not have argv - see issue #1545.
             bool null_ok = (p->type == INTERNAL_BLOCK_NODE);
             validate_pointer(p->get_argv(), _(L"Process argument list"), null_ok);
             validate_pointer(p->argv0(), _(L"Process name"), null_ok);
-            validate_pointer(p->next, _(L"Process list pointer"), true);
 
             if ((p->stopped & (~0x00000001)) != 0) {
                 debug(0, _(L"Job '%ls', process '%ls' has inconsistent state \'stopped\'=%d"),
@@ -1013,8 +1010,6 @@ void proc_sanity_check() {
                       j->command_wcstr(), p->argv0(), p->completed);
                 sanity_lose();
             }
-
-            p = p->next;
         }
     }
 }
diff --git a/src/proc.h b/src/proc.h
index 9649950aa..b75d20742 100644
--- a/src/proc.h
+++ b/src/proc.h
@@ -29,6 +29,9 @@
 /// The status code use when a wildcard had no matches.
 #define STATUS_UNMATCHED_WILDCARD 124
 
+/// The status code use when illegal command name is encountered.
+#define STATUS_ILLEGAL_CMD 123
+
 /// The status code used for normal exit in a  builtin.
 #define STATUS_BUILTIN_OK 0
 
@@ -87,7 +90,10 @@ class process_t {
 
    public:
     process_t();
-    ~process_t();
+
+    // Note whether we are the first and/or last in the job
+    bool is_first_in_job;
+    bool is_last_in_job;
 
     /// Type of process. Can be one of \c EXTERNAL, \c INTERNAL_BUILTIN, \c INTERNAL_FUNCTION, \c
     /// INTERNAL_EXEC.
@@ -137,8 +143,6 @@ class process_t {
     volatile int status;
     /// Special flag to tell the evaluation function for count to print the help information.
     int count_help_magic;
-    /// Next process in pipeline. We own this and we are responsible for deleting it.
-    process_t *next;
 #ifdef HAVE__PROC_SELF_STAT
     /// Last time of cpu time check.
     struct timeval last_time;
@@ -147,8 +151,11 @@ class process_t {
 #endif
 };
 
+typedef std::unique_ptr process_ptr_t;
+typedef std::vector process_list_t;
+
 /// Constants for the flag variable in the job struct.
-enum {
+enum job_flag_t {
     /// Whether the user has been told about stopped job.
     JOB_NOTIFIED = 1 << 0,
     /// Whether this job is in the foreground.
@@ -182,8 +189,8 @@ class job_t {
     const io_chain_t block_io;
 
     // No copying.
-    job_t(const job_t &rhs);
-    void operator=(const job_t &);
+    job_t(const job_t &rhs) = delete;
+    void operator=(const job_t &) = delete;
 
    public:
     job_t(job_id_t jobid, const io_chain_t &bio);
@@ -201,9 +208,9 @@ class job_t {
     /// Sets the command.
     void set_command(const wcstring &cmd) { command_str = cmd; }
 
-    /// A linked list of all the processes in this job. We are responsible for deleting this when we
-    /// are deallocated.
-    process_t *first_process;
+    /// All the processes in this job.
+    process_list_t processes;
+
     /// Process group ID for the process group that this job is running in.
     pid_t pgid;
     /// The saved terminal modes of this job. This needs to be saved so that we can restore the
@@ -216,6 +223,10 @@ class job_t {
     /// Bitset containing information about the job. A combination of the JOB_* constants.
     unsigned int flags;
 
+    // Get and set flags
+    bool get_flag(job_flag_t flag) const;
+    void set_flag(job_flag_t flag, bool set);
+
     /// Returns the block IO redirections associated with the job. These are things like the IO
     /// redirections associated with the begin...end statement.
     const io_chain_t &block_io_chain() const { return this->block_io; }
@@ -242,12 +253,12 @@ extern int is_login;
 /// Whether we are running an event handler.
 extern int is_event;
 
-typedef std::list job_list_t;
+// List of jobs. We sometimes mutate this while iterating - hence it must be a list, not a vector
+typedef std::list> job_list_t;
 
 bool job_list_is_empty(void);
 
-/// A class to aid iteration over jobs list. Note this is used from a signal handler, so it must be
-/// careful to not allocate memory.
+/// A class to aid iteration over jobs list
 class job_iterator_t {
     job_list_t *const job_list;
     job_list_t::iterator current, end;
@@ -258,7 +269,7 @@ class job_iterator_t {
     job_t *next() {
         job_t *job = NULL;
         if (current != end) {
-            job = *current;
+            job = current->get();
             ++current;
         }
         return job;
@@ -291,21 +302,12 @@ extern int job_control_mode;
 /// anything.
 extern int no_exec;
 
-/// Add the specified flag to the bitset of flags for the specified job.
-void job_set_flag(job_t *j, unsigned int flag, int set);
-
-/// Returns one if the specified flag is set in the specified job, 0 otherwise.
-int job_get_flag(const job_t *j, unsigned int flag);
-
 /// Sets the status of the last process to exit.
 void proc_set_last_status(int s);
 
 /// Returns the status of the last process to exit.
 int proc_get_last_status();
 
-/// Remove the specified job.
-void job_free(job_t *j);
-
 /// Promotes a job to the front of the job list.
 void job_promote(job_t *job);
 
@@ -340,7 +342,7 @@ void job_handle_signal(int signal, siginfo_t *info, void *con);
 int job_signal(job_t *j, int signal);
 
 /// Mark a process as failed to execute (and therefore completed).
-void job_mark_process_as_failed(const job_t *job, process_t *p);
+void job_mark_process_as_failed(job_t *job, const process_t *p);
 
 #ifdef HAVE__PROC_SELF_STAT
 /// Use the procfs filesystem to look up how many jiffies of cpu time was used by this process. This
diff --git a/src/reader.cpp b/src/reader.cpp
index f3886668a..f7228843a 100644
--- a/src/reader.cpp
+++ b/src/reader.cpp
@@ -14,30 +14,31 @@
 #include "config.h"
 
 // IWYU pragma: no_include 
+#include 
 #include 
+#include 
 #include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
 #ifdef HAVE_SIGINFO_H
 #include 
 #endif
+#include 
+#include 
+#include 
+#include 
 #ifdef HAVE_SYS_SELECT_H
 #include 
 #endif
-#include 
-#include 
-#include 
+#include 
 #include 
+#include 
+#include 
+#include 
 #include 
+#include 
+
+#include 
 #include 
+#include 
 
 #include "color.h"
 #include "common.h"
@@ -71,6 +72,10 @@
 #include "util.h"
 #include "wutil.h"  // IWYU pragma: keep
 
+// Name of the variable that tells how long it took, in milliseconds, for the previous
+// interactive command to complete.
+#define ENV_CMD_DURATION L"CMD_DURATION"
+
 /// Maximum length of prefix string when printing completion list. Longer prefixes will be
 /// ellipsized.
 #define PREFIX_MAX_LEN 9
@@ -281,7 +286,7 @@ static reader_data_t *data = 0;
 
 /// This flag is set to true when fish is interactively reading from stdin. It changes how a ^C is
 /// handled by the fish interrupt handler.
-static int is_interactive_read;
+static volatile sig_atomic_t is_interactive_read;
 
 /// Flag for ending non-interactive shell.
 static int end_loop = 0;
@@ -290,7 +295,7 @@ static int end_loop = 0;
 static std::stack > current_filename;
 
 /// This variable is set to true by the signal handler when ^C is pressed.
-static volatile int interrupted = 0;
+static volatile sig_atomic_t interrupted = 0;
 
 // Prototypes for a bunch of functions defined later on.
 static bool is_backslashed(const wcstring &str, size_t pos);
@@ -305,14 +310,15 @@ static struct termios tty_modes_for_external_cmds;
 static void reader_super_highlight_me_plenty(int highlight_pos_adjust = 0, bool no_io = false);
 
 /// Variable to keep track of forced exits - see \c reader_exit_forced();
-static int exit_forced;
+static bool exit_forced;
 
 /// Give up control of terminal.
 static void term_donate() {
     set_color(rgb_color_t::normal(), rgb_color_t::normal());
 
     while (1) {
-        if (tcsetattr(0, TCSANOW, &tty_modes_for_external_cmds)) {
+        if (tcsetattr(STDIN_FILENO, TCSANOW, &tty_modes_for_external_cmds) == -1) {
+            if (errno == EIO) redirect_tty_output();
             if (errno != EINTR) {
                 debug(1, _(L"Could not set terminal mode for new job"));
                 wperror(L"tcsetattr");
@@ -340,20 +346,21 @@ static void update_buff_pos(editable_line_t *el, size_t buff_pos) {
 /// Grab control of terminal.
 static void term_steal() {
     while (1) {
-        if (tcsetattr(0, TCSANOW, &shell_modes)) {
+        if (tcsetattr(STDIN_FILENO, TCSANOW, &shell_modes) == -1) {
+            if (errno == EIO) redirect_tty_output();
             if (errno != EINTR) {
                 debug(1, _(L"Could not set terminal mode for shell"));
-                wperror(L"tcsetattr");
+                perror("tcsetattr");
                 break;
             }
         } else
             break;
     }
 
-    common_handle_winch(0);
+    invalidate_termsize();
 }
 
-int reader_exit_forced() { return exit_forced; }
+bool reader_exit_forced() { return exit_forced; }
 
 /// Given a command line and an autosuggestion, return the string that gets shown to the user.
 wcstring combine_command_and_autosuggestion(const wcstring &cmdline,
@@ -412,7 +419,7 @@ static void reader_repaint() {
 
     if (data->sel_active) {
         highlight_spec_t selection_color = highlight_make_background(highlight_spec_selection);
-        for (size_t i = data->sel_start_pos; i <= std::min(len - 1, data->sel_stop_pos); i++) {
+        for (size_t i = data->sel_start_pos; i < std::min(len, data->sel_stop_pos); i++) {
             colors[i] = selection_color;
         }
     }
@@ -618,7 +625,7 @@ bool reader_data_t::expand_abbreviation_as_necessary(size_t cursor_backtrack) {
             // lengths.
             size_t new_buff_pos = el->position + new_cmdline.size() - el->text.size();
 
-            el->text.swap(new_cmdline);
+            el->text = std::move(new_cmdline);
             update_buff_pos(el, new_buff_pos);
             data->command_line_changed(el);
             result = true;
@@ -654,32 +661,7 @@ bool reader_thread_job_is_stale() {
 }
 
 void reader_write_title(const wcstring &cmd, bool reset_cursor_position) {
-    const env_var_t term_str = env_get_string(L"TERM");
-
-    // This is a pretty lame heuristic for detecting terminals that do not support setting the
-    // title. If we recognise the terminal name as that of a virtual terminal, we assume it supports
-    // setting the title. If we recognise it as that of a console, we assume it does not support
-    // setting the title. Otherwise we check the ttyname and see if we believe it is a virtual
-    // terminal.
-    //
-    // One situation in which this breaks down is with screen, since screen supports setting the
-    // terminal title if the underlying terminal does so, but will print garbage on terminals that
-    // don't. Since we can't see the underlying terminal below screen there is no way to fix this.
-    if (term_str.missing()) return;
-
-    const wchar_t *term = term_str.c_str();
-    bool recognized = contains(term, L"xterm", L"screen", L"tmux", L"nxterm", L"rxvt");
-    recognized = recognized || !wcsncmp(term, L"xterm-", wcslen(L"xterm-"));
-    recognized = recognized || !wcsncmp(term, L"screen-", wcslen(L"screen-"));
-    recognized = recognized || !wcsncmp(term, L"tmux-", wcslen(L"tmux-"));
-
-    if (!recognized) {
-        char *n = ttyname(STDIN_FILENO);
-
-        if (contains(term, L"linux")) return;
-        if (contains(term, L"dumb")) return;
-        if (strstr(n, "tty") || strstr(n, "/vc/")) return;
-    }
+    if (!term_supports_setting_title()) return;
 
     wcstring fish_title_command = DEFAULT_TITLE;
     if (function_exists(L"fish_title")) {
@@ -691,22 +673,25 @@ void reader_write_title(const wcstring &cmd, bool reset_cursor_position) {
     }
 
     wcstring_list_t lst;
-
     proc_push_interactive(0);
     if (exec_subshell(fish_title_command, lst, false /* ignore exit status */) != -1 &&
         !lst.empty()) {
-        writestr(L"\x1b]0;");
+        fputws(L"\e]0;", stdout);
         for (size_t i = 0; i < lst.size(); i++) {
-            writestr(lst.at(i).c_str());
+            fputws(lst.at(i).c_str(), stdout);
         }
-        writestr(L"\7");
+        fputwc(L'\a', stdout);
     }
+
     proc_pop_interactive();
     set_color(rgb_color_t::reset(), rgb_color_t::reset());
     if (reset_cursor_position && !lst.empty()) {
         // Put the cursor back at the beginning of the line (issue #2453).
-        writestr(L"\r");
+        fputwc(L'\r', stdout);
     }
+
+    // TODO: This should be removed when issue #3748 is fixed.
+    fflush(stdout);
 }
 
 /// Reexecute the prompt command. The output is inserted into data->prompt_buff.
@@ -765,6 +750,11 @@ static void exec_prompt() {
 void reader_init() {
     VOMIT_ON_FAILURE(pthread_key_create(&generation_count_key, NULL));
 
+    // Ensure this var is present even before an interactive command is run so that if it is used
+    // in a function like `fish_prompt` or `fish_right_prompt` it is defined at the time the first
+    // prompt is issued.
+    env_set(ENV_CMD_DURATION, L"0", ENV_UNEXPORT);
+
     // Save the initial terminal mode.
     tcgetattr(STDIN_FILENO, &terminal_mode_on_startup);
 
@@ -808,14 +798,16 @@ void restore_term_mode() {
     // Restore the term mode if we own the terminal. It's important we do this before
     // restore_foreground_process_group, otherwise we won't think we own the terminal.
     if (getpid() == tcgetpgrp(STDIN_FILENO)) {
-        tcsetattr(STDIN_FILENO, TCSANOW, &terminal_mode_on_startup);
+        if (tcsetattr(STDIN_FILENO, TCSANOW, &terminal_mode_on_startup) == -1 && errno == EIO) {
+            redirect_tty_output();
+        }
     }
 }
 
 void reader_exit(int do_exit, int forced) {
     if (data) data->end_loop = do_exit;
     end_loop = do_exit;
-    if (forced) exit_forced = 1;
+    if (forced) exit_forced = true;
 }
 
 void reader_repaint_needed() {
@@ -841,18 +833,13 @@ void reader_repaint_if_needed() {
     }
 }
 
-static void reader_repaint_if_needed_one_arg(void *unused) {
-    UNUSED(unused);
-    reader_repaint_if_needed();
-}
-
 void reader_react_to_color_change() {
     if (!data) return;
 
     if (!data->repaint_needed || !data->screen_reset_needed) {
         data->repaint_needed = true;
         data->screen_reset_needed = true;
-        input_common_add_callback(reader_repaint_if_needed_one_arg, NULL);
+        input_common_add_callback(reader_repaint_if_needed);
     }
 }
 
@@ -1124,32 +1111,28 @@ static void completion_insert(const wchar_t *val, complete_flags_t flags) {
     reader_set_buffer_maintaining_pager(new_command_line, cursor);
 }
 
-struct autosuggestion_context_t {
+struct autosuggestion_result_t {
+    wcstring suggestion;
     wcstring search_string;
-    wcstring autosuggestion;
-    size_t cursor_pos;
-    history_search_t searcher;
-    file_detection_context_t detector;
-    const wcstring working_directory;
-    const env_vars_snapshot_t vars;
-    const unsigned int generation_count;
+};
 
-    autosuggestion_context_t(history_t *history, const wcstring &term, size_t pos)
-        : search_string(term),
-          cursor_pos(pos),
-          searcher(*history, term, HISTORY_SEARCH_TYPE_PREFIX),
-          detector(history),
-          working_directory(env_get_pwd_slash()),
-          vars(env_vars_snapshot_t::highlighting_keys),
-          generation_count(s_generation_count) {}
-
-    // The function run in the background thread to determine an autosuggestion.
-    int threaded_autosuggest(void) {
+// Returns a function that can be invoked (potentially
+// on a background thread) to determine the autosuggestion
+static std::function get_autosuggestion_performer(
+    const wcstring &search_string, size_t cursor_pos, history_t *history) {
+    const unsigned int generation_count = s_generation_count;
+    const wcstring working_directory(env_get_pwd_slash());
+    env_vars_snapshot_t vars(env_vars_snapshot_t::highlighting_keys);
+    // TODO: suspicious use of 'history' here
+    // This is safe because histories are immortal, but perhaps
+    // this should use shared_ptr
+    return [=]() -> autosuggestion_result_t {
         ASSERT_IS_BACKGROUND_THREAD();
 
+        const autosuggestion_result_t nothing = {};
         // If the main thread has moved on, skip all the work.
         if (generation_count != s_generation_count) {
-            return 0;
+            return nothing;
         }
 
         VOMIT_ON_FAILURE(
@@ -1157,34 +1140,34 @@ struct autosuggestion_context_t {
 
         // Let's make sure we aren't using the empty string.
         if (search_string.empty()) {
-            return 0;
+            return nothing;
         }
 
+        history_search_t searcher(*history, search_string, HISTORY_SEARCH_TYPE_PREFIX);
         while (!reader_thread_job_is_stale() && searcher.go_backwards()) {
             history_item_t item = searcher.current_item();
 
             // Skip items with newlines because they make terrible autosuggestions.
             if (item.str().find('\n') != wcstring::npos) continue;
 
-            if (autosuggest_validate_from_history(item, detector, working_directory, vars)) {
+            if (autosuggest_validate_from_history(item, working_directory, vars)) {
                 // The command autosuggestion was handled specially, so we're done.
-                this->autosuggestion = searcher.current_string();
-                return 1;
+                return {searcher.current_string(), search_string};
             }
         }
 
         // Maybe cancel here.
-        if (reader_thread_job_is_stale()) return 0;
+        if (reader_thread_job_is_stale()) return nothing;
 
         // Here we do something a little funny. If the line ends with a space, and the cursor is not
         // at the end, don't use completion autosuggestions. It ends up being pretty weird seeing
         // stuff get spammed on the right while you go back to edit a line
         const wchar_t last_char = search_string.at(search_string.size() - 1);
-        const bool cursor_at_end = (this->cursor_pos == search_string.size());
-        if (!cursor_at_end && iswspace(last_char)) return 0;
+        const bool cursor_at_end = (cursor_pos == search_string.size());
+        if (!cursor_at_end && iswspace(last_char)) return nothing;
 
         // On the other hand, if the line ends with a quote, don't go dumping stuff after the quote.
-        if (wcschr(L"'\"", last_char) && cursor_at_end) return 0;
+        if (wcschr(L"'\"", last_char) && cursor_at_end) return nothing;
 
         // Try normal completions.
         std::vector completions;
@@ -1192,18 +1175,14 @@ struct autosuggestion_context_t {
         completions_sort_and_prioritize(&completions);
         if (!completions.empty()) {
             const completion_t &comp = completions.at(0);
-            size_t cursor = this->cursor_pos;
-            this->autosuggestion = completion_apply_to_command_line(
-                comp.completion, comp.flags, this->search_string, &cursor, true /* append only */);
-            return 1;
+            size_t cursor = cursor_pos;
+            wcstring suggestion = completion_apply_to_command_line(
+                comp.completion, comp.flags, search_string, &cursor, true /* append only */);
+            return {std::move(suggestion), search_string};
         }
 
-        return 0;
-    }
-};
-
-static int threaded_autosuggest(autosuggestion_context_t *ctx) {
-    return ctx->threaded_autosuggest();
+        return nothing;
+    };
 }
 
 static bool can_autosuggest(void) {
@@ -1215,15 +1194,16 @@ static bool can_autosuggest(void) {
            el == &data->command_line && el->text.find_first_not_of(whitespace) != wcstring::npos;
 }
 
-static void autosuggest_completed(autosuggestion_context_t *ctx, int result) {
-    if (result && can_autosuggest() && ctx->search_string == data->command_line.text &&
-        string_prefixes_string_case_insensitive(ctx->search_string, ctx->autosuggestion)) {
+// Called after an autosuggestion has been computed on a background thread
+static void autosuggest_completed(autosuggestion_result_t result) {
+    if (!result.suggestion.empty() && can_autosuggest() &&
+        result.search_string == data->command_line.text &&
+        string_prefixes_string_case_insensitive(result.search_string, result.suggestion)) {
         // Autosuggestion is active and the search term has not changed, so we're good to go.
-        data->autosuggestion = ctx->autosuggestion;
+        data->autosuggestion = std::move(result.suggestion);
         sanity_check();
         reader_repaint();
     }
-    delete ctx;
 }
 
 static void update_autosuggestion(void) {
@@ -1233,9 +1213,8 @@ static void update_autosuggestion(void) {
     if (data->allow_autosuggestion && !data->suppress_autosuggestion &&
         !data->command_line.empty() && data->history_search.is_at_end()) {
         const editable_line_t *el = data->active_edit_line();
-        autosuggestion_context_t *ctx =
-            new autosuggestion_context_t(data->history, el->text, el->position);
-        iothread_perform(threaded_autosuggest, autosuggest_completed, ctx);
+        auto performer = get_autosuggestion_performer(el->text, el->position, data->history);
+        iothread_perform(performer, &autosuggest_completed);
     }
 }
 
@@ -1295,7 +1274,7 @@ static void reader_flash() {
     }
 
     reader_repaint();
-    writestr(L"\a");
+    fputwc(L'\a', stdout);
 
     pollint.tv_sec = 0;
     pollint.tv_nsec = 100 * 1000000;
@@ -1375,7 +1354,7 @@ static bool handle_completions(const std::vector &comp,
     const wcstring tok(begin, end - begin);
 
     // Check trivial cases.
-    int size = comp.size();
+    size_t size = comp.size();
     if (size == 0) {
         // No suitable completions found, flash screen and return.
         reader_flash();
@@ -1602,8 +1581,9 @@ static void reader_interactive_init() {
         for (unsigned long loop_count = 0;; loop_count++) {
             pid_t owner = tcgetpgrp(STDIN_FILENO);
             shell_pgid = getpgrp();
-            if (owner < 0 && errno == ENOTTY) {
+            if (owner == -1 && errno == ENOTTY) {
                 // No TTY, cannot be interactive?
+                redirect_tty_output();
                 debug(1, _(L"No TTY for interactive shell (tcgetpgrp failed)"));
                 wperror(L"setpgid");
                 exit_without_destructors(1);
@@ -1638,22 +1618,24 @@ static void reader_interactive_init() {
     // Put ourselves in our own process group.
     shell_pgid = getpid();
     if (getpgrp() != shell_pgid && setpgid(shell_pgid, shell_pgid) < 0) {
-        debug(1, _(L"Couldn't put the shell in its own process group"));
+        debug(0, _(L"Couldn't put the shell in its own process group"));
         wperror(L"setpgid");
         exit_without_destructors(1);
     }
 
     // Grab control of the terminal.
-    if (tcsetpgrp(STDIN_FILENO, shell_pgid)) {
-        debug(1, _(L"Couldn't grab control of terminal"));
+    if (tcsetpgrp(STDIN_FILENO, shell_pgid) == -1) {
+        if (errno == ENOTTY) redirect_tty_output();
+        debug(0, _(L"Couldn't grab control of terminal"));
         wperror(L"tcsetpgrp");
         exit_without_destructors(1);
     }
 
-    common_handle_winch(0);
+    invalidate_termsize();
 
-    if (tcsetattr(0, TCSANOW, &shell_modes))  // set the new modes
-    {
+    // Set the new modes.
+    if (tcsetattr(0, TCSANOW, &shell_modes) == -1) {
+        if (errno == EIO) redirect_tty_output();
         wperror(L"tcsetattr");
     }
 
@@ -1663,7 +1645,6 @@ static void reader_interactive_init() {
 /// Destroy data for interactive use.
 static void reader_interactive_destroy() {
     kill_destroy();
-    writestr(L"\n");
     set_color(rgb_color_t::reset(), rgb_color_t::reset());
     input_destroy();
 }
@@ -1916,14 +1897,12 @@ bool reader_get_selection(size_t *start, size_t *len) {
     bool result = false;
     if (data != NULL && data->sel_active) {
         *start = data->sel_start_pos;
-        *len = std::min(data->sel_stop_pos - data->sel_start_pos + 1, data->command_line.size());
+        *len = std::min(data->sel_stop_pos - data->sel_start_pos, data->command_line.size());
         result = true;
     }
     return result;
 }
 
-#define ENV_CMD_DURATION L"CMD_DURATION"
-
 void set_env_cmd_duration(struct timeval *after, struct timeval *before) {
     time_t secs = after->tv_sec - before->tv_sec;
     suseconds_t usecs = after->tv_usec - before->tv_usec;
@@ -2085,50 +2064,6 @@ void reader_import_history_if_necessary(void) {
     }
 }
 
-/// A class as the context pointer for a background (threaded) highlight operation.
-class background_highlight_context_t {
-   public:
-    /// The string to highlight.
-    const wcstring string_to_highlight;
-    /// Color buffer.
-    std::vector colors;
-    /// The position to use for bracket matching.
-    const size_t match_highlight_pos;
-    /// Function for syntax highlighting.
-    const highlight_function_t highlight_function;
-    /// Environment variables.
-    const env_vars_snapshot_t vars;
-    /// When the request was made.
-    const double when;
-    /// Gen count at the time the request was made.
-    const unsigned int generation_count;
-
-    background_highlight_context_t(const wcstring &pbuff, size_t phighlight_pos,
-                                   highlight_function_t phighlight_func)
-        : string_to_highlight(pbuff),
-          colors(pbuff.size(), 0),
-          match_highlight_pos(phighlight_pos),
-          highlight_function(phighlight_func),
-          vars(env_vars_snapshot_t::highlighting_keys),
-          when(timef()),
-          generation_count(s_generation_count) {}
-
-    int perform_highlight() {
-        if (generation_count != s_generation_count) {
-            // The gen count has changed, so don't do anything.
-            return 0;
-        }
-        VOMIT_ON_FAILURE(
-            pthread_setspecific(generation_count_key, (void *)(uintptr_t)generation_count));
-
-        if (!string_to_highlight.empty()) {
-            highlight_function(string_to_highlight, colors, match_highlight_pos, NULL /* error */,
-                               vars);
-        }
-        return 0;
-    }
-};
-
 /// Called to set the highlight flag for search results.
 static void highlight_search(void) {
     if (!data->search_buff.empty() && !data->history_search.is_at_end()) {
@@ -2144,26 +2079,48 @@ static void highlight_search(void) {
     }
 }
 
-static void highlight_complete(background_highlight_context_t *ctx, int result) {
-    UNUSED(result);  // ignored because of the indirect invocation via iothread_perform()
+struct highlight_result_t {
+    std::vector colors;
+    wcstring text;
+};
+
+static void highlight_complete(highlight_result_t result) {
     ASSERT_IS_MAIN_THREAD();
-    if (ctx->string_to_highlight == data->command_line.text) {
+    if (result.text == data->command_line.text) {
         // The data hasn't changed, so swap in our colors. The colors may not have changed, so do
         // nothing if they have not.
-        assert(ctx->colors.size() == data->command_line.size());
-        if (data->colors != ctx->colors) {
-            data->colors.swap(ctx->colors);
+        assert(result.colors.size() == data->command_line.size());
+        if (data->colors != result.colors) {
+            data->colors = std::move(result.colors);
             sanity_check();
             highlight_search();
             reader_repaint();
         }
     }
-
-    delete ctx;
 }
 
-static int threaded_highlight(background_highlight_context_t *ctx) {
-    return ctx->perform_highlight();
+// Given text, bracket matching position, and whether IO is allowed,
+// return a function that performs highlighting. The function may be invoked on a background thread.
+static std::function get_highlight_performer(const wcstring &text,
+                                                                       long match_highlight_pos,
+                                                                       bool no_io) {
+    env_vars_snapshot_t vars(env_vars_snapshot_t::highlighting_keys);
+    unsigned int generation_count = s_generation_count;
+    highlight_function_t highlight_func = no_io ? highlight_shell_no_io : data->highlight_function;
+    return [=]() -> highlight_result_t {
+        if (generation_count != s_generation_count) {
+            // The gen count has changed, so don't do anything.
+            return {};
+        }
+        if (text.empty()) {
+            return {};
+        }
+        VOMIT_ON_FAILURE(
+            pthread_setspecific(generation_count_key, (void *)(uintptr_t)generation_count));
+        std::vector colors(text.size(), 0);
+        highlight_func(text, colors, match_highlight_pos, NULL /* error */, vars);
+        return {std::move(colors), text};
+    };
 }
 
 /// Call specified external highlighting function and then do search highlighting. Lastly, clear the
@@ -2182,16 +2139,13 @@ static void reader_super_highlight_me_plenty(int match_highlight_pos_adjust, boo
 
     reader_sanity_check();
 
-    highlight_function_t highlight_func = no_io ? highlight_shell_no_io : data->highlight_function;
-    background_highlight_context_t *ctx =
-        new background_highlight_context_t(el->text, match_highlight_pos, highlight_func);
+    auto highlight_performer = get_highlight_performer(el->text, match_highlight_pos, no_io);
     if (no_io) {
-        // Highlighting without IO, we just do it. Note that highlight_complete deletes ctx.
-        int result = ctx->perform_highlight();
-        highlight_complete(ctx, result);
+        // Highlighting without IO, we just do it.
+        highlight_complete(highlight_performer());
     } else {
         // Highlighting including I/O proceeds in the background.
-        iothread_perform(threaded_highlight, highlight_complete, ctx);
+        iothread_perform(highlight_performer, &highlight_complete);
     }
     highlight_search();
 
@@ -2217,46 +2171,41 @@ bool shell_is_exiting() {
 /// This function is called when the main loop notices that end_loop has been set while in
 /// interactive mode. It checks if it is ok to exit.
 static void handle_end_loop() {
-    job_t *j;
-    int stopped_jobs_count = 0;
-    int is_breakpoint = 0;
-    const parser_t &parser = parser_t::principal_parser();
-
-    for (size_t i = 0; i < parser.block_count(); i++) {
-        if (parser.block_at_index(i)->type() == BREAKPOINT) {
-            is_breakpoint = 1;
-            break;
-        }
-    }
-
     job_iterator_t jobs;
-    while ((j = jobs.next())) {
-        if (!job_is_completed(j) && (job_is_stopped(j))) {
-            stopped_jobs_count++;
-            break;
+
+    if (!reader_exit_forced()) {
+        const parser_t &parser = parser_t::principal_parser();
+        for (size_t i = 0; i < parser.block_count(); i++) {
+            if (parser.block_at_index(i)->type() == BREAKPOINT) {
+                // We're executing within a breakpoint so we do not want to terminate the shell and
+                // kill background jobs.
+                return;
+            }
+        }
+
+        bool bg_jobs = false;
+        while (const job_t *j = jobs.next()) {
+            if (!job_is_completed(j)) {
+                bg_jobs = true;
+                break;
+            }
+        }
+
+        if (!data->prev_end_loop && bg_jobs) {
+            fputws(_(L"There are still jobs active (use the jobs command to see them).\n"), stdout);
+            fputws(_(L"A second attempt to exit will terminate them.\n"), stdout);
+            reader_exit(0, 0);
+            data->prev_end_loop = 1;
+            return;
         }
     }
 
-    if (!reader_exit_forced() && !data->prev_end_loop && stopped_jobs_count && !is_breakpoint) {
-        writestr(_(
-            L"There are stopped jobs. A second attempt to exit will enforce their termination.\n"));
-
-        reader_exit(0, 0);
-        data->prev_end_loop = 1;
-    } else {
-        // PCA: We used to only hangup jobs if stdin was closed. This prevented child processes from
-        // exiting. It's unclear to my why it matters if stdin is closed, but it seems to me if
-        // we're forcing an exit, we definitely want to hang up our processes. See issue #138.
-        if (reader_exit_forced() || !isatty(0)) {
-            // We already know that stdin is a tty since we're in interactive mode. If isatty
-            // returns false, it means stdin must have been closed.
-            job_iterator_t jobs;
-            while ((j = jobs.next())) {
-                // Send SIGHUP only to foreground processes. See issue #1771.
-                if (!job_is_completed(j) && job_get_flag(j, JOB_FOREGROUND)) {
-                    job_signal(j, SIGHUP);
-                }
-            }
+    // Kill remaining jobs before exiting.
+    jobs.reset();
+    while (job_t *j = jobs.next()) {
+        if (!job_is_completed(j)) {
+            if (job_is_stopped(j)) job_signal(j, SIGCONT);
+            job_signal(j, SIGHUP);
         }
     }
 }
@@ -2402,9 +2351,10 @@ const wchar_t *reader_readline(int nchars) {
     reader_repaint();
 
     // Get the current terminal modes. These will be restored when the function returns.
-    tcgetattr(0, &old_modes);
+    if (tcgetattr(STDIN_FILENO, &old_modes) == -1 && errno == EIO) redirect_tty_output();
     // Set the new modes.
-    if (tcsetattr(0, TCSANOW, &shell_modes)) {
+    if (tcsetattr(0, TCSANOW, &shell_modes) == -1) {
+        if (errno == EIO) redirect_tty_output();
         wperror(L"tcsetattr");
     }
 
@@ -2423,7 +2373,7 @@ const wchar_t *reader_readline(int nchars) {
             is_interactive_read = 1;
             c = input_readch();
             is_interactive_read = was_interactive_read;
-            // fprintf(stderr, "C: %lx\n", (long)c);
+            // fwprintf(stderr, L"C: %lx\n", (long)c);
 
             if (((!fish_reserved_codepoint(c))) && (c > 31) && (c != 127) && can_read(0)) {
                 wchar_t arr[READAHEAD_MAX + 1];
@@ -2485,7 +2435,7 @@ const wchar_t *reader_readline(int nchars) {
         if (command_ends_paging(c, focused_on_search_field)) {
             clear_pager();
         }
-        // fprintf(stderr, "\n\nchar: %ls\n\n", describe_char(c).c_str());
+        // fwprintf(stderr, L"\n\nchar: %ls\n\n", describe_char(c).c_str());
 
         switch (c) {
             // Go to beginning of line.
@@ -2541,7 +2491,7 @@ const wchar_t *reader_readline(int nchars) {
                 break;
             }
             case R_EOF: {
-                exit_forced = 1;
+                exit_forced = true;
                 data->end_loop = 1;
                 break;
             }
@@ -2606,7 +2556,7 @@ const wchar_t *reader_readline(int nchars) {
                     // up to the end of the token we're completing.
                     const wcstring buffcpy = wcstring(cmdsub_begin, token_end);
 
-                    // fprintf(stderr, "Complete (%ls)\n", buffcpy.c_str());
+                    // fwprintf(stderr, L"Complete (%ls)\n", buffcpy.c_str());
                     complete_flags_t complete_flags = COMPLETION_REQUEST_DEFAULT |
                                                       COMPLETION_REQUEST_DESCRIPTIONS |
                                                       COMPLETION_REQUEST_FUZZY_MATCH;
@@ -2718,7 +2668,7 @@ const wchar_t *reader_readline(int nchars) {
                 break;
             }
             // Escape was pressed.
-            case L'\x1b': {
+            case L'\e': {
                 if (data->search_mode) {
                     data->search_mode = NO_SEARCH;
 
@@ -2747,6 +2697,9 @@ const wchar_t *reader_readline(int nchars) {
                 if (el->position < el->size()) {
                     update_buff_pos(el, el->position + 1);
                     remove_backward();
+                    if (el->position > 0 && el->position == el->size()) {
+                        update_buff_pos(el, el->position - 1);
+                    }
                 }
                 break;
             }
@@ -3256,7 +3209,7 @@ const wchar_t *reader_readline(int nchars) {
         reader_repaint_if_needed();
     }
 
-    writestr(L"\n");
+    fputwc(L'\n', stdout);
 
     // Ensure we have no pager contents when we exit.
     if (!data->pager.empty()) {
@@ -3267,7 +3220,8 @@ const wchar_t *reader_readline(int nchars) {
     }
 
     if (!reader_exit_forced()) {
-        if (tcsetattr(0, TCSANOW, &old_modes)) {
+        if (tcsetattr(0, TCSANOW, &old_modes) == -1) {
+            if (errno == EIO) redirect_tty_output();
             wperror(L"tcsetattr");  // return to previous mode
         }
         set_color(rgb_color_t::reset(), rgb_color_t::reset());
@@ -3351,7 +3305,7 @@ static int read_ni(int fd, const io_chain_t &io) {
         parse_error_list_t errors;
         parse_node_tree_t tree;
         if (!parse_util_detect_errors(str, &errors, false /* do not accept incomplete */, &tree)) {
-            parser.eval_acquiring_tree(str, io, TOP, moved_ref(tree));
+            parser.eval(str, io, TOP, std::move(tree));
         } else {
             wcstring sb;
             parser.get_backtrace(str, errors, &sb);
@@ -3373,7 +3327,20 @@ int reader_read(int fd, const io_chain_t &io) {
     // If reader_read is called recursively through the '.' builtin, we need to preserve
     // is_interactive. This, and signal handler setup is handled by
     // proc_push_interactive/proc_pop_interactive.
-    int inter = ((fd == STDIN_FILENO) && isatty(STDIN_FILENO));
+    int inter = 0;
+    // This block is a hack to work around https://sourceware.org/bugzilla/show_bug.cgi?id=20632.
+    // See also, commit 396bf12. Without the need for this workaround we would just write:
+    // int inter = ((fd == STDIN_FILENO) && isatty(STDIN_FILENO));
+    if (fd == STDIN_FILENO) {
+        struct termios t;
+        int a_tty = isatty(STDIN_FILENO);
+        if (a_tty) {
+            inter = 1;
+        } else if (tcgetattr(STDIN_FILENO, &t) == -1 && errno == EIO) {
+            redirect_tty_output();
+            inter = 1;
+        }
+    }
     proc_push_interactive(inter);
 
     res = shell_is_interactive() ? read_i() : read_ni(fd, io);
diff --git a/src/reader.h b/src/reader.h
index 519aa2a10..da675fc68 100644
--- a/src/reader.h
+++ b/src/reader.h
@@ -195,7 +195,7 @@ bool shell_is_exiting();
 void reader_handle_sigint();
 
 /// This function returns true if fish is exiting by force, i.e. because stdin died.
-int reader_exit_forced();
+bool reader_exit_forced();
 
 /// Test if the given shell command contains errors. Uses parser_test for testing. Suitable for
 /// reader_set_test_function().
diff --git a/src/sanity.cpp b/src/sanity.cpp
index df355935b..b5c803304 100644
--- a/src/sanity.cpp
+++ b/src/sanity.cpp
@@ -12,19 +12,18 @@
 #include "sanity.h"
 
 /// Status from earlier sanity checks.
-static int insane;
+static bool insane = false;
 
 void sanity_lose() {
     debug(0, _(L"Errors detected, shutting down. Break on sanity_lose() to debug."));
-    insane = 1;
+    insane = true;
 }
 
-int sanity_check() {
+bool sanity_check() {
     if (!insane && shell_is_interactive()) history_sanity_check();
     if (!insane) reader_sanity_check();
     if (!insane) kill_sanity_check();
     if (!insane) proc_sanity_check();
-
     return insane;
 }
 
diff --git a/src/sanity.h b/src/sanity.h
index 6eedb08f0..4c8c27b4e 100644
--- a/src/sanity.h
+++ b/src/sanity.h
@@ -6,7 +6,7 @@
 void sanity_lose();
 
 /// Perform sanity checks, return 1 if program is in a sane state 0 otherwise.
-int sanity_check();
+bool sanity_check();
 
 /// Try and determine if ptr is a valid pointer. If not, loose sanity.
 ///
diff --git a/src/screen.cpp b/src/screen.cpp
index 54a1203f3..d40bdcb1a 100644
--- a/src/screen.cpp
+++ b/src/screen.cpp
@@ -118,14 +118,13 @@ static bool is_screen_name_escape_seq(const wchar_t *code, size_t *resulting_len
     }
 #endif
 
-    const wchar_t *const screen_name_end_sentinel = L"\x1b\\";
+    const wchar_t *const screen_name_end_sentinel = L"\e\\";
     const wchar_t *screen_name_end = wcsstr(&code[2], screen_name_end_sentinel);
     if (screen_name_end == NULL) {
         // Consider just k to be the code.
         *resulting_length = 2;
     } else {
-        const wchar_t *escape_sequence_end =
-            screen_name_end + wcslen(screen_name_end_sentinel);
+        const wchar_t *escape_sequence_end = screen_name_end + wcslen(screen_name_end_sentinel);
         *resulting_length = escape_sequence_end - code;
     }
     return true;
@@ -140,7 +139,7 @@ static bool is_iterm2_escape_seq(const wchar_t *code, size_t *resulting_length)
         size_t cursor = 2;
         for (; code[cursor] != L'\0'; cursor++) {
             // Consume a sequence of characters up to \ or .
-            if (code[cursor] == '\x07' || (code[cursor] == '\\' && code[cursor - 1] == '\x1b')) {
+            if (code[cursor] == '\x07' || (code[cursor] == '\\' && code[cursor - 1] == '\e')) {
                 found = true;
                 break;
             }
@@ -200,12 +199,12 @@ static bool is_csi_style_escape_seq(const wchar_t *code, size_t *resulting_lengt
 }
 
 /// Returns the number of characters in the escape code starting at 'code' (which should initially
-/// contain \x1b).
+/// contain \e).
 size_t escape_code_length(const wchar_t *code) {
     assert(code != NULL);
 
-    // The only escape codes we recognize start with \x1b.
-    if (code[0] != L'\x1b') return 0;
+    // The only escape codes we recognize start with \e.
+    if (code[0] != L'\e') return 0;
 
     size_t resulting_length = 0;
     bool found = false;
@@ -285,7 +284,7 @@ static prompt_layout_t calc_prompt_layout(const wchar_t *prompt) {
     prompt_layout.line_count = 1;
 
     for (j = 0; prompt[j]; j++) {
-        if (prompt[j] == L'\x1b') {
+        if (prompt[j] == L'\e') {
             // This is the start of an escape code. Skip over it if it's at least one character
             // long.
             size_t escape_len = escape_code_length(&prompt[j]);
@@ -417,7 +416,7 @@ static void s_desired_append_char(screen_t *s, wchar_t b, int c, int indent, siz
         if ((s->desired.cursor.x + cw) > screen_width) {
             // Current line is soft wrapped (assuming we support it).
             s->desired.line(s->desired.cursor.y).is_soft_wrapped = true;
-            // fprintf(stderr, "\n\n1 Soft wrapping %d\n\n", s->desired.cursor.y);
+            // fwprintf(stderr, L"\n\n1 Soft wrapping %d\n\n", s->desired.cursor.y);
 
             line_no = (int)s->desired.line_count();
             s->desired.add_line();
@@ -662,7 +661,7 @@ static bool test_stuff(screen_t *scr)
         int c = getchar();
         if (c != EOF) break;
     }
-    puts("Bye");
+    fwprintf(stdout, L"Bye\n");
     exit(0);
     while (1) sleep(10000);
     return true;
@@ -1196,7 +1195,8 @@ void s_reset(screen_t *s, screen_reset_mode_t mode) {
         // Don't need to check for fish_wcwidth errors; this is done when setting up
         // omitted_newline_char in common.cpp.
         int non_space_width = fish_wcwidth(omitted_newline_char);
-        if (screen_width >= non_space_width) {
+        // We do `>` rather than `>=` because the code below might require one extra space.
+        if (screen_width > non_space_width) {
             bool justgrey = true;
             if (enter_dim_mode) {
                 std::string dim = tparm(enter_dim_mode);
@@ -1226,16 +1226,22 @@ void s_reset(screen_t *s, screen_reset_mode_t mode) {
                 abandon_line_string.append(
                     str2wcstring(tparm(exit_attribute_mode)));  // normal text ANSI escape sequence
             }
-            abandon_line_string.append(screen_width - non_space_width, L' ');
+            int newline_glitch_width = term_has_xn ? 0 : 1;
+            abandon_line_string.append(screen_width - non_space_width - newline_glitch_width, L' ');
         }
         abandon_line_string.push_back(L'\r');
+        abandon_line_string.push_back(omitted_newline_char);
         // Now we are certainly on a new line. But we may have dropped the omitted newline char on
         // it. So append enough spaces to overwrite the omitted newline char, and then clear all the
-        // spaces from the new line
+        // spaces from the new line.
         abandon_line_string.append(non_space_width, L' ');
         abandon_line_string.push_back(L'\r');
-        // clear entire line - el2
-        abandon_line_string.append(L"\x1b[2K");
+        // Clear entire line. Zsh doesn't do this. Fish added this with commit 4417a6ee: If you have
+        // a prompt preceded by a new line, you'll get a line full of spaces instead of an empty
+        // line above your prompt. This doesn't make a difference in normal usage, but copying and
+        // pasting your terminal log becomes a pain. This commit clears that line, making it an
+        // actual empty line.
+        abandon_line_string.append(L"\e[2K");
 
         const std::string narrow_abandon_line_string = wcs2string(abandon_line_string);
         write_loop(STDOUT_FILENO, narrow_abandon_line_string.c_str(),
diff --git a/src/screen.h b/src/screen.h
index abe76df20..c4eb257f1 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -54,6 +54,8 @@ struct line_t {
         text.insert(text.end(), line.text.begin(), line.text.end());
         colors.insert(colors.end(), line.colors.begin(), line.colors.end());
     }
+
+    wcstring to_string() const { return wcstring(this->text.begin(), this->text.end()); }
 };
 
 /// A class representing screen contents.
@@ -89,7 +91,9 @@ class screen_data_t {
 
     line_t &line(size_t idx) { return line_datas.at(idx); }
 
-    size_t line_count(void) { return line_datas.size(); }
+    const line_t &line(size_t idx) const { return line_datas.at(idx); }
+
+    size_t line_count() const { return line_datas.size(); }
 
     void append_lines(const screen_data_t &d) {
         this->line_datas.insert(this->line_datas.end(), d.line_datas.begin(), d.line_datas.end());
diff --git a/src/signal.cpp b/src/signal.cpp
index a718d250e..aa76e8d33 100644
--- a/src/signal.cpp
+++ b/src/signal.cpp
@@ -14,9 +14,11 @@
 #include "fallback.h"  // IWYU pragma: keep
 #include "proc.h"
 #include "reader.h"
-#include "signal.h"
 #include "wutil.h"  // IWYU pragma: keep
 
+// This is a temporary var while we explore whether signal_block() and friends is needed.
+bool ignore_signal_block = false;
+
 /// Struct describing an entry for the lookup table used to convert between signal names and signal
 /// ids, etc.
 struct lookup_entry {
@@ -151,19 +153,15 @@ static int match_signal_name(const wchar_t *canonical, const wchar_t *name) {
 }
 
 int wcs2sig(const wchar_t *str) {
-    int i;
-    wchar_t *end = 0;
-
-    for (i = 0; lookup[i].desc; i++) {
+    for (int i = 0; lookup[i].desc; i++) {
         if (match_signal_name(lookup[i].name, str)) {
             return lookup[i].signal;
         }
     }
-    errno = 0;
-    int res = fish_wcstoi(str, &end, 10);
-    if (!errno && res >= 0 && !*end) return res;
 
-    return -1;
+    int res = fish_wcstoi(str);
+    if (errno || res < 0) return -1;
+    return res;
 }
 
 const wchar_t *sig2wcs(int sig) {
@@ -244,6 +242,15 @@ static void handle_chld(int sig, siginfo_t *info, void *context) {
     default_handler(sig, info, context);
 }
 
+// We have a sigalarm handler that does nothing
+// This is used in the signal torture test, to verify
+// that we behave correctly when receiving lots of irrelevant signals
+static void handle_sigalarm(int sig, siginfo_t *info, void *context) {
+    UNUSED(sig);
+    UNUSED(info);
+    UNUSED(context);
+}
+
 void signal_reset_handlers() {
     int i;
 
@@ -257,88 +264,82 @@ void signal_reset_handlers() {
     }
 }
 
-/// Sets appropriate signal handlers.
-void signal_set_handlers() {
+static void set_interactive_handlers() {
     struct sigaction act;
-
     sigemptyset(&act.sa_mask);
-    act.sa_flags = SA_SIGINFO;
-    act.sa_sigaction = &default_handler;
 
-    // First reset everything to a use default_handler, a function whose sole action is to fire of
-    // an event.
+    // Interactive mode. Ignore interactive signals.  We are a shell, we know what is best for
+    // the user.
+    act.sa_handler = SIG_IGN;
     sigaction(SIGINT, &act, 0);
     sigaction(SIGQUIT, &act, 0);
     sigaction(SIGTSTP, &act, 0);
-    sigaction(SIGTTIN, &act, 0);
     sigaction(SIGTTOU, &act, 0);
-    sigaction(SIGCHLD, &act, 0);
 
-    // Ignore sigpipe, which we may get from the universal variable notifier.
-    sigaction(SIGPIPE, &act, 0);
+    // We don't ignore SIGTTIN because we might send it to ourself.
+    act.sa_sigaction = &default_handler;
+    act.sa_flags = SA_SIGINFO;
+    sigaction(SIGTTIN, &act, 0);
 
-    if (shell_is_interactive()) {
-        // Interactive mode. Ignore interactive signals.  We are a shell, we know what is best for
-        // the user.
-        act.sa_handler = SIG_IGN;
+    act.sa_sigaction = &handle_int;
+    act.sa_flags = SA_SIGINFO;
+    sigaction(SIGINT, &act, 0);
 
-        sigaction(SIGINT, &act, 0);
-        sigaction(SIGQUIT, &act, 0);
-        sigaction(SIGTSTP, &act, 0);
-        sigaction(SIGTTIN, &act, 0);
-        sigaction(SIGTTOU, &act, 0);
+    // SIGTERM restores the terminal controlling process before dying.
+    act.sa_sigaction = &handle_term;
+    act.sa_flags = SA_SIGINFO;
+    sigaction(SIGTERM, &act, 0);
 
-        act.sa_sigaction = &handle_int;
-        act.sa_flags = SA_SIGINFO;
-        if (sigaction(SIGINT, &act, 0)) {
-            wperror(L"sigaction");
-            FATAL_EXIT();
-        }
+    act.sa_sigaction = &handle_hup;
+    act.sa_flags = SA_SIGINFO;
+    sigaction(SIGHUP, &act, 0);
 
-        act.sa_sigaction = &handle_chld;
-        act.sa_flags = SA_SIGINFO;
-        if (sigaction(SIGCHLD, &act, 0)) {
-            wperror(L"sigaction");
-            FATAL_EXIT();
-        }
+    // SIGALARM as part of our signal torture test
+    act.sa_sigaction = &handle_sigalarm;
+    act.sa_flags = SA_SIGINFO;
+    sigaction(SIGALRM, &act, 0);
 
 #ifdef SIGWINCH
-        act.sa_flags = SA_SIGINFO;
-        act.sa_sigaction = &handle_winch;
-        if (sigaction(SIGWINCH, &act, 0)) {
-            wperror(L"sigaction");
-            FATAL_EXIT();
-        }
+    act.sa_sigaction = &handle_winch;
+    act.sa_flags = SA_SIGINFO;
+    sigaction(SIGWINCH, &act, 0);
 #endif
+}
 
-        act.sa_flags = SA_SIGINFO;
-        act.sa_sigaction = &handle_hup;
-        if (sigaction(SIGHUP, &act, 0)) {
-            wperror(L"sigaction");
-            FATAL_EXIT();
-        }
+static void set_non_interactive_handlers() {
+    struct sigaction act;
+    sigemptyset(&act.sa_mask);
 
-        // SIGTERM restores the terminal controlling process before dying.
-        act.sa_flags = SA_SIGINFO;
-        act.sa_sigaction = &handle_term;
-        if (sigaction(SIGTERM, &act, 0)) {
-            wperror(L"sigaction");
-            FATAL_EXIT();
-        }
+    // Non-interactive. Ignore interrupt, check exit status of processes to determine result
+    // instead.
+    act.sa_handler = SIG_IGN;
+    sigaction(SIGINT, &act, 0);
+    sigaction(SIGQUIT, &act, 0);
+}
+
+/// Sets up appropriate signal handlers.
+void signal_set_handlers() {
+    struct sigaction act;
+    sigemptyset(&act.sa_mask);
+
+    // Ignore SIGPIPE. We'll detect failed writes and deal with them appropriately. We don't want
+    // this signal interrupting other syscalls or terminating us.
+    act.sa_handler = SIG_IGN;
+    sigaction(SIGPIPE, &act, 0);
+
+    // Whether or not we're interactive we want SIGCHLD to not interrupt restartable syscalls.
+    act.sa_flags = SA_SIGINFO;
+    act.sa_sigaction = &handle_chld;
+    act.sa_flags = SA_SIGINFO | SA_RESTART;
+    if (sigaction(SIGCHLD, &act, 0)) {
+        wperror(L"sigaction");
+        FATAL_EXIT();
+    }
+
+    if (shell_is_interactive()) {
+        set_interactive_handlers();
     } else {
-        // Non-interactive. Ignore interrupt, check exit status of processes to determine result
-        // instead.
-        act.sa_handler = SIG_IGN;
-        sigaction(SIGINT, &act, 0);
-        sigaction(SIGQUIT, &act, 0);
-
-        act.sa_handler = SIG_DFL;
-        act.sa_sigaction = &handle_chld;
-        act.sa_flags = SA_SIGINFO;
-        if (sigaction(SIGCHLD, &act, 0)) {
-            wperror(L"sigaction");
-            exit_without_destructors(1);
-        }
+        set_non_interactive_handlers();
     }
 }
 
@@ -372,6 +373,8 @@ void get_signals_with_handlers(sigset_t *set) {
 }
 
 void signal_block() {
+    if (ignore_signal_block) return;
+
     ASSERT_IS_MAIN_THREAD();
     sigset_t chldset;
 
@@ -381,10 +384,12 @@ void signal_block() {
     }
 
     block_count++;
-    //	debug( 0, L"signal block level increased to %d", block_count );
+    // debug( 0, L"signal block level increased to %d", block_count );
 }
 
 void signal_unblock() {
+    if (ignore_signal_block) return;
+
     ASSERT_IS_MAIN_THREAD();
     sigset_t chldset;
 
@@ -400,7 +405,10 @@ void signal_unblock() {
         sigfillset(&chldset);
         VOMIT_ON_FAILURE(pthread_sigmask(SIG_UNBLOCK, &chldset, 0));
     }
-    //	debug( 0, L"signal block level decreased to %d", block_count );
+    // debug( 0, L"signal block level decreased to %d", block_count );
 }
 
-bool signal_is_blocked() { return static_cast(block_count); }
+bool signal_is_blocked() {
+    if (ignore_signal_block) return false;
+    return static_cast(block_count);
+}
diff --git a/src/signal.h b/src/signal.h
index 2800caf64..3c4da3990 100644
--- a/src/signal.h
+++ b/src/signal.h
@@ -38,4 +38,5 @@ bool signal_is_blocked();
 /// Returns signals with non-default handlers.
 void get_signals_with_handlers(sigset_t *set);
 
+extern bool ignore_signal_block;
 #endif
diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp
index 29d11639c..d39e27bcb 100644
--- a/src/tokenizer.cpp
+++ b/src/tokenizer.cpp
@@ -5,7 +5,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -490,7 +489,7 @@ void tokenizer_t::tok_next() {
     }
 
     if (!this->has_next) {
-        // wprintf( L"EOL\n" );
+        // fwprintf(stdout, L"EOL\n" );
         this->last_type = TOK_END;
         return;
     }
@@ -610,7 +609,7 @@ wcstring tok_first(const wcstring &str) {
     tokenizer_t t(str.c_str(), TOK_SQUASH_ERRORS);
     tok_t token;
     if (t.next(&token) && token.type == TOK_STRING) {
-        result.swap(token.text);
+        result = std::move(token.text);
     }
     return result;
 }
@@ -667,7 +666,7 @@ bool move_word_state_machine_t::consume_char_path_components(wchar_t c) {
         s_end
     };
 
-    // printf("state %d, consume '%lc'\n", state, c);
+    // fwprintf(stdout, L"state %d, consume '%lc'\n", state, c);
     bool consumed = false;
     while (state != s_end && !consumed) {
         switch (state) {
diff --git a/src/util.cpp b/src/util.cpp
index 7caba32bc..600ef9e36 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -28,16 +28,15 @@ int wcsfilecmp(const wchar_t *a, const wchar_t *b) {
 
     long secondary_diff = 0;
     if (iswdigit(*a) && iswdigit(*b)) {
-        wchar_t *aend, *bend;
+        const wchar_t *aend, *bend;
         long al;
         long bl;
         long diff;
 
-        errno = 0;
-        al = wcstol(a, &aend, 10);
-        bl = wcstol(b, &bend, 10);
-
-        if (errno) {
+        al = fish_wcstol(a, &aend);
+        int a1_errno = errno;
+        bl = fish_wcstol(b, &bend);
+        if (a1_errno || errno) {
             // Huge numbers - fall back to regular string comparison.
             return wcscmp(a, b);
         }
diff --git a/src/wildcard.cpp b/src/wildcard.cpp
index cd8cb226d..15fbe59de 100644
--- a/src/wildcard.cpp
+++ b/src/wildcard.cpp
@@ -490,7 +490,8 @@ class wildcard_expander_t {
 
     void add_expansion_result(const wcstring &result) {
         // This function is only for the non-completions case.
-        assert(!static_cast(this->flags & EXPAND_FOR_COMPLETIONS));  //!OCLINT(multiple unary operator)
+        assert(!static_cast(this->flags &
+                                  EXPAND_FOR_COMPLETIONS));  //!OCLINT(multiple unary operator)
         if (this->completion_set.insert(result).second) {
             append_completion(this->resolved_completions, result);
             this->did_add = true;
diff --git a/src/wutil.cpp b/src/wutil.cpp
index 25556c92f..10122453b 100644
--- a/src/wutil.cpp
+++ b/src/wutil.cpp
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -37,12 +38,8 @@ const file_id_t kInvalidFileID = {(dev_t)-1LL, (ino_t)-1LL, (uint64_t)-1LL, -1,
 #endif
 #endif
 
-/// Lock to protect wgettext.
-static pthread_mutex_t wgettext_lock;
-
 /// Map used as cache by wgettext.
-typedef std::map wgettext_map_t;
-static wgettext_map_t wgettext_map;
+static owning_lock> wgettext_map;
 
 bool wreaddir_resolving(DIR *dir, const std::wstring &dir_path, std::wstring &out_name,
                         bool *out_is_dir) {
@@ -404,7 +401,6 @@ wcstring wbasename(const wcstring &path) {
 
 // Really init wgettext.
 static void wgettext_really_init() {
-    pthread_mutex_init(&wgettext_lock, NULL);
     fish_bindtextdomain(PACKAGE_NAME, LOCALEDIR);
     fish_textdomain(PACKAGE_NAME);
 }
@@ -422,8 +418,8 @@ const wcstring &wgettext(const wchar_t *in) {
     wcstring key = in;
 
     wgettext_init_if_necessary();
-    scoped_lock locker(wgettext_lock);
-    wcstring &val = wgettext_map[key];
+    auto wmap = wgettext_map.acquire();
+    wcstring &val = wmap.value[key];
     if (val.empty()) {
         cstring mbs_in = wcs2string(key);
         char *out = fish_gettext(mbs_in.c_str());
@@ -483,6 +479,7 @@ int fish_iswgraph(wint_t wc) {
 ///
 /// \return null if this is a valid name, and a pointer to the first invalid character otherwise.
 const wchar_t *wcsvarname(const wchar_t *str) {
+    if (str[0] == L'\0') return str;
     while (*str) {
         if ((!fish_iswalnum(*str)) && (*str != L'_')) {
             return str;
@@ -497,10 +494,15 @@ const wchar_t *wcsvarname(const wchar_t *str) {
 /// \return null if this is a valid name, and a pointer to the first invalid character otherwise.
 const wchar_t *wcsvarname(const wcstring &str) { return wcsvarname(str.c_str()); }
 
-/// Test if the given string is a valid function name.
+/// Test if the string is a valid function name.
 ///
-/// \return null if this is a valid name, and a pointer to the first invalid character otherwise.
-const wchar_t *wcsfuncname(const wcstring &str) { return wcschr(str.c_str(), L'/'); }
+/// \return true if it is valid else false.
+bool wcsfuncname(const wcstring &str) {
+    if (str.size() == 0) return false;
+    if (str.at(0) == L'-') return false;
+    if (str.find_first_of(L'/') != wcstring::npos) return false;
+    return true;
+}
 
 /// Test if the given string is valid in a variable name.
 ///
@@ -517,16 +519,138 @@ int fish_wcswidth(const wchar_t *str) { return fish_wcswidth(str, wcslen(str));
 /// See fallback.h for the normal definitions.
 int fish_wcswidth(const wcstring &str) { return fish_wcswidth(str.c_str(), str.size()); }
 
-int fish_wcstoi(const wchar_t *str, wchar_t **endptr, int base) {
-    long ret = wcstol(str, endptr, base);
-    if (ret > INT_MAX) {
-        ret = INT_MAX;
+/// Like fish_wcstol(), but fails on a value outside the range of an int.
+///
+/// This is needed because BSD and GNU implementations differ in several ways that make it really
+/// annoying to use them in a portable fashion.
+///
+/// The caller doesn't have to zero errno. Sets errno to -1 if the int ends with something other
+/// than a digit. Leading whitespace is ignored (per the base wcstol implementation). Trailing
+/// whitespace is also ignored. We also treat empty strings and strings containing only whitespace
+/// as invalid.
+int fish_wcstoi(const wchar_t *str, const wchar_t **endptr, int base) {
+    while (iswspace(*str)) ++str;  // skip leading whitespace
+    if (!*str) {  // this is because some implementations don't handle this sensibly
+        errno = EINVAL;
+        if (endptr) *endptr = str;
+        return 0;
+    }
+
+    errno = 0;
+    wchar_t *_endptr;
+    long result = wcstol(str, &_endptr, base);
+    if (result > INT_MAX) {
+        result = INT_MAX;
         errno = ERANGE;
-    } else if (ret < INT_MIN) {
-        ret = INT_MIN;
+    } else if (result < INT_MIN) {
+        result = INT_MIN;
         errno = ERANGE;
     }
-    return (int)ret;
+    while (iswspace(*_endptr)) ++_endptr;  // skip trailing whitespace
+    if (!errno && *_endptr) {
+        if (_endptr == str) {
+            errno = EINVAL;
+        } else {
+            errno = -1;
+        }
+    }
+    if (endptr) *endptr = _endptr;
+    return (int)result;
+}
+
+/// An enhanced version of wcstol().
+///
+/// This is needed because BSD and GNU implementations differ in several ways that make it really
+/// annoying to use them in a portable fashion.
+///
+/// The caller doesn't have to zero errno. Sets errno to -1 if the int ends with something other
+/// than a digit. Leading whitespace is ignored (per the base wcstol implementation). Trailing
+/// whitespace is also ignored.
+long fish_wcstol(const wchar_t *str, const wchar_t **endptr, int base) {
+    while (iswspace(*str)) ++str;  // skip leading whitespace
+    if (!*str) {  // this is because some implementations don't handle this sensibly
+        errno = EINVAL;
+        if (endptr) *endptr = str;
+        return 0;
+    }
+
+    errno = 0;
+    wchar_t *_endptr;
+    long result = wcstol(str, &_endptr, base);
+    while (iswspace(*_endptr)) ++_endptr;  // skip trailing whitespace
+    if (!errno && *_endptr) {
+        if (_endptr == str) {
+            errno = EINVAL;
+        } else {
+            errno = -1;
+        }
+    }
+    if (endptr) *endptr = _endptr;
+    return result;
+}
+
+/// An enhanced version of wcstoll().
+///
+/// This is needed because BSD and GNU implementations differ in several ways that make it really
+/// annoying to use them in a portable fashion.
+///
+/// The caller doesn't have to zero errno. Sets errno to -1 if the int ends with something other
+/// than a digit. Leading whitespace is ignored (per the base wcstoll implementation). Trailing
+/// whitespace is also ignored.
+long long fish_wcstoll(const wchar_t *str, const wchar_t **endptr, int base) {
+    while (iswspace(*str)) ++str;  // skip leading whitespace
+    if (!*str) {  // this is because some implementations don't handle this sensibly
+        errno = EINVAL;
+        if (endptr) *endptr = str;
+        return 0;
+    }
+
+    errno = 0;
+    wchar_t *_endptr;
+    long long result = wcstoll(str, &_endptr, base);
+    while (iswspace(*_endptr)) ++_endptr;  // skip trailing whitespace
+    if (!errno && *_endptr) {
+        if (_endptr == str) {
+            errno = EINVAL;
+        } else {
+            errno = -1;
+        }
+    }
+    if (endptr) *endptr = _endptr;
+    return result;
+}
+
+/// An enhanced version of wcstoull().
+///
+/// This is needed because BSD and GNU implementations differ in several ways that make it really
+/// annoying to use them in a portable fashion.
+///
+/// The caller doesn't have to zero errno. Sets errno to -1 if the int ends with something other
+/// than a digit. Leading minus is considered invalid. Leading whitespace is ignored (per the base
+/// wcstoull implementation). Trailing whitespace is also ignored.
+unsigned long long fish_wcstoull(const wchar_t *str, const wchar_t **endptr, int base) {
+    while (iswspace(*str)) ++str;  // skip leading whitespace
+    if (!*str ||      // this is because some implementations don't handle this sensibly
+        *str == '-')  // disallow minus as the first character to avoid questionable wrap-around
+    {
+        errno = EINVAL;
+        if (endptr) *endptr = str;
+        return 0;
+    }
+
+    errno = 0;
+    wchar_t *_endptr;
+    unsigned long long result = wcstoull(str, &_endptr, base);
+    while (iswspace(*_endptr)) ++_endptr;  // skip trailing whitespace
+    if (!errno && *_endptr) {
+        if (_endptr == str) {
+            errno = EINVAL;
+        } else {
+            errno = -1;
+        }
+    }
+    if (endptr) *endptr = _endptr;
+    return result;
 }
 
 file_id_t file_id_t::file_id_from_stat(const struct stat *buf) {
diff --git a/src/wutil.h b/src/wutil.h
index 601fac936..2bd8ed80a 100644
--- a/src/wutil.h
+++ b/src/wutil.h
@@ -3,6 +3,7 @@
 #define FISH_WUTIL_H
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -111,13 +112,15 @@ int fish_iswgraph(wint_t wc);
 
 const wchar_t *wcsvarname(const wchar_t *str);
 const wchar_t *wcsvarname(const wcstring &str);
-const wchar_t *wcsfuncname(const wcstring &str);
+bool wcsfuncname(const wcstring &str);
 bool wcsvarchr(wchar_t chr);
 int fish_wcswidth(const wchar_t *str);
 int fish_wcswidth(const wcstring &str);
 
-/// Like wcstol(), but fails on a value outside the range of an int.
-int fish_wcstoi(const wchar_t *str, wchar_t **endptr, int base);
+int fish_wcstoi(const wchar_t *str, const wchar_t **endptr = NULL, int base = 10);
+long fish_wcstol(const wchar_t *str, const wchar_t **endptr = NULL, int base = 10);
+long long fish_wcstoll(const wchar_t *str, const wchar_t **endptr = NULL, int base = 10);
+unsigned long long fish_wcstoull(const wchar_t *str, const wchar_t **endptr = NULL, int base = 10);
 
 /// Class for representing a file's inode. We use this to detect and avoid symlink loops, among
 /// other things. While an inode / dev pair is sufficient to distinguish co-existing files, Linux
diff --git a/tests/abbr.err b/tests/abbr.err
index 13fdfd748..83f97ab79 100644
--- a/tests/abbr.err
+++ b/tests/abbr.err
@@ -1,2 +1,7 @@
 abbr: no such abbreviation 'NOT_AN_ABBR'
 abbr: abbreviation cannot have spaces in the key
+abbr: no such abbreviation '__abbr6'
+abbr: abbreviation cannot have spaces in the key
+abbr: option requires an argument -- -r
+abbr: Unexpected argument -- __abbr10
+abbr: abbreviation '__abbr12' already exists, cannot rename
diff --git a/tests/abbr.in b/tests/abbr.in
index 2086f66cb..5ed22c346 100644
--- a/tests/abbr.in
+++ b/tests/abbr.in
@@ -37,3 +37,35 @@ abbr d2 env a=b banana
 abbr -l | string match -q d2; or echo "= test failed"
 
 abbr "a b c" "d e f"; or true
+
+# Test renaming
+abbr __abbr4 omega
+abbr | grep __abbr5
+abbr -r __abbr4 __abbr5
+abbr | grep __abbr5
+abbr -e __abbr5
+abbr | grep __abbr4
+
+# Test renaming a nonexistent abbreviation
+abbr -r __abbr6 __abbr; or true
+
+# Test renaming to a abbreviation with spaces
+abbr __abbr4 omega
+abbr -r __abbr4 "g h i"; or true
+abbr -e __abbr4
+
+# Test renaming without arguments
+abbr __abbr7 omega
+abbr -r __abbr7; or true
+
+# Test renaming with too many arguments
+abbr __abbr8 omega
+abbr -r __abbr8 __abbr9 __abbr10; or true
+abbr | grep __abbr8
+abbr | grep __abbr9; or true
+abbr | grep __abbr10; or true
+
+# Test renaming to existing abbreviation
+abbr __abbr11 omega11
+abbr __abbr12 omega12
+abbr -r __abbr11 __abbr12; or true
diff --git a/tests/abbr.out b/tests/abbr.out
index 53998613a..168fbfcee 100644
--- a/tests/abbr.out
+++ b/tests/abbr.out
@@ -6,3 +6,5 @@ abbr __abbr1 delta
 abbr __abbr1 delta
 abbr '~__abbr2' '$xyz'
 abbr -- --__abbr3 xyz
+abbr __abbr5 omega
+abbr __abbr8 omega
diff --git a/tests/bind.expect b/tests/bind.expect
index 00da321c6..3f0508ddb 100644
--- a/tests/bind.expect
+++ b/tests/bind.expect
@@ -92,6 +92,18 @@ expect_prompt -re {\r\nTAXT\r\n} {
     puts stderr "vi mode replace char, default timeout: long delay"
 }
 
+# Test deleting characters with 'x'.
+send "echo MORE-TEXT"
+send "\033"
+# Delay needed to allow fish to transition to vi "normal" mode.
+sleep 0.150
+send "xxxxx\r"
+expect_prompt -re {\r\nMORE\r\n} {
+    puts "vi mode delete char, default timeout: long delay"
+} unmatched {
+    puts stderr "vi mode delete char, default timeout: long delay"
+}
+
 # Verify that changing the escape timeout has an effect.
 send "set -g fish_escape_delay_ms 200\r"
 expect_prompt
diff --git a/tests/bind.expect.out b/tests/bind.expect.out
index b9ff26444..e04e9bd3a 100644
--- a/tests/bind.expect.out
+++ b/tests/bind.expect.out
@@ -5,6 +5,7 @@ prime vi mode, default timeout
 vi-mode default timeout set correctly
 vi replace line, default timeout: long delay
 vi mode replace char, default timeout: long delay
+vi mode delete char, default timeout: long delay
 vi replace line, 100ms timeout: long delay
 vi replace line, 100ms timeout: short delay
 t-binding success
diff --git a/tests/exit.expect b/tests/exit.expect
new file mode 100644
index 000000000..3ff2074f7
--- /dev/null
+++ b/tests/exit.expect
@@ -0,0 +1,37 @@
+# vim: set filetype=expect:
+#
+# Test handling of the `exit` command.
+set pid [spawn $fish]
+expect_prompt
+
+# Verify that if we attempt to exit with a job in the background we get warned
+# about that job and are told to type `exit` a second time.
+send "sleep 111 &\r"
+expect_prompt
+send "exit\r"
+expect "There are still jobs active"
+expect "A second attempt to exit will terminate them."
+expect_prompt
+
+# Running anything other than `exit` should result in the same warning with
+# the shell still running.
+send "sleep 113 &\r"
+expect_prompt
+send "exit\r"
+expect "There are still jobs active"
+expect "A second attempt to exit will terminate them."
+expect_prompt
+
+# Verify that asking to exit a second time does so.
+send "exit\r"
+catch {expect default exp_continue} output
+wait
+
+# Verify all child processes have been killed. We don't use `-p $pid` because
+# if the shell has a bug the child processes might have been reparented to pid
+# 1 rather than killed.
+set status [catch {exec pgrep -l -f "sleep 11"} output]
+if {$status == 0} {
+    puts stderr "Commands spawned by the shell still running after `exit`"
+    puts stderr $output
+}
diff --git a/tests/exit.expect.err b/tests/exit.expect.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/exit.expect.out b/tests/exit.expect.out
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/fkr.expect b/tests/fkr.expect
index 130888fbc..963cba0ed 100644
--- a/tests/fkr.expect
+++ b/tests/fkr.expect
@@ -38,7 +38,9 @@ expect -ex "char: \\c@\r\nbind \\c@ 'do something'\r\n" {
 }
 
 # Does it keep running if handed control sequences in the wrong order?
-send "\x03\x04"
+send "\x03"
+sleep 0.010
+send "\x04"
 expect -ex "char: \\cD\r\n" {
     puts "invalid terminate sequence handled"
 } unmatched {
diff --git a/tests/function.err b/tests/function.err
index e69de29bb..84a25ec9b 100644
--- a/tests/function.err
+++ b/tests/function.err
@@ -0,0 +1,9 @@
+function: Illegal function name '-a'
+fish: function -a arg1 arg2 name2 ; end
+      ^
+function: Illegal function name '--argument-names'
+fish: function --argument-names arg1 arg2 name4 ; end
+      ^
+function: Unexpected positional argument 'abc'
+fish: function name5 abc --argument-names def ; end
+      ^
diff --git a/tests/function.in b/tests/function.in
index 747bbcecb..25b1f561d 100644
--- a/tests/function.in
+++ b/tests/function.in
@@ -31,16 +31,29 @@ set bar 'bad bar'
 set baz 'bad baz'
 frob
 
-# Test that -a does not mix up the function name with arguments
-# See #2068
-function name1 -a arg1 arg2 ; end
+# This sequence of tests originally verified that functions `name2` and
+# `name4` were created. See issue #2068. That behavior is not what we want.
+# The function name must always be the first argument of the `function`
+# command. See issue #2827.
+function name1 -a arg1 arg2 ; echo hello; end
 function -a arg1 arg2 name2 ; end
-function name3 --argument-names arg1 arg2 ; end
+function name3 --argument-names arg1 arg2 ; echo hello; echo goodbye; end
 function --argument-names arg1 arg2 name4 ; end
-for i in (seq 4)
-    if functions -q name$i
-        echo "Function name$i found"
-    else
-        echo "Function name$i not found, but should have been"
-    end
-end
+function name5 abc --argument-names def ; end
+functions -q name1; and echo "Function name1 found"
+functions -q name2; or echo "Function name2 not found as expected"
+functions -q name3; and echo "Function name3 found"
+functions -q name4; or echo "Function name4 not found as expected"
+
+# Verify that functions can be copied. Tests against regression of issue #3601.
+functions -c name1 name1a
+functions --copy name3 name3a
+functions -q name1a
+or echo "Function name1a not found as expected"
+functions -q name3a
+or echo "Function name3a not found as expected"
+echo Checking that the copied functions are identical other than the name
+diff (functions name1 | psub) (functions name1a | psub)
+diff (functions name3 | psub) (functions name3a | psub)
+
+exit 0
diff --git a/tests/function.out b/tests/function.out
index 5a3da6195..6845d37f0 100644
--- a/tests/function.out
+++ b/tests/function.out
@@ -19,6 +19,15 @@ $bar: (5)
 5: '3'
 $baz: (0)
 Function name1 found
-Function name2 found
+Function name2 not found as expected
 Function name3 found
-Function name4 found
+Function name4 not found as expected
+Checking that the copied functions are identical other than the name
+1c1
+< function name1 --argument arg1 arg2
+---
+> function name1a --argument arg1 arg2
+1c1
+< function name3 --argument arg1 arg2
+---
+> function name3a --argument arg1 arg2
diff --git a/tests/functions.err b/tests/functions.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/functions.in b/tests/functions.in
new file mode 100644
index 000000000..c51981db5
--- /dev/null
+++ b/tests/functions.in
@@ -0,0 +1,50 @@
+# vim: set filetype=fish:
+#
+# Test the `functions` builtin
+
+function f1
+end
+
+# ==========
+# Verify that `functions --metadata` works as expected when given too many args.
+set x (functions --metadata f1 f2 2>&1)
+if test "$x" != "functions: Expected exactly one function name for --metadata"
+    echo "Unexpected output for 'functions --metadata f1 f2': $x" >&2
+end
+
+# ==========
+# Verify that `functions --metadata` works as expected when given the name of a
+# known function.
+set x (functions --metadata f1)
+if test "$x" != "stdin"
+    echo "Unexpected output for 'functions --metadata f1': $x" >&2
+end
+
+# ==========
+# Verify that `functions --metadata` works as expected when given the name of an
+# unknown function.
+set x (functions -m f2)
+if test "$x" != "n/a"
+    echo "Unexpected output for 'functions --metadata f2': $x" >&2
+end
+
+# ==========
+# Verify that `functions --metadata` works as expected when given the name of a
+# function that could be autoloaded but isn't currently loaded.
+set x (functions -m abbr)
+if test (count $x) -ne 1
+or not string match -q '*/share/functions/abbr.fish' "$x"
+    echo "Unexpected output for 'functions -m abbr': $x" >&2
+end
+
+# ==========
+# Verify that `functions --verbose --metadata` works as expected when given the name of a
+# function that was autoloaded.
+set x (functions -v -m abbr)
+if test (count $x) -ne 4
+or not string match -q '*/share/functions/abbr.fish' $x[1]
+or test $x[2] != autoloaded
+or test $x[3] != 1
+or test $x[4] != scope-shadowing
+    echo "Unexpected output for 'functions -v -m abbr': $x" >&2
+end
diff --git a/tests/functions.out b/tests/functions.out
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/interactive.fish b/tests/interactive.fish
index cdb449c13..22bd62762 100644
--- a/tests/interactive.fish
+++ b/tests/interactive.fish
@@ -7,6 +7,10 @@
 # This is a list of flakey tests that often succeed when rerun.
 set TESTS_TO_RETRY bind.expect
 
+# Set this var to modify behavior of the code being tests. Such as avoiding running
+# `fish_update_completions` when running tests.
+set -x FISH_UNIT_TESTS_RUNNING 1
+
 # Change to directory containing this script
 cd (dirname (status -f))
 
diff --git a/tests/math.in b/tests/math.in
index d8cb50922..40ad59f5b 100644
--- a/tests/math.in
+++ b/tests/math.in
@@ -7,3 +7,4 @@ math -s0 '10 % 6'
 math '23 % 7'
 math -s6 '5 / 3 * 0.3'
 true
+math "1 + 1233242342353453463458972349873489273984873289472914712894791824712941"
diff --git a/tests/math.out b/tests/math.out
index 0a46b6a56..a49461da2 100644
--- a/tests/math.out
+++ b/tests/math.out
@@ -6,3 +6,4 @@
 4
 2
 .499999
+1233242342353453463458972349873489273984873289472914712894791824712942
diff --git a/tests/random.err b/tests/random.err
new file mode 100644
index 000000000..d6f1ea51d
--- /dev/null
+++ b/tests/random.err
@@ -0,0 +1,16 @@
+random: a is not a valid integer
+random: 18446744073709551614 is not a valid integer
+random: Too many arguments
+random: END must be greater than START
+random: 18446744073709551614 is not a valid integer
+random: 1d is not a valid integer
+random: 1c is not a valid integer
+random: END must be greater than START
+random: - is not a valid integer
+random: -1 is not a valid integer
+random: -9223372036854775807 is not a valid integer
+random: STEP must be a positive integer
+random: range contains only one possible value
+random: range contains only one possible value
+random: nothing to choose from
+random: Too many arguments
diff --git a/tests/random.in b/tests/random.in
new file mode 100644
index 000000000..d8e31df19
--- /dev/null
+++ b/tests/random.in
@@ -0,0 +1,98 @@
+set -l max 9223372036854775807
+set -l close_max 9223372036854775806
+set -l min -9223372036854775807
+set -l close_min -9223372036854775806
+set -l diff_max 18446744073709551614
+
+# check failure cases
+random a
+random $diff_max
+random -- 1 2 3 4
+random -- 10 -10
+random -- 10 $diff_max
+random -- 1 1d
+random -- 1 1c 10
+random -- 10 10
+random -- 1 - 10
+random -- 1 -1 10
+random -- 1 $min 10
+random -- 1 0 10
+random -- 1 11 10
+random -- 0 $diff_max $max
+random choice
+random choic a b c
+
+function check_boundaries
+    if not test $argv[1] -ge $argv[2] -a $argv[1] -le $argv[3] 
+        printf "Unexpected: %s <= %s <= %s not verified\n" $argv[2] $argv[1] $argv[3] >&2
+        return 1
+    end
+end
+
+function test_range
+    return (check_boundaries (random -- $argv) $argv)
+end
+
+function check_contains
+    if not contains -- $argv[1] $argv[2..-1]
+        printf "Unexpected: %s not among possibilities" $argv[1] >&2
+        printf " %s" $argv[2..-1] >&2
+        printf "\n" >&2
+        return 1
+    end
+end
+
+function test_step
+    return (check_contains (random -- $argv) (seq -- $argv))
+end
+
+function test_choice
+    return (check_contains (random choice $argv) $argv)
+end
+
+for i in (seq 10)
+    check_boundaries (random) 0 32767
+
+    test_range 0 10
+    test_range -10 -1
+    test_range -10 10
+
+    test_range 0 $max
+    test_range $min -1
+    test_range $min $max
+
+    test_range $close_max $max
+    test_range $min $close_min
+    test_range $close_min $close_max
+
+    #OSX's `seq` uses scientific notation for large numbers, hence not usable here
+    check_contains (random -- 0 $max $max) 0 $max
+    check_contains (random -- 0 $close_max $max) 0 $close_max
+    check_contains (random -- $min $max 0) $min 0
+    check_contains (random -- $min $close_max 0) $min -1
+    check_contains (random -- $min $max $max) $min 0 $max
+    check_contains (random -- $min $diff_max $max) $min $max
+
+    test_step 0 $i 10
+    test_step -5 $i 5
+    test_step -10 $i 0
+    
+    test_choice a
+    test_choice foo bar
+    test_choice bass trout salmon zander perch carp
+end
+
+
+#check seeding
+set -l seed (random)
+random $seed
+set -l run1 (random) (random) (random) (random) (random)
+random $seed
+set -l run2 (random) (random) (random) (random) (random)
+if not test "$run1" = "$run2"
+    printf "Unexpected different sequences after seeding with %s\n" $seed
+    printf "%s " $run1
+    printf "\n"
+    printf "%s " $run2
+    printf "\n"
+end
diff --git a/tests/random.out b/tests/random.out
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/read.expect b/tests/read.expect
index 3c153f733..45594c21e 100644
--- a/tests/read.expect
+++ b/tests/read.expect
@@ -75,3 +75,23 @@ send_line -h "12`_marker 7"
 expect_prompt
 expect_marker 7
 print_var_contents foo
+
+# ==========
+# The fix for issue #2007 initially introduced a problem when using a function
+# to read from /dev/stdin when that is associated with the tty. These tests
+# are to ensure we don't introduce a regression.
+send "r2l\n"
+expect_read_prompt
+send "abc\n"
+expect_read_prompt
+send "def\n"
+expect "abc then def\r\n"
+expect_prompt
+
+send "r2l  $path
+read -l longstr2 < $path
+test "$longstr" = "$longstr2"
+and echo "Chunked reads test pass"
+or echo "Chunked reads test failure: long strings don't match!"
+rm $path
+
 true
diff --git a/tests/read.out b/tests/read.out
index 43b016db3..d35a9146a 100644
--- a/tests/read.out
+++ b/tests/read.out
@@ -55,3 +55,6 @@ newline
 1 'foo' 1 'bar'
 2 'foo' 'bar'
 2 'baz' 'quux'
+
+# chunked read tests
+Chunked reads test pass
diff --git a/tests/signals.expect b/tests/signals.expect
new file mode 100644
index 000000000..dc7991b8b
--- /dev/null
+++ b/tests/signals.expect
@@ -0,0 +1,28 @@
+# vim: set filetype=expect:
+#
+# Test signal handling for interactive shells.
+
+# Verify that sending SIGHUP to the shell, such as will happen when the tty is
+# closed by the terminal, terminates the shell and the foreground command and
+# any background commands run from that shell.
+set pid [spawn $fish]
+expect_prompt
+send "sleep 130 &\r"
+expect_prompt
+send "sleep 131 &\r"
+expect_prompt
+send "sleep 132\r"
+exec -- kill -HUP $pid
+
+# Verify the spawned fish shell has exited.
+catch {expect default exp_continue} output
+wait
+
+# Verify all child processes have been killed. We don't use `-p $pid` because
+# if the shell has a bug the child processes might have been reparented to pid
+# 1 rather than killed.
+set status [catch {exec pgrep -l -f "sleep 13"} output]
+if {$status == 0} {
+    puts stderr "Commands spawned by the shell still running after SIGHUP"
+    puts stderr $output
+}
diff --git a/tests/signals.expect.err b/tests/signals.expect.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/signals.expect.out b/tests/signals.expect.out
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/test.fish b/tests/test.fish
index f5741f29b..1e2be399d 100644
--- a/tests/test.fish
+++ b/tests/test.fish
@@ -4,6 +4,10 @@
 # should be running it via `make test` to ensure the environment is properly
 # setup.
 
+# Set this var to modify behavior of the code being tests. Such as avoiding running
+# `fish_update_completions` when running tests.
+set -x FISH_UNIT_TESTS_RUNNING 1
+
 # Change to directory containing this script
 cd (dirname (status -f))
 
diff --git a/tests/test4.in b/tests/test4.in
index 6d5014553..08bc1be44 100644
--- a/tests/test4.in
+++ b/tests/test4.in
@@ -33,65 +33,65 @@ set -g smurf yellow
 call3
 call4
 
-set -l foo 1 
-set -g bar 2 
-set -U baz 3 
+set -l foo 1
+set -g bar 2
+set -U baz 3
 
-set -l -q foo 
+set -l -q foo
 
 if test $status -ne 0
-    echo Test 5 fail 
+    echo Test 5 fail
 else
     echo Test 5 pass
 end;
 
-if not set -g -q bar 
-    echo Test 6 fail 
+if not set -g -q bar
+    echo Test 6 fail
 else
     echo Test 6 pass
 end;
 
-if not set -U -q baz 
-    echo Test 7 fail 
+if not set -U -q baz
+    echo Test 7 fail
 else
     echo Test 7 pass
 end;
 
-set -u -l -q foo 
-if test $status -ne 0 
-    echo Test 8 fail 
+set -u -l -q foo
+if test $status -ne 0
+    echo Test 8 fail
 else
     echo Test 8 pass
 
 end;
 
-if not set -u -g -q bar 
-    echo Test 9 fail 
+if not set -u -g -q bar
+    echo Test 9 fail
 else
     echo Test 9 pass
 end;
 
-if not set -u -U -q baz 
-    echo Test 10 fail 
+if not set -u -U -q baz
+    echo Test 10 fail
 else
     echo Test 10 pass
 end;
 
-set -x -l -q foo 
+set -x -l -q foo
 if test $status -eq 0
-    echo Test 11 fail 
+    echo Test 11 fail
 else
     echo Test 11 pass
 end;
 
-if set -x -g -q bar 
-    echo Test 12 fail 
+if set -x -g -q bar
+    echo Test 12 fail
 else
     echo Test 12 pass
 end;
 
-if set -x -U -q baz 
-    echo Test 13 fail 
+if set -x -U -q baz
+    echo Test 13 fail
 else
     echo Test 13 pass
 end;
@@ -100,61 +100,61 @@ set -x -l foo 1
 set -x -g bar 2
 set -x -U baz 3
 
-set -l -q foo 
-if test $status -ne 0 
-    echo Test 14 fail 
+set -l -q foo
+if test $status -ne 0
+    echo Test 14 fail
 else
     echo Test 14 pass
 end;
 
-if not set -g -q bar 
-    echo Test 15 fail 
+if not set -g -q bar
+    echo Test 15 fail
 else
     echo Test 15 pass
 end;
 
-if not set -U -q baz 
-    echo Test 16 fail 
+if not set -U -q baz
+    echo Test 16 fail
 else
     echo Test 16 pass
 
 end;
 
-set -u -l -q foo 
-if test $status -ne 1 
-    echo Test 17 fail 
+set -u -l -q foo
+if test $status -ne 1
+    echo Test 17 fail
 else
     echo Test 17 pass
 end;
 
-if set -u -g -q bar 
-    echo Test 18 fail 
+if set -u -g -q bar
+    echo Test 18 fail
 else
     echo Test 18 pass
 end;
 
-if set -u -U -q baz 
-    echo Test 19 fail 
+if set -u -U -q baz
+    echo Test 19 fail
 else
     echo Test 19 pass
 
 end;
 
-set -x -l -q foo 
-if test $status -ne 0 
-    echo Test 20 fail 
+set -x -l -q foo
+if test $status -ne 0
+    echo Test 20 fail
 else
     echo Test 20 pass
 end;
 
-if not set -x -g -q bar 
-    echo Test 21 fail 
+if not set -x -g -q bar
+    echo Test 21 fail
 else
     echo Test 21 pass
 end;
 
-if not set -x -U -q baz 
-    echo Test 22 fail 
+if not set -x -U -q baz
+    echo Test 22 fail
 else
     echo Test 22 pass
 end;
diff --git a/tests/test6.err b/tests/test6.err
index f259ceb70..5252a9953 100644
--- a/tests/test6.err
+++ b/tests/test6.err
@@ -1,4 +1,3 @@
 complete: -o requires a non-empty string
-complete: -d requires a non-empty string
 complete: -l requires a non-empty string
 complete: -s requires a non-empty string
diff --git a/tests/test6.in b/tests/test6.in
index de217fe57..0ea772bb9 100644
--- a/tests/test6.in
+++ b/tests/test6.in
@@ -3,7 +3,6 @@
 # Regression test for issue #3129. In previous versions these statements would
 # cause an `assert()` to fire thus killing the shell.
 complete -c pkill -o ''
-complete -c pkill -d ''
 complete -c pkill -l ''
 complete -c pkill -s ''
 
@@ -52,6 +51,27 @@ complete -c CCCC -e
 echo "CCCC:"
 complete -C'CCCC -' | sort
 
+echo "Test that -- suppresses option completions"
+complete -c TestDoubleDash -l TestDoubleDashOption
+complete -C'TestDoubleDash -' | sort
+echo "Expect no output:" (complete -C'TestDoubleDash -- -' | sort)
+
+# fish seems to have always handled "exclusive" options strangely
+# It seems to treat them the same as "old-style" (single-dash) long options
+echo "Testing exclusive options"
+complete -c TestExclusive -x -s Q
+complete -c TestExclusive -x -s W
+complete -c TestExclusive -s A
+echo "Expect -A -Q -W:" (complete -C'TestExclusive -' | sort | string join ' ')
+echo "Expect -AQ -AW:" (complete -C'TestExclusive -A' | sort | string join ' ')
+echo "Expect no output 1:" (complete -C'TestExclusive -Q')
+echo "Expect no output 2:" (complete -C'TestExclusive -W')
+
+# Test for optional arguments, like cp's --backup
+complete -c TestOptionalArgument -l backup -f -a 'none all simple'
+echo "Expect --backup --backup=:" (complete -C'TestOptionalArgument -' | sort | string join ' ')
+echo "Expect --backup=all  --backup=none  --backup=simple:" (complete -C'TestOptionalArgument --backup=' | sort | string join ' ')
+
 # Test that directory completions work correctly
 if begin; rm -rf test6.tmp.dir; and mkdir test6.tmp.dir; end
     pushd test6.tmp.dir
diff --git a/tests/test6.out b/tests/test6.out
index ca6e69066..6e21926d2 100644
--- a/tests/test6.out
+++ b/tests/test6.out
@@ -30,6 +30,16 @@ CCCC:
 -b
 -bar
 CCCC:
+Test that -- suppresses option completions
+--TestDoubleDashOption
+Expect no output:
+Testing exclusive options
+Expect -A -Q -W: -A -Q -W
+Expect -AQ -AW: -AQ -AW
+Expect no output 1:
+Expect no output 2:
+Expect --backup --backup=: --backup --backup=
+Expect --backup=all  --backup=none  --backup=simple: --backup=all --backup=none --backup=simple
 implicit cd complete works
 no implicit cd complete after 'command'
 PATH does not cause incorrect implicit cd
diff --git a/tests/test_functions/r2l.fish b/tests/test_functions/r2l.fish
new file mode 100644
index 000000000..5401ddb7b
--- /dev/null
+++ b/tests/test_functions/r2l.fish
@@ -0,0 +1,5 @@
+function r2l
+    read line1
+    read line2
+    echo $line1 then $line2
+end
diff --git a/tests/test_util.fish b/tests/test_util.fish
index 22c478524..97af65129 100644
--- a/tests/test_util.fish
+++ b/tests/test_util.fish
@@ -109,7 +109,7 @@ function say -V suppress_color
 
     if begin; test -n "$suppress_color"; or set_color $color_flags $argv[1]; end
         printf '%s' $argv[2..-1]
-        test -z "$suppress_color"; and set_color reset
+        test -z "$suppress_color"; and set_color normal
         if test -z "$suppress_newline"
             echo
         end