mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-10 18:01:11 -03:00
Compare commits
213 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
44e8a12b66 | ||
|
|
fe21577a8e | ||
|
|
a4ac924512 | ||
|
|
e936629dc3 | ||
|
|
dfabf7f206 | ||
|
|
7118269e4b | ||
|
|
100355c3c1 | ||
|
|
4b1fced1f8 | ||
|
|
abff4e5b41 | ||
|
|
25082b6528 | ||
|
|
766482d90e | ||
|
|
15e0a44fc7 | ||
|
|
3b653cd26a | ||
|
|
ba6661e9df | ||
|
|
55af8e4966 | ||
|
|
dcad2ef17b | ||
|
|
418192b312 | ||
|
|
76d9051605 | ||
|
|
ca2b2103d3 | ||
|
|
14e6bdb139 | ||
|
|
20d42378de | ||
|
|
41c9f89fcf | ||
|
|
7953863b38 | ||
|
|
3fff030ee2 | ||
|
|
da9f7227f5 | ||
|
|
ba932b6590 | ||
|
|
c02e2b1320 | ||
|
|
37a95a3096 | ||
|
|
bbd229b206 | ||
|
|
6a60377e02 | ||
|
|
fc87b3c4b4 | ||
|
|
fcbdb6f2a7 | ||
|
|
a537b01814 | ||
|
|
bd5a16d213 | ||
|
|
be0bd50bad | ||
|
|
cab5c63402 | ||
|
|
d480d892c9 | ||
|
|
f2ccbe7374 | ||
|
|
85241817f8 | ||
|
|
8cf46bdb5c | ||
|
|
5e6d1efb56 | ||
|
|
bc1f9b6f1c | ||
|
|
85d069c106 | ||
|
|
cfecb58bb6 | ||
|
|
11c2ec91d4 | ||
|
|
cc6f133368 | ||
|
|
350b637a1a | ||
|
|
f917dccf6f | ||
|
|
62d380a1ee | ||
|
|
65ef6cf217 | ||
|
|
2bba0f7b8f | ||
|
|
565970b8ca | ||
|
|
6ea3dd7dfe | ||
|
|
8176a1253b | ||
|
|
4f67c38777 | ||
|
|
86beb7b109 | ||
|
|
98a6c491b1 | ||
|
|
66c045c439 | ||
|
|
a1ec38f53b | ||
|
|
64f1024eb5 | ||
|
|
b3500bfbdc | ||
|
|
f8c45324b6 | ||
|
|
bf5d4f6b07 | ||
|
|
1300e68fa5 | ||
|
|
1a76f2ecb9 | ||
|
|
9c5fb0392d | ||
|
|
f4c5eaf05b | ||
|
|
dd90b4ece4 | ||
|
|
4930db35e2 | ||
|
|
e6409a88d5 | ||
|
|
77a48dc252 | ||
|
|
029be823e2 | ||
|
|
421aff7d67 | ||
|
|
9e7094adfc | ||
|
|
19e8d60179 | ||
|
|
9d9869e515 | ||
|
|
54e19b1efb | ||
|
|
f603b6ef68 | ||
|
|
81e0fcbc13 | ||
|
|
b999bd9c8c | ||
|
|
9c9a8f9d0f | ||
|
|
461ef2a508 | ||
|
|
7492b6cdb3 | ||
|
|
34e27ff4c2 | ||
|
|
47588c8e75 | ||
|
|
00c6fcfe98 | ||
|
|
c90f7c3203 | ||
|
|
6467ead9ad | ||
|
|
cb7caf2afc | ||
|
|
c6ebb23f38 | ||
|
|
5753d63958 | ||
|
|
e56d9765d7 | ||
|
|
a5b7ec2624 | ||
|
|
b2fa41307c | ||
|
|
fce74c73c7 | ||
|
|
e110b29c2f | ||
|
|
a3aba0269d | ||
|
|
e1f4aa5fcd | ||
|
|
e19ee86b0d | ||
|
|
6e71b5a59c | ||
|
|
b70092e281 | ||
|
|
602eac89c4 | ||
|
|
d8b5cc6717 | ||
|
|
76fedccf13 | ||
|
|
41206e70b4 | ||
|
|
bc2c37c739 | ||
|
|
4a2a47666f | ||
|
|
94fbbb7669 | ||
|
|
63010c26ad | ||
|
|
f398b2eafa | ||
|
|
1214067d03 | ||
|
|
0469d05447 | ||
|
|
2fcec27e23 | ||
|
|
42d0283489 | ||
|
|
3fbd8036f4 | ||
|
|
3b4bacb5ba | ||
|
|
7e350dab66 | ||
|
|
9c23d50e92 | ||
|
|
2ec7428e32 | ||
|
|
594f81ec8c | ||
|
|
9767b76881 | ||
|
|
0ace93c2a4 | ||
|
|
c73d165165 | ||
|
|
c1945f8275 | ||
|
|
4d368dc06c | ||
|
|
9ff0e9cf72 | ||
|
|
a971d91a70 | ||
|
|
52b74f9f34 | ||
|
|
b932a9a084 | ||
|
|
997f2dffbf | ||
|
|
1289e03134 | ||
|
|
9a8e5e64ed | ||
|
|
774c050f92 | ||
|
|
478a319442 | ||
|
|
24fea5dd7b | ||
|
|
2b05bdfa94 | ||
|
|
6c8a559023 | ||
|
|
ca8c337c94 | ||
|
|
8ccad65504 | ||
|
|
fd11f294bc | ||
|
|
b3fa76c1be | ||
|
|
d3dd9400e3 | ||
|
|
234034d302 | ||
|
|
edc20a7505 | ||
|
|
3a29028f60 | ||
|
|
f4af7603da | ||
|
|
63a28eb46f | ||
|
|
b85d9ee737 | ||
|
|
58042b0e9f | ||
|
|
23759e6eca | ||
|
|
1d3465698f | ||
|
|
b156f083be | ||
|
|
f83b754cd4 | ||
|
|
df4a0d65bd | ||
|
|
77b5532ce9 | ||
|
|
d9ec65da4d | ||
|
|
4b9dcf1cf2 | ||
|
|
1fbac89a38 | ||
|
|
ceacfb83a8 | ||
|
|
d736c8cca6 | ||
|
|
60769903a5 | ||
|
|
8b73bac580 | ||
|
|
c8162c2900 | ||
|
|
de181c91d5 | ||
|
|
687ba1c9ef | ||
|
|
02802b509d | ||
|
|
7f18dd6a4a | ||
|
|
2f7a472230 | ||
|
|
b8f2f46945 | ||
|
|
2570eb1ab8 | ||
|
|
d3062f9a97 | ||
|
|
8619d17f43 | ||
|
|
8062eb3511 | ||
|
|
e0322bf0e0 | ||
|
|
ddc617f80a | ||
|
|
f64364cced | ||
|
|
32502bfac8 | ||
|
|
1f6a98ecb8 | ||
|
|
6ad0f141be | ||
|
|
0b6366aacb | ||
|
|
deed3a63a3 | ||
|
|
cab80b452b | ||
|
|
338d32a7c6 | ||
|
|
88f15a6804 | ||
|
|
20b3f3b9a1 | ||
|
|
1145a5d483 | ||
|
|
125ca9ff73 | ||
|
|
bc1efb1556 | ||
|
|
7b5649097f | ||
|
|
c2e1d76400 | ||
|
|
f7435559a7 | ||
|
|
47afca1fdb | ||
|
|
372c811763 | ||
|
|
dd061b1dda | ||
|
|
eb3c99c54e | ||
|
|
5d864e3f69 | ||
|
|
1b71f91a01 | ||
|
|
b30886228c | ||
|
|
f91de04269 | ||
|
|
a3531db645 | ||
|
|
1e8fe508f0 | ||
|
|
54244fd33d | ||
|
|
4c1d1bb218 | ||
|
|
903326ddf5 | ||
|
|
0105ec284d | ||
|
|
55b253152c | ||
|
|
6573d2b451 | ||
|
|
cfa9ecbfd2 | ||
|
|
b139201a33 | ||
|
|
946b5d1528 | ||
|
|
3b2670532a | ||
|
|
d00bc973fe | ||
|
|
4768b37531 |
@@ -30,7 +30,7 @@ PROJECT_NUMBER = @PACKAGE_VERSION@
|
||||
# If a relative path is entered, it will be relative to the location
|
||||
# where doxygen was started. If left blank the current directory will be used.
|
||||
|
||||
OUTPUT_DIRECTORY = builtin_doc
|
||||
OUTPUT_DIRECTORY = help_doc
|
||||
|
||||
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
|
||||
# 4096 sub-directories (in 2 levels) under the output directory of each output
|
||||
@@ -423,7 +423,7 @@ WARN_LOGFILE =
|
||||
# directories like "/usr/src/myproject". Separate the files or directories
|
||||
# with spaces.
|
||||
|
||||
INPUT =
|
||||
INPUT = doc_src
|
||||
|
||||
# If the value of the INPUT tag contains directories, you can use the
|
||||
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
||||
302
Makefile.in
302
Makefile.in
@@ -96,7 +96,7 @@ FISH_OBJS := function.o builtin.o complete.o env.o exec.o expand.o \
|
||||
# Additional files used by builtin.o
|
||||
#
|
||||
|
||||
BUILTIN_FILES := builtin_help.c builtin_set.c builtin_commandline.c \
|
||||
BUILTIN_FILES := builtin_set.c builtin_commandline.c \
|
||||
builtin_ulimit.c builtin_complete.c builtin_jobs.c
|
||||
|
||||
|
||||
@@ -105,7 +105,8 @@ BUILTIN_FILES := builtin_help.c builtin_set.c builtin_commandline.c \
|
||||
#
|
||||
|
||||
FISH_PAGER_OBJS := fish_pager.o output.o wutil.o tokenizer.o \
|
||||
input_common.o env_universal.o env_universal_common.o common.o
|
||||
input_common.o env_universal.o env_universal_common.o common.o \
|
||||
print_help.o
|
||||
|
||||
|
||||
#
|
||||
@@ -119,62 +120,41 @@ FISH_TESTS_OBJS := $(FISH_OBJS) fish_tests.o
|
||||
# All objects that the system needs to build fishd
|
||||
#
|
||||
|
||||
FISHD_OBJS := fishd.o env_universal_common.o wutil.o \
|
||||
doc_src/fishd.o common.o
|
||||
FISHD_OBJS := fishd.o env_universal_common.o wutil.o print_help.o \
|
||||
common.o
|
||||
|
||||
|
||||
#
|
||||
# All objects needed to build mimedb
|
||||
#
|
||||
|
||||
MIME_OBJS := mimedb.o xdgmimealias.o xdgmime.o xdgmimeglob.o \
|
||||
xdgmimeint.o xdgmimemagic.o xdgmimeparent.o wutil.o common.o
|
||||
MIME_OBJS := mimedb.o print_help.o xdgmimealias.o xdgmime.o \
|
||||
xdgmimeglob.o xdgmimeint.o xdgmimemagic.o xdgmimeparent.o wutil.o \
|
||||
common.o
|
||||
|
||||
|
||||
#
|
||||
# Files containing documentation for builtins.
|
||||
# Files containing user documentation
|
||||
#
|
||||
|
||||
BUILTIN_DOC_SRC := doc_src/source.txt doc_src/and.txt \
|
||||
doc_src/begin.txt doc_src/bg.txt doc_src/bind.txt \
|
||||
doc_src/block.txt doc_src/break.txt doc_src/builtin.txt \
|
||||
doc_src/case.txt doc_src/cd.txt doc_src/command.txt \
|
||||
doc_src/commandline.txt doc_src/complete.txt doc_src/continue.txt \
|
||||
doc_src/else.txt doc_src/end.txt doc_src/eval.txt doc_src/exec.txt \
|
||||
doc_src/exit.txt doc_src/fg.txt doc_src/for.txt \
|
||||
doc_src/function.txt doc_src/functions.txt doc_src/if.txt \
|
||||
doc_src/jobs.txt doc_src/not.txt doc_src/or.txt doc_src/random.txt \
|
||||
doc_src/return.txt doc_src/read.txt doc_src/set.txt \
|
||||
doc_src/status.txt doc_src/switch.txt doc_src/ulimit.txt \
|
||||
doc_src/while.txt
|
||||
#
|
||||
# These files are the source files, they contain a few @FOO@-style substitutions
|
||||
#
|
||||
|
||||
HDR_FILES_SRC := doc_src/index.hdr.in doc_src/commands.hdr.in doc_src/design.hdr doc_src/license.hdr doc_src/faq.hdr
|
||||
|
||||
|
||||
#
|
||||
# Files generated by running doxygen on the files in $(BUILTIN_DOC_SRC)
|
||||
# These are the generated result files
|
||||
#
|
||||
|
||||
BUILTIN_DOC_HDR := $(BUILTIN_DOC_SRC:.txt=.doxygen)
|
||||
|
||||
HDR_FILES := doc_src/index.hdr doc_src/commands.hdr doc_src/design.hdr doc_src/license.hdr doc_src/faq.hdr
|
||||
HDR_FILES := $(subst .hdr.in,.hdr,$(HDR_FILES_SRC))
|
||||
|
||||
#
|
||||
# Files containing documentation for external commands.
|
||||
#
|
||||
|
||||
CMD_DOC_SRC := doc_src/contains.txt doc_src/count.txt doc_src/dirh.txt \
|
||||
doc_src/dirs.txt doc_src/fish.txt doc_src/fish_pager.txt \
|
||||
doc_src/fishd.txt doc_src/help.txt doc_src/isatty.txt \
|
||||
doc_src/mimedb.txt doc_src/nextd.txt doc_src/open.txt \
|
||||
doc_src/popd.txt doc_src/prevd.txt doc_src/psub.txt \
|
||||
doc_src/pushd.txt doc_src/set_color.txt doc_src/trap.txt \
|
||||
doc_src/type.txt doc_src/umask.txt doc_src/vared.txt
|
||||
|
||||
|
||||
#
|
||||
# Files generated by running doxygen on the files in $(CMD_DOC_SRC)
|
||||
#
|
||||
|
||||
CMD_DOC_HDR := $(CMD_DOC_SRC:.txt=.doxygen)
|
||||
HELP_SRC := $(wildcard doc_src/*.txt)
|
||||
|
||||
|
||||
#
|
||||
@@ -192,25 +172,29 @@ TEST_IN := $(wildcard tests/test*.in)
|
||||
# Files in ./doc_src/
|
||||
#
|
||||
|
||||
DOC_SRC_DIR_FILES := doc_src/Doxyfile.in doc_src/index.hdr \
|
||||
doc_src/license.hdr doc_src/faq.hdr doc_src/design.hdr \
|
||||
$(BUILTIN_DOC_SRC) $(CMD_DOC_SRC)
|
||||
DOC_SRC_DIR_FILES := $(HDR_FILES_SRC) $(HELP_SRC)
|
||||
|
||||
|
||||
#
|
||||
# Files in ./. There is some overlap between the variables in the
|
||||
# list, so when copying these files, cp will complain that some files
|
||||
# are specified more than once.
|
||||
# Files in ./
|
||||
#
|
||||
|
||||
MAIN_DIR_FILES := Doxyfile Doxyfile.user Makefile.in configure \
|
||||
configure.ac config.h.in install-sh set_color.c count.c \
|
||||
key_reader.c gen_hdr.sh gen_hdr2.c $(MIME_OBJS:.o=.h) \
|
||||
$(MIME_OBJS:.o=.c) $(FISH_OBJS:.o=.h) $(BUILTIN_FILES) \
|
||||
$(COMMON_FILES) $(COMMON_FILES:.c=.h) $(FISH_OBJS:.o=.c) \
|
||||
builtin_help.hdr fish.spec.in INSTALL README user_doc.head.html \
|
||||
xsel-0.9.6.tar ChangeLog config.sub config.guess fish_tests.c \
|
||||
main.c fish_pager.c fishd.c seq.in
|
||||
MAIN_DIR_FILES_UNSORTED := Doxyfile Doxyfile.user Doxyfile.help.in \
|
||||
Makefile.in configure configure.ac config.h.in install-sh \
|
||||
set_color.c count.c key_reader.c $(MIME_OBJS:.o=.h) \
|
||||
$(MIME_OBJS:.o=.c) $(FISH_OBJS:.o=.h) $(BUILTIN_FILES) \
|
||||
$(COMMON_FILES) $(COMMON_FILES:.c=.h) $(FISH_OBJS:.o=.c) \
|
||||
fish.spec.in INSTALL README user_doc.head.html xsel-0.9.6.tar \
|
||||
ChangeLog config.sub config.guess fish_tests.c main.c fish_pager.c \
|
||||
fishd.c seq.in
|
||||
|
||||
#
|
||||
# The sorting is not meaningful in itself, but it has the side effect
|
||||
# of removing duplicates, which means there will be fewer warnings
|
||||
# during building.
|
||||
#
|
||||
|
||||
MAIN_DIR_FILES := $(sort $(MAIN_DIR_FILES_UNSORTED))
|
||||
|
||||
|
||||
#
|
||||
@@ -253,19 +237,16 @@ FUNCTIONS_DIR_FILES := $(wildcard share/functions/*.fish)
|
||||
# Programs to install
|
||||
#
|
||||
|
||||
PROGRAMS:=fish set_color @XSEL@ @SEQ_FALLBACK@ mimedb count fish_pager fishd
|
||||
SIMPLE_PROGRAMS := fish set_color mimedb count fish_pager fishd
|
||||
PROGRAMS := $(SIMPLE_PROGRAMS) @XSEL@ @SEQ_FALLBACK@
|
||||
|
||||
|
||||
#
|
||||
# Manual pagess to install
|
||||
# Manual pages to install
|
||||
#
|
||||
|
||||
MANUALS:=doc_src/builtin_doc/man/man1/fish.1 @XSEL_MAN_PATH@ \
|
||||
doc_src/builtin_doc/man/man1/mimedb.1 \
|
||||
doc_src/builtin_doc/man/man1/set_color.1 \
|
||||
doc_src/builtin_doc/man/man1/count.1 \
|
||||
doc_src/builtin_doc/man/man1/fishd.1 \
|
||||
doc_src/builtin_doc/man/man1/fish_pager.1
|
||||
MANUALS := $(addsuffix .1, $(addprefix share/man/, \
|
||||
$(SIMPLE_PROGRAMS))) @XSEL_MAN_PATH@
|
||||
|
||||
|
||||
#
|
||||
@@ -280,9 +261,9 @@ TRANSLATIONS := $(TRANSLATIONS_SRC:.po=.gmo)
|
||||
# Make everything needed for installing fish
|
||||
#
|
||||
|
||||
all: $(PROGRAMS) user_doc etc/config.fish share/config.fish share/config_interactive.fish $(TRANSLATIONS)
|
||||
all: $(PROGRAMS) user_doc share/man etc/config.fish share/config.fish share/config_interactive.fish $(TRANSLATIONS)
|
||||
@echo fish has now been built.
|
||||
@echo Use \'make install\' to install fish.
|
||||
@echo Use \'$(MAKE) install\' to install fish.
|
||||
.PHONY: all
|
||||
|
||||
|
||||
@@ -304,7 +285,7 @@ Makefile: Makefile.in configure
|
||||
#
|
||||
|
||||
debug:
|
||||
make fish CFLAGS="@CFLAGS@ $(MACROS) -O0 -Wno-unused -Werror -g"
|
||||
$(MAKE) fish CFLAGS="@CFLAGS@ $(MACROS) -O0 -Wno-unused -Werror -g"
|
||||
.PHONY: debug
|
||||
|
||||
|
||||
@@ -312,8 +293,9 @@ debug:
|
||||
# User documentation, describing the features of the fish shell.
|
||||
#
|
||||
|
||||
user_doc: doc_src/index.hdr doc_src/design.hdr doc_src/license.hdr doc_src/faq.hdr Doxyfile.user user_doc.head.html $(CMD_DOC_SRC) $(BUILTIN_DOC_SRC)
|
||||
$(MAKE) doc.h # Depend on the sources (*.hdr) and manually make the intermediate as needed
|
||||
|
||||
user_doc: $(HDR_FILES) Doxyfile.user user_doc.head.html
|
||||
$(MAKE) doc.h # Depend on the sources (*.hdr) and manually make the intermediate doc.h file if needed
|
||||
doxygen Doxyfile.user
|
||||
touch user_doc
|
||||
|
||||
@@ -322,7 +304,7 @@ user_doc: doc_src/index.hdr doc_src/design.hdr doc_src/license.hdr doc_src/faq.h
|
||||
# Source code documentation. Also includes user documentation.
|
||||
#
|
||||
|
||||
doc: *.h *.c doc.h Doxyfile builtin_help.c
|
||||
doc: *.h *.c doc.h Doxyfile
|
||||
doxygen;
|
||||
|
||||
|
||||
@@ -363,19 +345,32 @@ xsel-0.9.6/xsel: xsel-0.9.6
|
||||
# builtins
|
||||
#
|
||||
|
||||
doc_src/commands.hdr:$(BUILTIN_DOC_SRC) $(CMD_DOC_SRC)
|
||||
rm -f commands.tmp;
|
||||
echo "/** \page commands Commands, functions and builtins bundled with fish" >>commands.tmp;
|
||||
echo "Fish ships with a large number of builtin commands, shellscript functions and external commands. These are all described below. " >>commands.tmp;
|
||||
for i in `printf "%s\n" $(BUILTIN_DOC_SRC) $(CMD_DOC_SRC)|sort`; do \
|
||||
echo "<hr>" >>commands.tmp; \
|
||||
cat $$i >>commands.tmp; \
|
||||
echo >>commands.tmp; \
|
||||
echo >>commands.tmp; \
|
||||
echo "Back to <a href='index.html#toc-commands'>index</a>". >>commands.tmp; \
|
||||
doc_src/commands.hdr:$(HELP_SRC) doc_src/commands.hdr.in
|
||||
-rm command_list.tmp $@
|
||||
for i in `printf "%s\n" $(HELP_SRC)|sort`; do \
|
||||
echo "<hr>" >>command_list.tmp; \
|
||||
cat $$i >>command_list.tmp; \
|
||||
echo >>command_list.tmp; \
|
||||
echo >>command_list.tmp; \
|
||||
echo "Back to <a href='index.html#toc-commands'>index</a>". >>command_list.tmp; \
|
||||
done
|
||||
echo "*/" >>commands.tmp
|
||||
mv commands.tmp doc_src/commands.hdr
|
||||
mv command_list.tmp command_list.txt
|
||||
cat $@.in | awk '{if ($$0 ~ /@command_list@/){ system("cat command_list.txt");} else{ print $$0;}}' >$@
|
||||
|
||||
|
||||
toc.txt: $(subst index.hdr,index.hdr.in,$(HDR_FILES))
|
||||
-rm toc.tmp $@
|
||||
for i in $(subst index.hdr,index.hdr.in,$(HDR_FILES)); do\
|
||||
NAME=`basename $$i .hdr`; \
|
||||
NAME=`basename $$NAME .hdr.in`; \
|
||||
sed <$$i >>toc.tmp -n \
|
||||
-e 's,.*\\page *\([^ ]*\) *\(.*\)$$,- <a href="'$$NAME'.html" name="toc-'$$NAME'">\2</a>,p' \
|
||||
-e 's,.*\\section *\([^ ]*\) *\(.*\)$$, - <a href="'$$NAME'.html#\1" name="toc-'$$NAME'">\2</a>,p'; \
|
||||
done
|
||||
mv toc.tmp $@
|
||||
|
||||
doc_src/index.hdr: toc.txt doc_src/index.hdr.in
|
||||
cat $@.in | awk '{if ($$0 ~ /@toc@/){ system("cat toc.txt");} else{ print $$0;}}' >$@
|
||||
|
||||
|
||||
#
|
||||
@@ -385,19 +380,8 @@ doc_src/commands.hdr:$(BUILTIN_DOC_SRC) $(CMD_DOC_SRC)
|
||||
# documentation.
|
||||
#
|
||||
|
||||
doc.h:$(HDR_FILES)
|
||||
rm -f doc.h
|
||||
echo "/** \mainpage Fish user documentation" >doc.tmp
|
||||
echo "\section toc Table of contents" >>doc.tmp
|
||||
echo '- <a href="index.html" name="toc-index">Fish user documentation</a>' >>doc.tmp
|
||||
for i in $(HDR_FILES); do\
|
||||
sed <$$i >>doc.tmp -n \
|
||||
-e 's,.*\\page *\([^ ]*\) *\(.*\)$$,- <a href="'`basename $$i .hdr`'.html" name="toc-'`basename $$i .hdr`'">\2</a>,p' \
|
||||
-e 's,.*\\section *\([^ ]*\) *\(.*\)$$, - <a href="'`basename $$i .hdr`'.html#\1" name="toc-'`basename $$i .hdr`'">\2</a>,p'; \
|
||||
done
|
||||
cat $(HDR_FILES) >>doc.tmp;
|
||||
mv doc.tmp doc.h
|
||||
|
||||
doc.h: $(HDR_FILES)
|
||||
cat $(HDR_FILES) >$@
|
||||
|
||||
#
|
||||
# This rule creates complete doxygen headers from each of the various
|
||||
@@ -450,10 +434,10 @@ doc.h:$(HDR_FILES)
|
||||
# Create a template translation object
|
||||
#
|
||||
|
||||
messages.pot: *.c *.h etc/*.in share/fish share/completions/*.fish share/functions/*.fish seq
|
||||
messages.pot: *.c *.h etc/*.in share/*.in share/completions/*.fish share/functions/*.fish seq
|
||||
if test $(HAVE_GETTEXT) = 1;then \
|
||||
xgettext -k_ -kN_ *.c *.h -o messages.pot; \
|
||||
if xgettext -j -k_ -kN_ -LShell etc/*.in share/fish share/completions/*.fish share/functions/*.fish seq -o messages.pot; then true; else \
|
||||
if xgettext -j -k_ -kN_ -k--description -LShell etc/*.in share/*.in share/completions/*.fish share/functions/*.fish seq -o messages.pot; then true; else \
|
||||
echo "Your xgettext version is too old to build the messages.pot file"\
|
||||
rm messages.pot\
|
||||
false;\
|
||||
@@ -467,8 +451,7 @@ common.o: $(COMMON_FILES)
|
||||
|
||||
#
|
||||
# Generate the internal help functions by making doxygen create
|
||||
# man-pages which are then converted into C code. The convertion path
|
||||
# looks like this:
|
||||
# man-pages. The convertion path looks like this:
|
||||
#
|
||||
# .txt file
|
||||
# ||
|
||||
@@ -480,70 +463,37 @@ common.o: $(COMMON_FILES)
|
||||
# (doxygen)
|
||||
# ||
|
||||
# \/
|
||||
# man file
|
||||
# roff file
|
||||
# ||
|
||||
# (man)
|
||||
# (__fish_print_help)
|
||||
# ||
|
||||
# \/
|
||||
# formated text
|
||||
# with escape
|
||||
# sequences
|
||||
# ||
|
||||
# \/
|
||||
# (gen_hdr2)
|
||||
# ||
|
||||
# \/
|
||||
# .c file
|
||||
#
|
||||
# Which is an awful, clunky and ugly way of producing
|
||||
# documentation. There ought to be something simpler.
|
||||
#
|
||||
# There ought to be something simpler.
|
||||
#
|
||||
|
||||
doc_src/builtin_doc: $(BUILTIN_DOC_SRC) doc_src/count.txt builtin_help.hdr $(CMD_DOC_SRC)
|
||||
for i in $(BUILTIN_DOC_SRC) $(CMD_DOC_SRC); do \
|
||||
share/man: $(HELP_SRC)
|
||||
-rm doc_src/*.doxygen # Remove temp files from previous run
|
||||
-rm -r help_doc
|
||||
-mkdir share/man
|
||||
touch share/man
|
||||
for i in $(HELP_SRC); do \
|
||||
FILE=doc_src/`basename $$i .txt`.doxygen; \
|
||||
echo "/** \page" `basename $$i .txt` >$$FILE; \
|
||||
cat $$i >>$$FILE; \
|
||||
echo "*/" >>$$FILE; \
|
||||
done
|
||||
cd doc_src; doxygen; cd ..;
|
||||
for i in doc_src/builtin_doc/man/man1/*.1; do \
|
||||
CMD_NAME=`basename $$i .1`; \
|
||||
sed -e "s/\(.\)\\.SH/\1/" -e "s/$$CMD_NAME *\\\\- *\"\(.*\)\"/\1/" <$$i >$$i.tmp; \
|
||||
mv $$i.tmp $$i; \
|
||||
doxygen Doxyfile.help
|
||||
for i in $(HELP_SRC); do \
|
||||
CMD_NAME=`basename $$i .txt`; \
|
||||
sed -e "s/\(.\)\\.SH/\1/" -e "s/$$CMD_NAME *\\\\- *\"\(.*\)\"/\1/" <help_doc/man/man1/$$CMD_NAME.1 >share/man/$$CMD_NAME.1; \
|
||||
done
|
||||
touch doc_src/builtin_doc
|
||||
|
||||
builtin_help.c: doc_src/builtin_doc gen_hdr.sh
|
||||
$(MAKE) gen_hdr2 # Don't depend on gen_hdr2, because then we would need to rebuild the docs whenever we use a fresh tarball
|
||||
cp builtin_help.hdr builtin_help.c;
|
||||
if test -x gen_hdr.sh; then true; else chmod 755 gen_hdr.sh; fi
|
||||
for i in $(BUILTIN_DOC_HDR) doc_src/count.doxygen ; do \
|
||||
echo ' hash_put( &tbl, L"'`basename $$i .doxygen`'",' >>$@; \
|
||||
./gen_hdr.sh $$i >>$@; \
|
||||
printf " );\n\n" >>$@; \
|
||||
done;
|
||||
echo "}" >>builtin_help.c
|
||||
|
||||
|
||||
#
|
||||
# Generate help texts for external fish commands, like set_color and
|
||||
# mimedb.
|
||||
#
|
||||
|
||||
%.c : %.doxygen
|
||||
$(MAKE) gen_hdr2 builtin_help.c # These should really be filed as dependencis for %.c above instead, but that seems to confuse make
|
||||
echo "// This file was automatically generated, do not edit" >$@
|
||||
echo "#include <stdlib.h>" >>$@
|
||||
echo "#include <stdio.h>" >>$@
|
||||
echo >>$@
|
||||
echo "void print_help()" >>$@
|
||||
echo "{" >>$@
|
||||
echo ' printf( "%s",' >>$@
|
||||
chmod 755 gen_hdr.sh
|
||||
./gen_hdr.sh $*.doxygen >>$@
|
||||
echo ");" >>$@
|
||||
echo "}" >>$@
|
||||
rm doc_src/*.doxygen # Clean up intermediate files in doc_src/
|
||||
rm -r help_doc # Clean up intermediate help_doc tree
|
||||
|
||||
#
|
||||
# The build rules for installing/uninstalling fish
|
||||
@@ -561,8 +511,8 @@ check-uninstall:
|
||||
echo;\
|
||||
echo An older fish installation using an incompatible filesystem hierarchy was detected;\
|
||||
echo You must uninstall this fish version before proceeding;\
|
||||
echo type \'make uninstall-legacy\' to uninstall these files,;\
|
||||
echo or type \'make force-install\' to force installation.;\
|
||||
echo type \'$(MAKE) uninstall-legacy\' to uninstall these files,;\
|
||||
echo or type \'$(MAKE) force-install\' to force installation.;\
|
||||
echo The latter may result in a broken installation.;\
|
||||
echo;\
|
||||
false;\
|
||||
@@ -573,7 +523,7 @@ check-uninstall:
|
||||
echo;\
|
||||
echo An older fish installation using an incompatible filesystem hierarchy was detected;\
|
||||
echo You must remove the file $(DESTDIR)$(sysconfdir)/fish before proceeding;\
|
||||
echo type \'make uninstall-legacy\' to uninstall this file,;\
|
||||
echo type \'$(MAKE) uninstall-legacy\' to uninstall this file,;\
|
||||
echo or remove it manually using \'rm $(DESTDIR)$(sysconfdir)/fish\'.;\
|
||||
echo;\
|
||||
false;\
|
||||
@@ -588,9 +538,13 @@ check-uninstall:
|
||||
#
|
||||
|
||||
install-sh:
|
||||
if test -x install-sh; then true; else chmod 755 install-sh; fi
|
||||
if test -x $@; then true; else chmod 755 $@; fi
|
||||
.PHONY: install-sh
|
||||
|
||||
make_mercurial_completions.fish:
|
||||
if test -x $@; then true; else chmod 755 $@; fi
|
||||
.PHONY: make_mercurial_completions.fish
|
||||
|
||||
|
||||
#
|
||||
# Try to install after checking for incompatible installed versions.
|
||||
@@ -614,6 +568,7 @@ install-force: all install-translations
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/fish
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/fish/completions
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/fish/functions
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/fish/man
|
||||
$(INSTALL) -m 644 etc/config.fish $(DESTDIR)$(sysconfdir)/fish/
|
||||
$(INSTALL) -m 644 share/config.fish $(DESTDIR)$(datadir)/fish/
|
||||
$(INSTALL) -m 644 share/config_interactive.fish $(DESTDIR)$(datadir)/fish/
|
||||
@@ -623,6 +578,9 @@ install-force: all install-translations
|
||||
for i in $(FUNCTIONS_DIR_FILES); do \
|
||||
$(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/fish/functions/; \
|
||||
done;
|
||||
for i in share/man/*.1; do \
|
||||
$(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/fish/man/; \
|
||||
done;
|
||||
$(INSTALL) -m 644 etc/fish_inputrc $(DESTDIR)$(sysconfdir)/fish/fish_inputrc;
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(docdir)
|
||||
for i in user_doc/html/* ChangeLog; do \
|
||||
@@ -755,8 +713,8 @@ fish_tests: $(FISH_TESTS_OBJS)
|
||||
# mimedb does not need any libraries, so we don't use LDFLAGS here.
|
||||
#
|
||||
|
||||
mimedb: $(MIME_OBJS) doc_src/mimedb.o
|
||||
$(CC) $(MIME_OBJS) doc_src/mimedb.o $(LDFLAGS) -o $@
|
||||
mimedb: $(MIME_OBJS)
|
||||
$(CC) $(MIME_OBJS) $(LDFLAGS) -o $@
|
||||
|
||||
|
||||
#
|
||||
@@ -773,8 +731,8 @@ count: count.o
|
||||
# Build the set_color program
|
||||
#
|
||||
|
||||
set_color: set_color.o doc_src/set_color.o common.o
|
||||
$(CC) set_color.o doc_src/set_color.o common.o wutil.o $(LDFLAGS) -o $@
|
||||
set_color: set_color.o print_help.o common.o
|
||||
$(CC) set_color.o print_help.o common.o wutil.o $(LDFLAGS) -o $@
|
||||
|
||||
|
||||
#
|
||||
@@ -801,7 +759,6 @@ depend:
|
||||
./config.status
|
||||
.PHONY: depend
|
||||
|
||||
|
||||
#
|
||||
# Copy all the source files into a new directory and use tar to create
|
||||
# an archive from it. Simplest way I could think of to make an archive
|
||||
@@ -811,7 +768,7 @@ depend:
|
||||
# exists
|
||||
#
|
||||
|
||||
fish-@PACKAGE_VERSION@.tar: $(DOC_SRC_DIR_FILES) $(MAIN_DIR_FILES) $(ETC_DIR_FILES) $(TEST_DIR_FILES) $(SHARE_DIR_FILES) $(FUNCTIONS_DIR_FILES) $(COMPLETIONS_DIR_FILES) ChangeLog user_doc doc_src/builtin_doc
|
||||
fish-@PACKAGE_VERSION@.tar: $(DOC_SRC_DIR_FILES) $(MAIN_DIR_FILES) $(ETC_DIR_FILES) $(TEST_DIR_FILES) $(SHARE_DIR_FILES) $(FUNCTIONS_DIR_FILES) $(COMPLETIONS_DIR_FILES) ChangeLog user_doc share/man
|
||||
rm -rf fish-@PACKAGE_VERSION@
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@/doc_src
|
||||
@@ -820,6 +777,7 @@ fish-@PACKAGE_VERSION@.tar: $(DOC_SRC_DIR_FILES) $(MAIN_DIR_FILES) $(ETC_DIR_FIL
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@/share
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@/share/completions
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@/share/functions
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@/share/man
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@/tests
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@/po
|
||||
cp -f $(DOC_SRC_DIR_FILES) fish-@PACKAGE_VERSION@/doc_src
|
||||
@@ -830,8 +788,8 @@ fish-@PACKAGE_VERSION@.tar: $(DOC_SRC_DIR_FILES) $(MAIN_DIR_FILES) $(ETC_DIR_FIL
|
||||
cp -f $(FUNCTIONS_DIR_FILES) fish-@PACKAGE_VERSION@/share/functions/
|
||||
cp -f $(TESTS_DIR_FILES) fish-@PACKAGE_VERSION@/tests/
|
||||
cp -f $(TRANSLATIONS_SRC) fish-@PACKAGE_VERSION@/po/
|
||||
cp -f share/man/*.1 fish-@PACKAGE_VERSION@/share/man/
|
||||
cp -rf user_doc fish-@PACKAGE_VERSION@/
|
||||
cp -rf doc_src/builtin_doc fish-@PACKAGE_VERSION@/doc_src/
|
||||
tar -c fish-@PACKAGE_VERSION@ >fish-@PACKAGE_VERSION@.tar
|
||||
rm -rf fish-@PACKAGE_VERSION@
|
||||
|
||||
@@ -865,6 +823,22 @@ fish.spec: fish.spec.in
|
||||
./config.status
|
||||
|
||||
|
||||
#
|
||||
# Completion files which are autogenerated using various scripts
|
||||
#
|
||||
|
||||
share/completions/darcs.fish: make_mercurial_completions.fish
|
||||
./make_mercurial_completions.fish darcs 'complete -c darcs -n "not __fish_use_subcommand" -a "(test -f _darcs/prefs/repos; and cat _darcs/prefs/repos)" --description "Darcs repo"' 'complete -c darcs -a "test predist boringfile binariesfile" -n "contains setpref (commandline -poc)" -d "woot" -x' >$@
|
||||
|
||||
share/completions/hg.fish: make_mercurial_completions.fish
|
||||
./make_mercurial_completions.fish hg >$@
|
||||
|
||||
share/completions/svn.fish: make_mercurial_completions.fish
|
||||
./make_mercurial_completions.fish svn >$@
|
||||
|
||||
share/completions/cvs.fish: make_mercurial_completions.fish
|
||||
./make_mercurial_completions.fish cvs >$@
|
||||
|
||||
#
|
||||
# Create .rpm file for the current systems architecture and an
|
||||
# .src.rpm file.
|
||||
@@ -894,7 +868,7 @@ rpm: fish-@PACKAGE_VERSION@.tar.bz2 fish.spec
|
||||
#
|
||||
|
||||
distclean: clean
|
||||
rm -f fish.spec doc_src/Doxyfile
|
||||
rm -f fish.spec Doxyfile.help
|
||||
rm -f etc/config.fish share/config_interactive.fish seq share/config.fish
|
||||
rm -f config.status config.log config.h Makefile
|
||||
.PHONY: distclean
|
||||
@@ -908,7 +882,7 @@ distclean: clean
|
||||
clean:
|
||||
rm -f *.o doc.h doc.tmp doc_src/*.doxygen doc_src/*.c doc_src/*.o doc_src/commands.hdr
|
||||
rm -f tests/tmp.err tests/tmp.out tests/tmp.status tests/foo.txt
|
||||
rm -f tokenizer_test fish key_reader set_color gen_hdr2 mimedb
|
||||
rm -f tokenizer_test fish key_reader set_color mimedb
|
||||
rm -f fishd fish_pager count fish_tests
|
||||
rm -f fish-@PACKAGE_VERSION@.tar
|
||||
rm -f fish-@PACKAGE_VERSION@.tar.gz
|
||||
@@ -926,8 +900,8 @@ builtin.o: config.h fallback.h util.h wutil.h builtin.h function.h complete.h
|
||||
builtin.o: proc.h io.h parser.h event.h reader.h env.h common.h wgetopt.h
|
||||
builtin.o: sanity.h tokenizer.h wildcard.h input_common.h input.h intern.h
|
||||
builtin.o: signal.h halloc.h halloc_util.h parse_util.h expand.h path.h
|
||||
builtin.o: builtin_help.c builtin_set.c builtin_commandline.c
|
||||
builtin.o: builtin_complete.c builtin_ulimit.c builtin_jobs.c
|
||||
builtin.o: builtin_set.c builtin_commandline.c builtin_complete.c
|
||||
builtin.o: builtin_ulimit.c builtin_jobs.c
|
||||
builtin_commandline.o: config.h signal.h fallback.h util.h wutil.h builtin.h
|
||||
builtin_commandline.o: common.h wgetopt.h reader.h proc.h io.h parser.h
|
||||
builtin_commandline.o: event.h tokenizer.h input_common.h input.h
|
||||
@@ -935,7 +909,6 @@ builtin_commandline.o: parse_util.h
|
||||
builtin_complete.o: config.h signal.h fallback.h util.h wutil.h builtin.h
|
||||
builtin_complete.o: common.h complete.h wgetopt.h parser.h proc.h io.h
|
||||
builtin_complete.o: event.h reader.h
|
||||
builtin_help.o: config.h util.h common.h halloc_util.h
|
||||
builtin_jobs.o: config.h fallback.h util.h wutil.h builtin.h proc.h io.h
|
||||
builtin_jobs.o: parser.h event.h common.h wgetopt.h
|
||||
builtin_set.o: config.h signal.h fallback.h util.h wutil.h builtin.h env.h
|
||||
@@ -960,8 +933,7 @@ event.o: config.h signal.h fallback.h util.h wutil.h function.h proc.h io.h
|
||||
event.o: parser.h event.h common.h halloc_util.h
|
||||
exec.o: config.h signal.h fallback.h util.h common.h wutil.h proc.h io.h
|
||||
exec.o: exec.h parser.h event.h builtin.h function.h env.h wildcard.h
|
||||
exec.o: sanity.h expand.h env_universal.h env_universal_common.h halloc.h
|
||||
exec.o: halloc_util.h parse_util.h
|
||||
exec.o: sanity.h expand.h halloc.h halloc_util.h parse_util.h
|
||||
expand.o: config.h signal.h fallback.h util.h common.h wutil.h env.h proc.h
|
||||
expand.o: io.h parser.h event.h expand.h wildcard.h exec.h tokenizer.h
|
||||
expand.o: complete.h parse_util.h halloc.h halloc_util.h
|
||||
@@ -976,7 +948,7 @@ fish_tests.o: reader.h builtin.h function.h complete.h wutil.h env.h expand.h
|
||||
fish_tests.o: parser.h event.h tokenizer.h output.h exec.h halloc_util.h
|
||||
function.o: config.h signal.h wutil.h fallback.h util.h function.h proc.h
|
||||
function.o: io.h parser.h event.h common.h intern.h reader.h parse_util.h
|
||||
function.o: env.h expand.h
|
||||
function.o: env.h expand.h halloc.h halloc_util.h
|
||||
halloc.o: config.h fallback.h util.h common.h halloc.h
|
||||
halloc_util.o: config.h fallback.h util.h common.h halloc.h
|
||||
highlight.o: config.h signal.h fallback.h util.h wutil.h highlight.h
|
||||
@@ -1011,7 +983,7 @@ parser.o: env_universal_common.h intern.h parse_util.h halloc.h halloc_util.h
|
||||
parser.o: path.h
|
||||
parse_util.o: config.h fallback.h util.h wutil.h common.h tokenizer.h
|
||||
parse_util.o: parse_util.h expand.h intern.h exec.h proc.h io.h env.h
|
||||
parse_util.o: wildcard.h halloc_util.h
|
||||
parse_util.o: signal.h wildcard.h halloc_util.h
|
||||
path.o: config.h fallback.h util.h common.h env.h wutil.h halloc.h
|
||||
path.o: halloc_util.h path.h expand.h
|
||||
proc.o: config.h signal.h fallback.h util.h wutil.h proc.h io.h common.h
|
||||
@@ -1024,8 +996,8 @@ reader.o: function.h output.h screen.h parse_util.h
|
||||
sanity.o: config.h signal.h fallback.h util.h common.h sanity.h proc.h io.h
|
||||
sanity.o: history.h reader.h kill.h wutil.h
|
||||
screen.o: config.h fallback.h common.h util.h wutil.h output.h highlight.h
|
||||
screen.o: screen.h
|
||||
set_color.o: config.h fallback.h
|
||||
screen.o: screen.h env.h
|
||||
set_color.o: config.h fallback.h print_help.h
|
||||
signal.o: config.h signal.h common.h util.h fallback.h wutil.h event.h
|
||||
signal.o: reader.h proc.h io.h
|
||||
test.o: stringtab.h
|
||||
|
||||
408
builtin.c
408
builtin.c
@@ -60,6 +60,8 @@
|
||||
#include "intern.h"
|
||||
#include "event.h"
|
||||
#include "signal.h"
|
||||
#include "exec.h"
|
||||
#include "highlight.h"
|
||||
|
||||
#include "halloc.h"
|
||||
#include "halloc_util.h"
|
||||
@@ -138,7 +140,6 @@ static hash_table_t *desc=0;
|
||||
/**
|
||||
Counts the number of non null pointers in the specified array
|
||||
*/
|
||||
|
||||
static int builtin_count_args( wchar_t **argv )
|
||||
{
|
||||
int argc = 1;
|
||||
@@ -193,11 +194,55 @@ static int count_char( const wchar_t *str, wchar_t c )
|
||||
|
||||
*/
|
||||
|
||||
|
||||
static void builtin_print_help( wchar_t *cmd, string_buffer_t *b )
|
||||
wchar_t *builtin_help_get( const wchar_t *name )
|
||||
{
|
||||
const char *h;
|
||||
array_list_t lst;
|
||||
string_buffer_t cmd;
|
||||
wchar_t *name_esc;
|
||||
|
||||
static string_buffer_t *out = 0;
|
||||
int i;
|
||||
|
||||
al_init( &lst );
|
||||
sb_init( &cmd );
|
||||
|
||||
if( !out )
|
||||
{
|
||||
out = sb_halloc( global_context );
|
||||
}
|
||||
else
|
||||
{
|
||||
sb_clear( out );
|
||||
}
|
||||
|
||||
name_esc = escape( name, 1 );
|
||||
sb_printf( &cmd, L"__fish_print_help %ls", name_esc );
|
||||
|
||||
|
||||
if( exec_subshell( (wchar_t *)cmd.buff, &lst ) >= 0 )
|
||||
{
|
||||
for( i=0; i<al_get_count( &lst); i++ )
|
||||
{
|
||||
sb_append( out, (wchar_t *)al_get( &lst, i ) );
|
||||
sb_append( out, L"\n" );
|
||||
}
|
||||
}
|
||||
|
||||
al_destroy( &lst );
|
||||
sb_destroy( &cmd );
|
||||
free( name_esc );
|
||||
|
||||
return (wchar_t *)out->buff;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void builtin_print_help( const wchar_t *cmd, string_buffer_t *b )
|
||||
{
|
||||
|
||||
const wchar_t *h;
|
||||
int is_short = 0;
|
||||
|
||||
if( b == sb_err )
|
||||
{
|
||||
sb_append( sb_err,
|
||||
@@ -209,64 +254,114 @@ static void builtin_print_help( wchar_t *cmd, string_buffer_t *b )
|
||||
if( !h )
|
||||
return;
|
||||
|
||||
wchar_t *str = str2wcs( h );
|
||||
wchar_t *str = wcsdup( h );
|
||||
if( str )
|
||||
{
|
||||
|
||||
if( is_interactive && !builtin_out_redirect && b==sb_err)
|
||||
if( b==sb_err )
|
||||
{
|
||||
|
||||
/* Interactive mode help to screen - only print synopsis if the rest won't fit */
|
||||
/*
|
||||
Interactive mode help to screen - only print synopsis if
|
||||
the rest won't fit
|
||||
*/
|
||||
|
||||
int screen_height, lines;
|
||||
|
||||
screen_height = common_get_height();
|
||||
lines = count_char( str, L'\n' );
|
||||
if( lines > 2*screen_height/3 )
|
||||
if( !is_interactive || (lines > 2*screen_height/3) )
|
||||
{
|
||||
wchar_t *pos;
|
||||
int cut=0;
|
||||
int i;
|
||||
|
||||
/* Find first empty line */
|
||||
for( pos=str; *pos; pos++ )
|
||||
is_short = 1;
|
||||
|
||||
/*
|
||||
First move down 4 lines
|
||||
*/
|
||||
|
||||
pos = str;
|
||||
for( i=0; i<4; i++ )
|
||||
{
|
||||
pos = wcschr( pos+1, L'\n' );
|
||||
if( !pos )
|
||||
break;
|
||||
}
|
||||
|
||||
if( pos )
|
||||
{
|
||||
if( *pos == L'\n' )
|
||||
{
|
||||
wchar_t *pos2;
|
||||
int is_empty = 1;
|
||||
|
||||
for( pos2 = pos+1; *pos2; pos2++ )
|
||||
/*
|
||||
Then find the next empty line
|
||||
*/
|
||||
for( ; *pos; pos++ )
|
||||
{
|
||||
if( *pos == L'\n' )
|
||||
{
|
||||
if( *pos2 == L'\n' )
|
||||
break;
|
||||
wchar_t *pos2;
|
||||
int is_empty = 1;
|
||||
|
||||
if( *pos2 != L'\t' && *pos2 !=L' ' )
|
||||
for( pos2 = pos+1; *pos2; pos2++ )
|
||||
{
|
||||
is_empty = 0;
|
||||
if( *pos2 == L'\n' )
|
||||
break;
|
||||
|
||||
if( *pos2 != L'\t' && *pos2 !=L' ' )
|
||||
{
|
||||
is_empty = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( is_empty )
|
||||
{
|
||||
/*
|
||||
And cut it
|
||||
*/
|
||||
*(pos2+1)=L'\0';
|
||||
cut = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( is_empty )
|
||||
{
|
||||
*(pos+1)=L'\0';
|
||||
cut = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
We did not find a good place to cut message to
|
||||
shorten it - so we make sure we don't print
|
||||
anything.
|
||||
*/
|
||||
if( !cut )
|
||||
{
|
||||
*str = 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
sb_append( b, str );
|
||||
if( is_short )
|
||||
{
|
||||
sb_printf( b, _(L"%ls: Type 'help %ls' for related documentation\n\n"), cmd, cmd );
|
||||
}
|
||||
|
||||
free( str );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Perform error reporting for encounter with unknown option
|
||||
*/
|
||||
static void builtin_unknown_option( const wchar_t *cmd, const wchar_t *opt )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
BUILTIN_ERR_UNKNOWN,
|
||||
cmd,
|
||||
opt );
|
||||
builtin_print_help( cmd, sb_err );
|
||||
}
|
||||
|
||||
/*
|
||||
Here follows the definition of all builtin commands. The function
|
||||
names are all on the form builtin_NAME where NAME is the name of the
|
||||
@@ -282,12 +377,12 @@ static void builtin_print_help( wchar_t *cmd, string_buffer_t *b )
|
||||
|
||||
Several other builtins, including jobs, ulimit and set are so big
|
||||
that they have been given their own file. These files are all named
|
||||
'builtin_NAME.c', where NAME is the name of the builtin.
|
||||
'builtin_NAME.c', where NAME is the name of the builtin. These files
|
||||
are included directly below.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "builtin_help.c"
|
||||
#include "builtin_set.c"
|
||||
#include "builtin_commandline.c"
|
||||
#include "builtin_complete.c"
|
||||
@@ -353,11 +448,10 @@ static int builtin_bind( wchar_t **argv )
|
||||
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
return STATUS_BUILTIN_OK;
|
||||
|
||||
case '?':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
builtin_unknown_option( argv[0], argv[woptind-1] );
|
||||
return STATUS_BUILTIN_ERROR;
|
||||
|
||||
}
|
||||
@@ -369,7 +463,7 @@ static int builtin_bind( wchar_t **argv )
|
||||
input_parse_inputrc_line( argv[i] );
|
||||
}
|
||||
|
||||
return 0;
|
||||
return STATUS_BUILTIN_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -443,7 +537,7 @@ static int builtin_block( wchar_t **argv )
|
||||
return STATUS_BUILTIN_ERROR;
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
return STATUS_BUILTIN_OK;
|
||||
|
||||
case 'g':
|
||||
scope = GLOBAL;
|
||||
@@ -458,8 +552,7 @@ static int builtin_block( wchar_t **argv )
|
||||
break;
|
||||
|
||||
case '?':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
builtin_unknown_option( argv[0], argv[woptind-1] );
|
||||
return STATUS_BUILTIN_ERROR;
|
||||
|
||||
}
|
||||
@@ -526,7 +619,7 @@ static int builtin_block( wchar_t **argv )
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return STATUS_BUILTIN_OK;
|
||||
|
||||
}
|
||||
|
||||
@@ -584,15 +677,14 @@ static int builtin_builtin( wchar_t **argv )
|
||||
return STATUS_BUILTIN_ERROR;
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
return STATUS_BUILTIN_OK;
|
||||
|
||||
case 'n':
|
||||
list=1;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
builtin_unknown_option( argv[0], argv[woptind-1] );
|
||||
return STATUS_BUILTIN_ERROR;
|
||||
|
||||
}
|
||||
@@ -622,7 +714,7 @@ static int builtin_builtin( wchar_t **argv )
|
||||
}
|
||||
al_destroy( &names );
|
||||
}
|
||||
return 0;
|
||||
return STATUS_BUILTIN_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -674,11 +766,10 @@ static int builtin_generic( wchar_t **argv )
|
||||
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
return STATUS_BUILTIN_OK;
|
||||
|
||||
case '?':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
builtin_unknown_option( argv[0], argv[woptind-1] );
|
||||
return STATUS_BUILTIN_ERROR;
|
||||
|
||||
}
|
||||
@@ -783,7 +874,7 @@ static int builtin_functions( wchar_t **argv )
|
||||
int argc=builtin_count_args( argv );
|
||||
int list=0;
|
||||
int show_hidden=0;
|
||||
int res = 0;
|
||||
int res = STATUS_BUILTIN_OK;
|
||||
int query = 0;
|
||||
|
||||
woptind=0;
|
||||
@@ -865,15 +956,14 @@ static int builtin_functions( wchar_t **argv )
|
||||
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
return STATUS_BUILTIN_OK;
|
||||
|
||||
case 'q':
|
||||
query = 1;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
builtin_unknown_option( argv[0], argv[woptind-1] );
|
||||
return STATUS_BUILTIN_ERROR;
|
||||
|
||||
}
|
||||
@@ -883,13 +973,12 @@ static int builtin_functions( wchar_t **argv )
|
||||
/*
|
||||
Erase, desc, query and list are mutually exclusive
|
||||
*/
|
||||
if( (erase + (desc!=0) + list + query) > 1 )
|
||||
if( (erase + (!!desc) + list + query) > 1 )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: Invalid combination of options\n" ),
|
||||
argv[0] );
|
||||
|
||||
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
return STATUS_BUILTIN_ERROR;
|
||||
@@ -900,7 +989,7 @@ static int builtin_functions( wchar_t **argv )
|
||||
int i;
|
||||
for( i=woptind; i<argc; i++ )
|
||||
function_remove( argv[i] );
|
||||
return 0;
|
||||
return STATUS_BUILTIN_OK;
|
||||
}
|
||||
else if( desc )
|
||||
{
|
||||
@@ -930,9 +1019,9 @@ static int builtin_functions( wchar_t **argv )
|
||||
|
||||
function_set_desc( func, desc );
|
||||
|
||||
return 0;
|
||||
return STATUS_BUILTIN_OK;
|
||||
}
|
||||
else if( list )
|
||||
else if( list || (argc==woptind))
|
||||
{
|
||||
int is_screen = !builtin_out_redirect && isatty(1);
|
||||
|
||||
@@ -967,49 +1056,22 @@ static int builtin_functions( wchar_t **argv )
|
||||
}
|
||||
|
||||
al_destroy( &names );
|
||||
return 0;
|
||||
return STATUS_BUILTIN_OK;
|
||||
}
|
||||
|
||||
switch( argc - woptind )
|
||||
for( i=woptind; i<argc; i++ )
|
||||
{
|
||||
case 0:
|
||||
if( !function_exists( argv[i] ) )
|
||||
res++;
|
||||
else
|
||||
{
|
||||
if( !query )
|
||||
{
|
||||
sb_append( sb_out, _( L"Current function definitions are:\n\n" ) );
|
||||
al_init( &names );
|
||||
function_get_names( &names, show_hidden );
|
||||
sort_list( &names );
|
||||
|
||||
for( i=0; i<al_get_count( &names ); i++ )
|
||||
{
|
||||
functions_def( (wchar_t *)al_get( &names, i ), sb_out );
|
||||
}
|
||||
|
||||
al_destroy( &names );
|
||||
functions_def( argv[i], sb_out );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
for( i=woptind; i<argc; i++ )
|
||||
{
|
||||
if( !function_exists( argv[i] ) )
|
||||
res++;
|
||||
else
|
||||
{
|
||||
if( !query )
|
||||
{
|
||||
functions_def( argv[i], sb_out );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
@@ -1031,7 +1093,7 @@ typedef struct function_data
|
||||
static int builtin_function( wchar_t **argv )
|
||||
{
|
||||
int argc = builtin_count_args( argv );
|
||||
int res=0;
|
||||
int res=STATUS_BUILTIN_OK;
|
||||
wchar_t *desc=0;
|
||||
array_list_t *events;
|
||||
int i;
|
||||
@@ -1231,10 +1293,10 @@ static int builtin_function( wchar_t **argv )
|
||||
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
return STATUS_BUILTIN_OK;
|
||||
|
||||
case '?':
|
||||
|
||||
builtin_unknown_option( argv[0], argv[woptind-1] );
|
||||
res = 1;
|
||||
break;
|
||||
|
||||
@@ -1328,7 +1390,7 @@ static int builtin_function( wchar_t **argv )
|
||||
current_block->tok_pos = parser_get_pos();
|
||||
current_block->skip = 1;
|
||||
|
||||
return 0;
|
||||
return STATUS_BUILTIN_OK;
|
||||
|
||||
}
|
||||
|
||||
@@ -1387,8 +1449,7 @@ static int builtin_random( wchar_t **argv )
|
||||
break;
|
||||
|
||||
case '?':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
builtin_unknown_option( argv[0], argv[woptind-1] );
|
||||
return STATUS_BUILTIN_ERROR;
|
||||
|
||||
}
|
||||
@@ -1444,7 +1505,7 @@ static int builtin_random( wchar_t **argv )
|
||||
return STATUS_BUILTIN_ERROR;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return STATUS_BUILTIN_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1460,7 +1521,9 @@ static int builtin_read( wchar_t **argv )
|
||||
wchar_t *nxt;
|
||||
wchar_t *prompt = DEFAULT_READ_PROMPT;
|
||||
wchar_t *commandline = L"";
|
||||
int exit_res=0;
|
||||
int exit_res=STATUS_BUILTIN_OK;
|
||||
wchar_t *mode_name = READ_MODE_NAME;
|
||||
int shell = 0;
|
||||
|
||||
woptind=0;
|
||||
|
||||
@@ -1497,6 +1560,14 @@ static int builtin_read( wchar_t **argv )
|
||||
L"command", required_argument, 0, 'c'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"mode-name", required_argument, 0, 'm'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"shell", required_argument, 0, 's'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"help", no_argument, 0, 'h'
|
||||
}
|
||||
@@ -1511,7 +1582,7 @@ static int builtin_read( wchar_t **argv )
|
||||
|
||||
int opt = wgetopt_long( argc,
|
||||
argv,
|
||||
L"xglUup:c:h",
|
||||
L"xglUup:c:hm:s",
|
||||
long_options,
|
||||
&opt_index );
|
||||
if( opt == -1 )
|
||||
@@ -1533,32 +1604,45 @@ static int builtin_read( wchar_t **argv )
|
||||
case L'x':
|
||||
place |= ENV_EXPORT;
|
||||
break;
|
||||
|
||||
case L'g':
|
||||
place |= ENV_GLOBAL;
|
||||
break;
|
||||
|
||||
case L'l':
|
||||
place |= ENV_LOCAL;
|
||||
break;
|
||||
|
||||
case L'U':
|
||||
place |= ENV_UNIVERSAL;
|
||||
break;
|
||||
|
||||
case L'u':
|
||||
place |= ENV_UNEXPORT;
|
||||
break;
|
||||
|
||||
case L'p':
|
||||
prompt = woptarg;
|
||||
break;
|
||||
|
||||
case L'c':
|
||||
commandline = woptarg;
|
||||
break;
|
||||
|
||||
case L'm':
|
||||
mode_name = woptarg;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
shell = 1;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
return STATUS_BUILTIN_OK;
|
||||
|
||||
case L'?':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
builtin_unknown_option( argv[0], argv[woptind-1] );
|
||||
return STATUS_BUILTIN_ERROR;
|
||||
}
|
||||
|
||||
@@ -1568,8 +1652,7 @@ static int builtin_read( wchar_t **argv )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
BUILTIN_ERR_EXPUNEXP,
|
||||
argv[0],
|
||||
parser_current_line() );
|
||||
argv[0] );
|
||||
|
||||
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
@@ -1580,8 +1663,7 @@ static int builtin_read( wchar_t **argv )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
BUILTIN_ERR_GLOCAL,
|
||||
argv[0],
|
||||
parser_current_line() );
|
||||
argv[0] );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
return STATUS_BUILTIN_ERROR;
|
||||
@@ -1605,7 +1687,7 @@ static int builtin_read( wchar_t **argv )
|
||||
if( (!iswalnum(*src)) && (*src != L'_' ) )
|
||||
{
|
||||
sb_printf( sb_err, BUILTIN_ERR_VARCHAR, argv[0], *src );
|
||||
sb_append2(sb_err, parser_current_line(), L"\n", (void *)0 );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return STATUS_BUILTIN_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -1622,11 +1704,29 @@ static int builtin_read( wchar_t **argv )
|
||||
*/
|
||||
if( isatty(0) && builtin_stdin == 0 )
|
||||
{
|
||||
reader_push( READ_MODE_NAME );
|
||||
wchar_t *line;
|
||||
|
||||
reader_push( mode_name );
|
||||
reader_set_prompt( prompt );
|
||||
|
||||
if( shell )
|
||||
{
|
||||
reader_set_complete_function( &complete );
|
||||
reader_set_highlight_function( &highlight_shell );
|
||||
reader_set_test_function( &reader_shell_test );
|
||||
}
|
||||
|
||||
reader_set_buffer( commandline, wcslen( commandline ) );
|
||||
buff = wcsdup(reader_readline( ));
|
||||
proc_push_interactive( 1 );
|
||||
line = reader_readline( );
|
||||
proc_pop_interactive();
|
||||
if( line )
|
||||
{
|
||||
buff = wcsdup( line );
|
||||
}
|
||||
else
|
||||
{
|
||||
exit_res = STATUS_BUILTIN_ERROR;
|
||||
}
|
||||
reader_pop();
|
||||
}
|
||||
else
|
||||
@@ -1694,7 +1794,7 @@ static int builtin_read( wchar_t **argv )
|
||||
sb_destroy( &sb );
|
||||
}
|
||||
|
||||
if( i != argc )
|
||||
if( i != argc && !exit_res )
|
||||
{
|
||||
|
||||
wchar_t *state;
|
||||
@@ -1745,7 +1845,7 @@ static int builtin_status( wchar_t **argv )
|
||||
int mode = NORMAL;
|
||||
|
||||
int argc = builtin_count_args( argv );
|
||||
int res=0;
|
||||
int res=STATUS_BUILTIN_OK;
|
||||
|
||||
woptind=0;
|
||||
|
||||
@@ -1833,7 +1933,7 @@ static int builtin_status( wchar_t **argv )
|
||||
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
return STATUS_BUILTIN_OK;
|
||||
|
||||
case 'j':
|
||||
if( wcscmp( woptarg, L"full" ) == 0 )
|
||||
@@ -1853,8 +1953,7 @@ static int builtin_status( wchar_t **argv )
|
||||
break;
|
||||
|
||||
case '?':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
builtin_unknown_option( argv[0], argv[woptind-1] );
|
||||
return STATUS_BUILTIN_ERROR;
|
||||
|
||||
}
|
||||
@@ -2013,7 +2112,7 @@ static int set_pwd( wchar_t *env)
|
||||
if( !res )
|
||||
{
|
||||
builtin_wperror( L"wgetcwd" );
|
||||
return 0;
|
||||
return STATUS_BUILTIN_OK;
|
||||
}
|
||||
env_set( env, dir_path, ENV_EXPORT | ENV_GLOBAL );
|
||||
return 1;
|
||||
@@ -2029,7 +2128,7 @@ static int builtin_cd( wchar_t **argv )
|
||||
{
|
||||
wchar_t *dir_in;
|
||||
wchar_t *dir;
|
||||
int res=0;
|
||||
int res=STATUS_BUILTIN_OK;
|
||||
void *context = halloc( 0, 0 );
|
||||
|
||||
|
||||
@@ -2097,7 +2196,7 @@ static int builtin_cd( wchar_t **argv )
|
||||
static int builtin_source( wchar_t ** argv )
|
||||
{
|
||||
int fd;
|
||||
int res;
|
||||
int res = STATUS_BUILTIN_OK;
|
||||
struct stat buf;
|
||||
int argc;
|
||||
|
||||
@@ -2126,7 +2225,7 @@ static int builtin_source( wchar_t ** argv )
|
||||
if( ( fd = wopen( argv[1], O_RDONLY ) ) == -1 )
|
||||
{
|
||||
builtin_wperror( L"open" );
|
||||
res = 1;
|
||||
res = STATUS_BUILTIN_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2380,7 +2479,7 @@ static int send_to_bg( job_t *j, const wchar_t *name )
|
||||
make_first( j );
|
||||
job_set_flag( j, JOB_FOREGROUND, 0 );
|
||||
job_continue( j, job_is_stopped(j) );
|
||||
return 0;
|
||||
return STATUS_BUILTIN_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -2389,7 +2488,7 @@ static int send_to_bg( job_t *j, const wchar_t *name )
|
||||
*/
|
||||
static int builtin_bg( wchar_t **argv )
|
||||
{
|
||||
int res = 0;
|
||||
int res = STATUS_BUILTIN_OK;
|
||||
|
||||
if( argv[1] == 0 )
|
||||
{
|
||||
@@ -2416,12 +2515,36 @@ static int builtin_bg( wchar_t **argv )
|
||||
}
|
||||
else
|
||||
{
|
||||
for( argv++; !res && *argv != 0; argv++ )
|
||||
wchar_t *end;
|
||||
int i;
|
||||
int pid;
|
||||
int err = 0;
|
||||
|
||||
for( i=1; argv[i]; i++ )
|
||||
{
|
||||
int pid = wcstol( *argv, 0, 10 );
|
||||
res |= send_to_bg( job_get_from_pid( pid ), *argv);
|
||||
errno=0;
|
||||
pid = (int)wcstol( argv[i], &end, 10 );
|
||||
if( errno || pid < 0 || *end || !job_get_from_pid( pid ) )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: '%ls' is not a job\n" ),
|
||||
argv[0],
|
||||
argv[i] );
|
||||
err = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !err )
|
||||
{
|
||||
for( i=1; !res && argv[i]; i++ )
|
||||
{
|
||||
pid = (int)wcstol( argv[i], 0, 10 );
|
||||
res |= send_to_bg( job_get_from_pid( pid ), *argv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -2432,7 +2555,7 @@ static int builtin_bg( wchar_t **argv )
|
||||
static int builtin_for( wchar_t **argv )
|
||||
{
|
||||
int argc = builtin_count_args( argv );
|
||||
int res=1;
|
||||
int res=STATUS_BUILTIN_ERROR;
|
||||
|
||||
|
||||
if( argc < 3)
|
||||
@@ -2619,9 +2742,9 @@ static int builtin_end( wchar_t **argv )
|
||||
else
|
||||
{
|
||||
debug(0,
|
||||
_(L"%ls: Missing function definition information. This is a fish bug. If you can reproduce it, please file a bug report to %s."),
|
||||
argv[0],
|
||||
PACKAGE_BUGREPORT);
|
||||
_(L"%ls: Missing function definition information."),
|
||||
argv[0] );
|
||||
bugreport();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2633,7 +2756,6 @@ static int builtin_end( wchar_t **argv )
|
||||
parser_pop_block();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
If everything goes ok, return status of last command to execute.
|
||||
*/
|
||||
@@ -2718,7 +2840,7 @@ static int builtin_break_continue( wchar_t **argv )
|
||||
}
|
||||
b->skip=1;
|
||||
b->loop_status = is_break?LOOP_BREAK:LOOP_CONTINUE;
|
||||
return 0;
|
||||
return STATUS_BUILTIN_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2793,7 +2915,7 @@ static int builtin_return( wchar_t **argv )
|
||||
*/
|
||||
static int builtin_switch( wchar_t **argv )
|
||||
{
|
||||
int res=0;
|
||||
int res=STATUS_BUILTIN_OK;
|
||||
int argc = builtin_count_args( argv );
|
||||
|
||||
if( argc != 2 )
|
||||
@@ -2841,7 +2963,7 @@ static int builtin_case( wchar_t **argv )
|
||||
|
||||
if( current_block->param2.switch_taken )
|
||||
{
|
||||
return 0;
|
||||
return STATUS_BUILTIN_OK;
|
||||
}
|
||||
|
||||
for( i=1; i<argc; i++ )
|
||||
@@ -2860,7 +2982,7 @@ static int builtin_case( wchar_t **argv )
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return STATUS_BUILTIN_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -3027,7 +3149,7 @@ const static builtin_data_t builtin_data[]=
|
||||
displays the help for count, but 'count (echo -h)' does not.
|
||||
*/
|
||||
{
|
||||
L"count", &builtin_generic, 0
|
||||
L"count", &builtin_generic, N_( L"Count the number of arguments" )
|
||||
}
|
||||
,
|
||||
{
|
||||
@@ -3042,6 +3164,8 @@ void builtin_init()
|
||||
|
||||
int i;
|
||||
|
||||
wopterr = 0;
|
||||
|
||||
al_init( &io_stack );
|
||||
hash_init( &builtin, &hash_wcs_func, &hash_wcs_cmp );
|
||||
|
||||
@@ -3076,7 +3200,7 @@ int builtin_exists( wchar_t *cmd )
|
||||
if( wcscmp( cmd, L"count" )==0)
|
||||
return 0;
|
||||
|
||||
return (hash_get(&builtin, cmd) != 0 );
|
||||
return !!hash_get(&builtin, cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3087,14 +3211,12 @@ static int internal_help( wchar_t *cmd )
|
||||
{
|
||||
CHECK( cmd, 0 );
|
||||
|
||||
if( wcscmp( cmd, L"for" ) == 0 ||
|
||||
wcscmp( cmd, L"while" ) == 0 ||
|
||||
wcscmp( cmd, L"function" ) == 0 ||
|
||||
wcscmp( cmd, L"if" ) == 0 ||
|
||||
wcscmp( cmd, L"end" ) == 0 ||
|
||||
wcscmp( cmd, L"switch" ) == 0 )
|
||||
return 1;
|
||||
return 0;
|
||||
return ( wcscmp( cmd, L"for" ) == 0 ||
|
||||
wcscmp( cmd, L"while" ) == 0 ||
|
||||
wcscmp( cmd, L"function" ) == 0 ||
|
||||
wcscmp( cmd, L"if" ) == 0 ||
|
||||
wcscmp( cmd, L"end" ) == 0 ||
|
||||
wcscmp( cmd, L"switch" ) == 0 );
|
||||
}
|
||||
|
||||
|
||||
@@ -3102,8 +3224,8 @@ int builtin_run( wchar_t **argv )
|
||||
{
|
||||
int (*cmd)(wchar_t **argv)=0;
|
||||
|
||||
CHECK( argv, 1 );
|
||||
CHECK( argv[0], 1 );
|
||||
CHECK( argv, STATUS_BUILTIN_ERROR );
|
||||
CHECK( argv[0], STATUS_BUILTIN_ERROR );
|
||||
|
||||
cmd = (int (*)(wchar_t **))hash_get( &builtin, argv[0] );
|
||||
|
||||
@@ -3112,7 +3234,7 @@ int builtin_run( wchar_t **argv )
|
||||
if( argv[2] == 0 && (parser_is_help( argv[1], 0 ) ) )
|
||||
{
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
return STATUS_BUILTIN_OK;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3128,7 +3250,7 @@ int builtin_run( wchar_t **argv )
|
||||
{
|
||||
debug( 0, _( L"Unknown builtin '%ls'" ), argv[0] );
|
||||
}
|
||||
return 1;
|
||||
return STATUS_BUILTIN_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
10
builtin.h
10
builtin.h
@@ -35,12 +35,12 @@ enum
|
||||
/**
|
||||
Error message on multiple scope levels for variables
|
||||
*/
|
||||
#define BUILTIN_ERR_GLOCAL _( L"%ls: Variable scope can only be one of universal, global and local\n%ls\n" )
|
||||
#define BUILTIN_ERR_GLOCAL _( L"%ls: Variable scope can only be one of universal, global and local\n" )
|
||||
|
||||
/**
|
||||
Error message for specifying both export and unexport to set/read
|
||||
*/
|
||||
#define BUILTIN_ERR_EXPUNEXP _( L"%ls: Variable can't be both exported and unexported\n%ls\n" )
|
||||
#define BUILTIN_ERR_EXPUNEXP _( L"%ls: Variable can't be both exported and unexported\n" )
|
||||
|
||||
/**
|
||||
Error message for unknown switch
|
||||
@@ -164,12 +164,10 @@ const wchar_t *builtin_complete_get_temporary_buffer();
|
||||
|
||||
|
||||
/**
|
||||
Return the help text for the specified builtin command. Use
|
||||
non-wide characters since wide characters have some issues with
|
||||
string formating escape sequences sometimes.
|
||||
Return the help text for the specified builtin command.
|
||||
|
||||
\param cmd The command for which to obtain help text
|
||||
*/
|
||||
char *builtin_help_get( const wchar_t *cmd );
|
||||
wchar_t *builtin_help_get( const wchar_t *cmd );
|
||||
|
||||
#endif
|
||||
|
||||
@@ -146,7 +146,6 @@ static void write_part( const wchar_t *begin,
|
||||
|
||||
if( tokenize )
|
||||
{
|
||||
|
||||
buff = wcsndup( begin, end-begin );
|
||||
// fwprintf( stderr, L"Subshell: %ls, end char %lc\n", buff, *end );
|
||||
sb_init( &out );
|
||||
@@ -159,20 +158,21 @@ static void write_part( const wchar_t *begin,
|
||||
(tok_get_pos( &tok)+wcslen(tok_last( &tok)) >= pos) )
|
||||
break;
|
||||
|
||||
// fwprintf( stderr, L"Next token %ls\n", tok_last( &tok ) );
|
||||
|
||||
switch( tok_last_type( &tok ) )
|
||||
{
|
||||
case TOK_STRING:
|
||||
sb_append2( &out, tok_last( &tok), L"\n", (void *)0 );
|
||||
{
|
||||
wchar_t *tmp = unescape( tok_last( &tok ), UNESCAPE_INCOMPLETE );
|
||||
sb_append2( &out, tmp, L"\n", (void *)0 );
|
||||
free( tmp );
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if( out.buff )
|
||||
sb_append( sb_out,
|
||||
(wchar_t *)out.buff );
|
||||
|
||||
sb_append( sb_out,
|
||||
(wchar_t *)out.buff );
|
||||
|
||||
free( buff );
|
||||
tok_destroy( &tok );
|
||||
@@ -180,12 +180,24 @@ static void write_part( const wchar_t *begin,
|
||||
}
|
||||
else
|
||||
{
|
||||
wchar_t *buff, *esc;
|
||||
|
||||
if( cut_at_cursor )
|
||||
{
|
||||
end = begin+pos;
|
||||
}
|
||||
sb_append_substring( sb_out, begin, end-begin );
|
||||
sb_append( sb_out, L"\n" );
|
||||
|
||||
buff = wcsndup( begin, end-begin );
|
||||
esc = unescape( buff, UNESCAPE_INCOMPLETE );
|
||||
|
||||
// debug( 0, L"woot2 %ls -> %ls", buff, esc );
|
||||
|
||||
sb_append( sb_out, esc );
|
||||
sb_append( sb_out, L"\n" );
|
||||
|
||||
free( esc );
|
||||
free( buff );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -369,7 +381,7 @@ static int builtin_commandline( wchar_t **argv )
|
||||
return 0;
|
||||
|
||||
case L'?':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
builtin_unknown_option( argv[0], argv[woptind-1] );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,6 @@ static void builtin_complete_add2( const wchar_t *cmd,
|
||||
array_list_t *gnu_opt,
|
||||
array_list_t *old_opt,
|
||||
int result_mode,
|
||||
int authorative,
|
||||
const wchar_t *condition,
|
||||
const wchar_t *comp,
|
||||
const wchar_t *desc )
|
||||
@@ -64,7 +63,6 @@ static void builtin_complete_add2( const wchar_t *cmd,
|
||||
0,
|
||||
0,
|
||||
result_mode,
|
||||
authorative,
|
||||
condition,
|
||||
comp,
|
||||
desc );
|
||||
@@ -78,7 +76,6 @@ static void builtin_complete_add2( const wchar_t *cmd,
|
||||
(wchar_t *)al_get(gnu_opt, i ),
|
||||
0,
|
||||
result_mode,
|
||||
authorative,
|
||||
condition,
|
||||
comp,
|
||||
desc );
|
||||
@@ -92,7 +89,6 @@ static void builtin_complete_add2( const wchar_t *cmd,
|
||||
(wchar_t *)al_get(old_opt, i ),
|
||||
1,
|
||||
result_mode,
|
||||
authorative,
|
||||
condition,
|
||||
comp,
|
||||
desc );
|
||||
@@ -106,7 +102,6 @@ static void builtin_complete_add2( const wchar_t *cmd,
|
||||
0,
|
||||
0,
|
||||
result_mode,
|
||||
authorative,
|
||||
condition,
|
||||
comp,
|
||||
desc );
|
||||
@@ -137,10 +132,17 @@ static void builtin_complete_add( array_list_t *cmd,
|
||||
gnu_opt,
|
||||
old_opt,
|
||||
result_mode,
|
||||
authorative,
|
||||
condition,
|
||||
comp,
|
||||
desc );
|
||||
|
||||
if( authorative != -1 )
|
||||
{
|
||||
complete_set_authorative( al_get( cmd, i ),
|
||||
COMMAND,
|
||||
authorative );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for( i=0; i<al_get_count( path ); i++ )
|
||||
@@ -151,12 +153,18 @@ static void builtin_complete_add( array_list_t *cmd,
|
||||
gnu_opt,
|
||||
old_opt,
|
||||
result_mode,
|
||||
authorative,
|
||||
condition,
|
||||
comp,
|
||||
desc );
|
||||
}
|
||||
|
||||
|
||||
if( authorative != -1 )
|
||||
{
|
||||
complete_set_authorative( al_get( path, i ),
|
||||
PATH,
|
||||
authorative );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -278,7 +286,7 @@ static int builtin_complete( wchar_t **argv )
|
||||
int argc=0;
|
||||
int result_mode=SHARED;
|
||||
int remove = 0;
|
||||
int authorative = 1;
|
||||
int authorative = -1;
|
||||
|
||||
string_buffer_t short_opt;
|
||||
array_list_t gnu_opt, old_opt;
|
||||
@@ -359,6 +367,10 @@ static int builtin_complete( wchar_t **argv )
|
||||
L"unauthorative", no_argument, 0, 'u'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"authorative", no_argument, 0, 'A'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"condition", required_argument, 0, 'n'
|
||||
}
|
||||
@@ -381,7 +393,7 @@ static int builtin_complete( wchar_t **argv )
|
||||
|
||||
int opt = wgetopt_long( argc,
|
||||
argv,
|
||||
L"a:c:p:s:l:o:d:frxeun:C::h",
|
||||
L"a:c:p:s:l:o:d:frxeuAn:C::h",
|
||||
long_options,
|
||||
&opt_index );
|
||||
if( opt == -1 )
|
||||
@@ -396,9 +408,6 @@ static int builtin_complete( wchar_t **argv )
|
||||
BUILTIN_ERR_UNKNOWN,
|
||||
argv[0],
|
||||
long_options[opt_index].name );
|
||||
sb_append( sb_err,
|
||||
parser_current_line() );
|
||||
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
|
||||
@@ -441,6 +450,10 @@ static int builtin_complete( wchar_t **argv )
|
||||
authorative=0;
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
authorative=1;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
sb_append( &short_opt, woptarg );
|
||||
break;
|
||||
@@ -474,10 +487,7 @@ static int builtin_complete( wchar_t **argv )
|
||||
return 0;
|
||||
|
||||
case '?':
|
||||
sb_append( sb_err,
|
||||
parser_current_line() );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
builtin_unknown_option( argv[0], argv[woptind-1] );
|
||||
res = 1;
|
||||
break;
|
||||
|
||||
@@ -561,8 +571,6 @@ static int builtin_complete( wchar_t **argv )
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: Too many arguments\n" ),
|
||||
argv[0] );
|
||||
sb_append( sb_err,
|
||||
parser_current_line() );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
res = 1;
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
/** \file builtin_help.c
|
||||
|
||||
Functions for printing usage information of builtin commands. This
|
||||
file is automatically generated from the file builtin_help.hdr and
|
||||
various help files in the doc_src directory.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "common.h"
|
||||
#include "halloc_util.h"
|
||||
|
||||
/**
|
||||
Hashtable storing the help text
|
||||
*/
|
||||
static hash_table_t tbl;
|
||||
|
||||
static void builtin_help_init();
|
||||
|
||||
char *builtin_help_get( const wchar_t *cmd )
|
||||
{
|
||||
builtin_help_init();
|
||||
|
||||
return (char *)hash_get( &tbl, (void *)cmd );
|
||||
}
|
||||
|
||||
/**
|
||||
Initialize help hash table. Don't invoke it manually,
|
||||
it is called by builtin_help_get automatically.
|
||||
*/
|
||||
static void builtin_help_init()
|
||||
{
|
||||
static int is_help_init = 0;
|
||||
if( is_help_init )
|
||||
return;
|
||||
is_help_init=1;
|
||||
halloc_register_function( global_context, (void (*)(void *))&hash_destroy, &tbl );
|
||||
hash_init( &tbl, &hash_wcs_func, &hash_wcs_cmp );
|
||||
@@ -222,8 +222,6 @@ static int builtin_jobs( wchar_t **argv )
|
||||
argv[0],
|
||||
long_options[opt_index].name );
|
||||
|
||||
sb_append( sb_err,
|
||||
parser_current_line() );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
|
||||
@@ -253,8 +251,7 @@ static int builtin_jobs( wchar_t **argv )
|
||||
return 0;
|
||||
|
||||
case '?':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
builtin_unknown_option( argv[0], argv[woptind-1] );
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
@@ -141,7 +141,8 @@ static int my_env_set( const wchar_t *key, array_list_t *val, int scope )
|
||||
{
|
||||
for( i=0; i<al_get_count( val ); i++ )
|
||||
{
|
||||
sb_append( &sb, (wchar_t *)al_get( val, i ) );
|
||||
wchar_t *next =(wchar_t *)al_get( val, i );
|
||||
sb_append( &sb, next?next:L"" );
|
||||
if( i<al_get_count( val )-1 )
|
||||
{
|
||||
sb_append( &sb, ARRAY_SEP_STR );
|
||||
@@ -232,9 +233,14 @@ static int parse_index( array_list_t *indexes,
|
||||
while (*src != L']')
|
||||
{
|
||||
wchar_t *end;
|
||||
long l_ind = wcstol(src, &end, 10);
|
||||
|
||||
if (end == src)
|
||||
long l_ind;
|
||||
|
||||
errno = 0;
|
||||
|
||||
l_ind = wcstol(src, &end, 10);
|
||||
|
||||
if( end==src || errno )
|
||||
{
|
||||
sb_printf(sb_err, _(L"%ls: Invalid index starting at '%ls'\n"), L"set", src);
|
||||
return 0;
|
||||
@@ -274,11 +280,11 @@ static int update_values( array_list_t *list,
|
||||
{
|
||||
/*
|
||||
The '- 1' below is because the indices in fish are
|
||||
one-based, but the array_lsit_t uses zero-based indices
|
||||
one-based, but the array_list_t uses zero-based indices
|
||||
*/
|
||||
long ind = al_get_long(indexes, i) - 1;
|
||||
void *new = (void *) al_get(values, i);
|
||||
if( ind <= 0 )
|
||||
if( ind < 0 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@@ -534,7 +540,7 @@ static int builtin_set( wchar_t **argv )
|
||||
return 0;
|
||||
|
||||
case '?':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
builtin_unknown_option( argv[0], argv[woptind-1] );
|
||||
return 1;
|
||||
|
||||
default:
|
||||
@@ -554,9 +560,8 @@ static int builtin_set( wchar_t **argv )
|
||||
if( query && (erase || list || global || local || universal || export || unexport ) )
|
||||
{
|
||||
sb_printf(sb_err,
|
||||
BUILTIN_ERR_COMBO2,
|
||||
argv[0],
|
||||
parser_current_line() );
|
||||
BUILTIN_ERR_COMBO,
|
||||
argv[0] );
|
||||
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
@@ -567,9 +572,8 @@ static int builtin_set( wchar_t **argv )
|
||||
if( erase && list )
|
||||
{
|
||||
sb_printf(sb_err,
|
||||
BUILTIN_ERR_COMBO2,
|
||||
argv[0],
|
||||
parser_current_line() );
|
||||
BUILTIN_ERR_COMBO,
|
||||
argv[0] );
|
||||
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
@@ -582,8 +586,7 @@ static int builtin_set( wchar_t **argv )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
BUILTIN_ERR_GLOCAL,
|
||||
argv[0],
|
||||
parser_current_line() );
|
||||
argv[0] );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
}
|
||||
@@ -595,8 +598,7 @@ static int builtin_set( wchar_t **argv )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
BUILTIN_ERR_EXPUNEXP,
|
||||
argv[0],
|
||||
parser_current_line() );
|
||||
argv[0] );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
}
|
||||
@@ -615,10 +617,55 @@ static int builtin_set( wchar_t **argv )
|
||||
int i;
|
||||
for( i=woptind; i<argc; i++ )
|
||||
{
|
||||
if( !env_exist( argv[i], scope ) )
|
||||
wchar_t *arg = argv[i];
|
||||
int slice=0;
|
||||
|
||||
if( !(dest = wcsdup(arg)))
|
||||
{
|
||||
retcode++;
|
||||
DIE_MEM();
|
||||
}
|
||||
|
||||
if( wcschr( dest, L'[' ) )
|
||||
{
|
||||
slice = 1;
|
||||
*wcschr( dest, L'[' )=0;
|
||||
}
|
||||
|
||||
if( slice )
|
||||
{
|
||||
array_list_t indexes;
|
||||
array_list_t result;
|
||||
int j;
|
||||
|
||||
al_init( &result );
|
||||
al_init( &indexes );
|
||||
|
||||
tokenize_variable_array( env_get( dest ), &result );
|
||||
|
||||
if( !parse_index( &indexes, arg, dest, al_get_count( &result ) ) )
|
||||
{
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
retcode = 1;
|
||||
break;
|
||||
}
|
||||
for( j=0; j<al_get_count( &indexes ); j++ )
|
||||
{
|
||||
long idx = al_get_long( &indexes, j );
|
||||
if( idx < 1 || idx > al_get_count( &result ) )
|
||||
{
|
||||
retcode++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !env_exist( arg, scope ) )
|
||||
{
|
||||
retcode++;
|
||||
}
|
||||
}
|
||||
|
||||
free( dest );
|
||||
|
||||
}
|
||||
return retcode;
|
||||
@@ -641,8 +688,7 @@ static int builtin_set( wchar_t **argv )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_(L"%ls: Erase needs a variable name\n%ls\n"),
|
||||
argv[0],
|
||||
parser_current_line() );
|
||||
argv[0] );
|
||||
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
retcode = 1;
|
||||
@@ -799,9 +845,8 @@ static int builtin_set( wchar_t **argv )
|
||||
if( woptind != argc )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_(L"%ls: Values cannot be specfied with erase\n%ls\n"),
|
||||
argv[0],
|
||||
parser_current_line() );
|
||||
_(L"%ls: Values cannot be specfied with erase\n"),
|
||||
argv[0] );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
retcode=1;
|
||||
}
|
||||
|
||||
@@ -123,7 +123,9 @@ static int get_multiplier( int what )
|
||||
}
|
||||
|
||||
/**
|
||||
Return the value for the specified resource limit
|
||||
Return the value for the specified resource limit. This function
|
||||
does _not_ multiply the limit value by the multiplier constant used
|
||||
by the commandline ulimit.
|
||||
*/
|
||||
static rlim_t get( int resource, int hard )
|
||||
{
|
||||
@@ -144,7 +146,7 @@ static void print( int resource, int hard )
|
||||
if( l == RLIM_INFINITY )
|
||||
sb_append( sb_out, L"unlimited\n" );
|
||||
else
|
||||
sb_printf( sb_out, L"%d\n", l );
|
||||
sb_printf( sb_out, L"%d\n", l / get_multiplier( resource ) );
|
||||
|
||||
}
|
||||
|
||||
@@ -178,10 +180,15 @@ static void print_all( int hard )
|
||||
resource_arr[i].switch_char);
|
||||
|
||||
if( l == RLIM_INFINITY )
|
||||
{
|
||||
sb_append( sb_out, L"unlimited\n" );
|
||||
}
|
||||
else
|
||||
sb_printf( sb_out, L"%d\n", l );
|
||||
{
|
||||
sb_printf( sb_out, L"%d\n", l/get_multiplier(resource_arr[i].resource) );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -202,14 +209,14 @@ static const wchar_t *get_desc( int what )
|
||||
}
|
||||
|
||||
/**
|
||||
Set the new value of the specified resource limit
|
||||
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 )
|
||||
{
|
||||
struct rlimit ls;
|
||||
getrlimit( resource, &ls );
|
||||
if( value != RLIM_INFINITY )
|
||||
value *= get_multiplier( resource );
|
||||
|
||||
if( hard )
|
||||
{
|
||||
@@ -241,22 +248,6 @@ static int set( int resource, int hard, int soft, rlim_t value )
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Set all resource limits
|
||||
*/
|
||||
static int set_all( int hard, int soft, rlim_t value )
|
||||
{
|
||||
int i;
|
||||
int res=0;
|
||||
|
||||
for( i=0; resource_arr[i].desc; i++ )
|
||||
{
|
||||
if( set( resource_arr[i].resource, hard, soft, value ) )
|
||||
res = 1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
The ulimit builtin, used for setting resource limits. Defined in
|
||||
builtin_ulimit.c.
|
||||
@@ -315,7 +306,7 @@ static int builtin_ulimit( wchar_t ** argv )
|
||||
}
|
||||
,
|
||||
{
|
||||
L"pipe-size", no_argument, 0, 'p'
|
||||
L"stack-size", no_argument, 0, 's'
|
||||
}
|
||||
,
|
||||
{
|
||||
@@ -345,7 +336,7 @@ static int builtin_ulimit( wchar_t ** argv )
|
||||
|
||||
int opt = wgetopt_long( argc,
|
||||
argv,
|
||||
L"aHScdflmnptuvh",
|
||||
L"aHScdflmnstuvh",
|
||||
long_options,
|
||||
&opt_index );
|
||||
if( opt == -1 )
|
||||
@@ -428,28 +419,41 @@ static int builtin_ulimit( wchar_t ** argv )
|
||||
return 0;
|
||||
|
||||
case L'?':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
builtin_unknown_option( argv[0], argv[woptind-1] );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if( report_all )
|
||||
{
|
||||
if( argc - woptind == 0 )
|
||||
{
|
||||
print_all( hard );
|
||||
}
|
||||
else
|
||||
{
|
||||
sb_append2( sb_err,
|
||||
argv[0],
|
||||
L": Too many arguments\n",
|
||||
(void *)0 );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch( argc - woptind )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
/*
|
||||
Show current limit value
|
||||
*/
|
||||
if( report_all )
|
||||
{
|
||||
print_all( hard );
|
||||
}
|
||||
else
|
||||
{
|
||||
print( what, hard );
|
||||
}
|
||||
|
||||
print( what, hard );
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
case 1:
|
||||
{
|
||||
/*
|
||||
@@ -457,7 +461,7 @@ static int builtin_ulimit( wchar_t ** argv )
|
||||
*/
|
||||
rlim_t new_limit;
|
||||
wchar_t *end;
|
||||
|
||||
|
||||
/*
|
||||
Set both hard and soft limits if nothing else was specified
|
||||
*/
|
||||
@@ -466,7 +470,6 @@ static int builtin_ulimit( wchar_t ** argv )
|
||||
hard=soft=1;
|
||||
}
|
||||
|
||||
|
||||
if( wcscasecmp( argv[woptind], L"unlimited" )==0)
|
||||
{
|
||||
new_limit = RLIM_INFINITY;
|
||||
@@ -492,30 +495,22 @@ static int builtin_ulimit( wchar_t ** argv )
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
}
|
||||
new_limit *= get_multiplier( what );
|
||||
}
|
||||
|
||||
if( report_all )
|
||||
{
|
||||
return set_all( hard, soft, new_limit );
|
||||
}
|
||||
else
|
||||
{
|
||||
return set( what, hard, soft, new_limit );
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
return set( what, hard, soft, new_limit );
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
sb_append2( sb_err,
|
||||
argv[0],
|
||||
L": Too many arguments\n",
|
||||
(void *)0 );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
107
common.c
107
common.c
@@ -44,6 +44,10 @@ parts of fish.
|
||||
#include <sys/time.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef HAVE_EXECINFO_H
|
||||
#include <execinfo.h>
|
||||
#endif
|
||||
|
||||
#ifndef HOST_NAME_MAX
|
||||
/**
|
||||
Maximum length of hostname return. It is ok if this is too short,
|
||||
@@ -110,6 +114,28 @@ static struct winsize termsize;
|
||||
*/
|
||||
static string_buffer_t *setlocale_buff=0;
|
||||
|
||||
|
||||
void show_stackframe()
|
||||
{
|
||||
void *trace[32];
|
||||
char **messages = (char **)NULL;
|
||||
int i, trace_size = 0;
|
||||
|
||||
trace_size = backtrace(trace, 32);
|
||||
messages = backtrace_symbols(trace, trace_size);
|
||||
|
||||
if( messages )
|
||||
{
|
||||
debug( 0, L"Backtrace:" );
|
||||
for( i=0; i<trace_size; i++ )
|
||||
{
|
||||
fwprintf( stderr, L"%s\n", messages[i]);
|
||||
}
|
||||
free( messages );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
wchar_t **list_to_char_arr( array_list_t *l )
|
||||
{
|
||||
wchar_t ** res = malloc( sizeof(wchar_t *)*(al_get_count( l )+1) );
|
||||
@@ -157,8 +183,6 @@ int fgetws2( wchar_t **b, int *len, FILE *f )
|
||||
|
||||
if( errno == EILSEQ )
|
||||
{
|
||||
|
||||
getc( f );
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -548,14 +572,17 @@ int read_blocked(int fd, void *buf, size_t count)
|
||||
void debug( int level, const wchar_t *msg, ... )
|
||||
{
|
||||
va_list va;
|
||||
|
||||
string_buffer_t sb;
|
||||
string_buffer_t sb2;
|
||||
|
||||
int errno_old = errno;
|
||||
|
||||
CHECK( msg, );
|
||||
|
||||
if( level > debug_level )
|
||||
return;
|
||||
|
||||
CHECK( msg, );
|
||||
|
||||
sb_init( &sb );
|
||||
sb_init( &sb2 );
|
||||
|
||||
@@ -570,6 +597,8 @@ void debug( int level, const wchar_t *msg, ... )
|
||||
|
||||
sb_destroy( &sb );
|
||||
sb_destroy( &sb2 );
|
||||
|
||||
errno = errno_old;
|
||||
}
|
||||
|
||||
void write_screen( const wchar_t *msg, string_buffer_t *buff )
|
||||
@@ -673,7 +702,7 @@ wchar_t *escape( const wchar_t *in,
|
||||
if( !in )
|
||||
{
|
||||
debug( 0, L"%s called with null input", __func__ );
|
||||
exit(1);
|
||||
FATAL_EXIT();
|
||||
}
|
||||
|
||||
out = malloc( sizeof(wchar_t)*(wcslen(in)*4 + 1));
|
||||
@@ -786,7 +815,7 @@ wchar_t *escape( const wchar_t *in,
|
||||
}
|
||||
|
||||
|
||||
wchar_t *unescape( const wchar_t * orig, int unescape_special )
|
||||
wchar_t *unescape( const wchar_t * orig, int flags )
|
||||
{
|
||||
|
||||
int mode = 0;
|
||||
@@ -795,7 +824,9 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special )
|
||||
int bracket_count=0;
|
||||
wchar_t prev=0;
|
||||
wchar_t *in;
|
||||
|
||||
int unescape_special = flags & UNESCAPE_SPECIAL;
|
||||
int allow_incomplete = flags & UNESCAPE_INCOMPLETE;
|
||||
|
||||
CHECK( orig, 0 );
|
||||
|
||||
len = wcslen( orig );
|
||||
@@ -828,10 +859,13 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special )
|
||||
*/
|
||||
case L'\0':
|
||||
{
|
||||
free(in);
|
||||
return 0;
|
||||
if( !allow_incomplete )
|
||||
{
|
||||
free(in);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Numeric escape sequences. No prefix means
|
||||
octal escape, otherwise hexadecimal.
|
||||
@@ -1148,6 +1182,8 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special )
|
||||
mode = 1;
|
||||
if( unescape_special )
|
||||
in[out_pos] = INTERNAL_SEPARATOR;
|
||||
else
|
||||
out_pos--;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1156,6 +1192,8 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special )
|
||||
mode = 2;
|
||||
if( unescape_special )
|
||||
in[out_pos] = INTERNAL_SEPARATOR;
|
||||
else
|
||||
out_pos--;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1188,8 +1226,13 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special )
|
||||
|
||||
case 0:
|
||||
{
|
||||
free(in);
|
||||
return 0;
|
||||
if( !allow_incomplete )
|
||||
{
|
||||
free(in);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
out_pos--;
|
||||
}
|
||||
|
||||
default:
|
||||
@@ -1204,6 +1247,8 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special )
|
||||
{
|
||||
if( unescape_special )
|
||||
in[out_pos] = INTERNAL_SEPARATOR;
|
||||
else
|
||||
out_pos--;
|
||||
mode = 0;
|
||||
}
|
||||
else
|
||||
@@ -1226,6 +1271,8 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special )
|
||||
mode = 0;
|
||||
if( unescape_special )
|
||||
in[out_pos] = INTERNAL_SEPARATOR;
|
||||
else
|
||||
out_pos--;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1235,8 +1282,13 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special )
|
||||
{
|
||||
case L'\0':
|
||||
{
|
||||
free(in);
|
||||
return 0;
|
||||
if( !allow_incomplete )
|
||||
{
|
||||
free(in);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
out_pos--;
|
||||
}
|
||||
|
||||
case '\\':
|
||||
@@ -1282,6 +1334,13 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !allow_incomplete && mode )
|
||||
{
|
||||
free( in );
|
||||
return 0;
|
||||
}
|
||||
|
||||
in[out_pos]=L'\0';
|
||||
return in;
|
||||
}
|
||||
@@ -1542,6 +1601,7 @@ void tokenize_variable_array( const wchar_t *val, array_list_t *out )
|
||||
{
|
||||
wchar_t *cpy = wcsdup( val );
|
||||
wchar_t *pos, *start;
|
||||
wchar_t *next;
|
||||
|
||||
if( !cpy )
|
||||
{
|
||||
@@ -1552,12 +1612,19 @@ void tokenize_variable_array( const wchar_t *val, array_list_t *out )
|
||||
{
|
||||
if( *pos == ARRAY_SEP )
|
||||
{
|
||||
|
||||
*pos=0;
|
||||
al_push( out, start==cpy?cpy:wcsdup(start) );
|
||||
next = start==cpy?cpy:wcsdup(start);
|
||||
if( !next )
|
||||
DIE_MEM();
|
||||
al_push( out, next );
|
||||
start=pos+1;
|
||||
}
|
||||
}
|
||||
al_push( out, start==cpy?cpy:wcsdup(start) );
|
||||
next = start==cpy?cpy:wcsdup(start);
|
||||
if( !next )
|
||||
DIE_MEM();
|
||||
al_push( out, next );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1601,3 +1668,11 @@ int create_directory( wchar_t *d )
|
||||
return ok?0:-1;
|
||||
}
|
||||
|
||||
void bugreport()
|
||||
{
|
||||
debug( 1,
|
||||
_( L"This is a bug. "
|
||||
L"If you can reproduce it, please send a bug report to %s." ),
|
||||
PACKAGE_BUGREPORT );
|
||||
}
|
||||
|
||||
|
||||
69
common.h
69
common.h
@@ -40,6 +40,10 @@
|
||||
*/
|
||||
#define BYTE_MAX 0xffu
|
||||
|
||||
#define UNESCAPE_SPECIAL 1
|
||||
#define UNESCAPE_INCOMPLETE 2
|
||||
|
||||
|
||||
/**
|
||||
Save the shell mode on startup so we can restore them on exit
|
||||
*/
|
||||
@@ -77,16 +81,27 @@ extern wchar_t *program_name;
|
||||
#define CHECK( arg, retval ) \
|
||||
if( !(arg) ) \
|
||||
{ \
|
||||
debug( 1, \
|
||||
_( L"function %s called with null value for argument %s. " \
|
||||
L"This is a bug. " \
|
||||
L"If you can reproduce it, please send a bug report to %s." ), \
|
||||
debug( 0, \
|
||||
_( L"function %s called with null value for argument %s. " ), \
|
||||
__func__, \
|
||||
#arg, \
|
||||
PACKAGE_BUGREPORT ); \
|
||||
#arg ); \
|
||||
bugreport(); \
|
||||
show_stackframe(); \
|
||||
return retval; \
|
||||
}
|
||||
|
||||
/**
|
||||
Pause for input, then exit the program. If supported, print a backtrace first.
|
||||
*/
|
||||
#define FATAL_EXIT() \
|
||||
{ \
|
||||
char c; \
|
||||
show_stackframe(); \
|
||||
read( 0, &c, 1 ); \
|
||||
exit( 1 ); \
|
||||
} \
|
||||
|
||||
|
||||
/**
|
||||
Exit program at once, leaving an error message about running out of memory.
|
||||
*/
|
||||
@@ -96,33 +111,22 @@ extern wchar_t *program_name;
|
||||
L"fish: Out of memory on line %d of file %s, shutting down fish\n", \
|
||||
__LINE__, \
|
||||
__FILE__ ); \
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
/**
|
||||
Cause fish to crash. This should only be used for debugging. If
|
||||
this function is ever called in shipped code, this is a bug.
|
||||
*/
|
||||
#define CRASH() \
|
||||
{ \
|
||||
int *n = 0; \
|
||||
*n = 1; \
|
||||
FATAL_EXIT(); \
|
||||
}
|
||||
|
||||
/**
|
||||
Check if signals are blocked. If so, print an error message and
|
||||
return from the function performing this check.
|
||||
*/
|
||||
#define CHECK_BLOCK( retval ) \
|
||||
#define CHECK_BLOCK( retval ) \
|
||||
if( signal_is_blocked() ) \
|
||||
{ \
|
||||
debug( 0, \
|
||||
L"function %s called while blocking signals. " \
|
||||
L"This is a bug. " \
|
||||
L"If you can reproduce it, please send a bug report to %s.", \
|
||||
__func__, \
|
||||
PACKAGE_BUGREPORT ); \
|
||||
return retval; \
|
||||
_( L"function %s called while blocking signals. " ), \
|
||||
__func__); \
|
||||
bugreport(); \
|
||||
show_stackframe(); \
|
||||
return retval; \
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -136,13 +140,15 @@ extern wchar_t *program_name;
|
||||
*/
|
||||
#define N_(wstr) wstr
|
||||
|
||||
/*
|
||||
Print a stack trace to stderr
|
||||
*/
|
||||
void show_stackframe();
|
||||
|
||||
/**
|
||||
Take an array_list_t containing wide strings and converts them to a
|
||||
single null-terminated wchar_t **. The array is allocated using
|
||||
halloc, and uses the \c context parameter as context. If \c context
|
||||
is not noll, all elements of the \c array_list_t are also
|
||||
registered to \c context using \c halloc_register().
|
||||
malloc, and needs to be fred's by the caller.
|
||||
*/
|
||||
wchar_t **list_to_char_arr( array_list_t *l );
|
||||
|
||||
@@ -309,6 +315,10 @@ int read_blocked(int fd, void *buf, 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.
|
||||
@@ -405,5 +415,10 @@ void tokenize_variable_array( const wchar_t *val, array_list_t *out );
|
||||
*/
|
||||
int create_directory( wchar_t *d );
|
||||
|
||||
/**
|
||||
Print a short message about how to file a bug report to stderr
|
||||
*/
|
||||
void bugreport();
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
930
complete.c
930
complete.c
File diff suppressed because it is too large
Load Diff
13
complete.h
13
complete.h
@@ -70,7 +70,8 @@
|
||||
|
||||
Add a completion.
|
||||
|
||||
Values are copied and should be freed by the caller.
|
||||
All supplied values are copied, they should be freed by or otherwise
|
||||
disposed by the caller.
|
||||
|
||||
Examples:
|
||||
|
||||
@@ -104,7 +105,6 @@
|
||||
file completion is not performed.
|
||||
\param comp A space separated list of completions which may contain subshells.
|
||||
\param desc A description of the completion.
|
||||
\param authorative Whether there list of completions 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.
|
||||
\param condition a command to be run to check it this completion should be used. If \c condition is empty, the completion is always used.
|
||||
|
||||
*/
|
||||
@@ -114,10 +114,17 @@ void complete_add( const wchar_t *cmd,
|
||||
const wchar_t *long_opt,
|
||||
int long_mode,
|
||||
int result_mode,
|
||||
int authorative,
|
||||
const wchar_t *condition,
|
||||
const wchar_t *comp,
|
||||
const wchar_t *desc );
|
||||
/**
|
||||
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_authorative( const wchar_t *cmd,
|
||||
int cmd_type,
|
||||
int authorative );
|
||||
|
||||
/**
|
||||
Remove a previously defined completion
|
||||
|
||||
117
configure.ac
117
configure.ac
@@ -9,7 +9,7 @@
|
||||
# configure the build process.
|
||||
#
|
||||
|
||||
AC_INIT(fish,1.22.1,fish-users@lists.sf.net)
|
||||
AC_INIT(fish,1.22.3,fish-users@lists.sf.net)
|
||||
|
||||
|
||||
#
|
||||
@@ -62,7 +62,7 @@ if test ! -f ./config.h.in -o config.h.in -ot configure.ac; then
|
||||
[cannot find the autoheader program in your path.
|
||||
This program needs to be run whenever the configure.ac file is modified.
|
||||
Please install it and try again.]
|
||||
)
|
||||
)
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
@@ -86,7 +86,7 @@ for i in /usr/pkg /sw /opt /opt/local; do
|
||||
CPPFLAGS="$CPPFLAGS -I$i/include/"
|
||||
CFLAGS="$CFLAGS -I$i/include/"
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for $i/lib library directory])
|
||||
@@ -94,7 +94,7 @@ for i in /usr/pkg /sw /opt /opt/local; do
|
||||
AC_MSG_RESULT(yes)
|
||||
LDFLAGS="$LDFLAGS -L$i/lib/ -R$i/lib/"
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for $i/bin command directory])
|
||||
@@ -102,7 +102,7 @@ for i in /usr/pkg /sw /opt /opt/local; do
|
||||
AC_MSG_RESULT(yes)
|
||||
optbindirs="$optbindirs $i/bin"
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
done
|
||||
@@ -185,13 +185,32 @@ AC_ARG_WITH(
|
||||
)
|
||||
|
||||
if [[ "$xsel" = "with_xsel" ]]; then
|
||||
AC_SUBST( XSEL,[xsel-0.9.6/xsel])
|
||||
AC_SUBST( XSEL_MAN,[xsel.1x])
|
||||
AC_SUBST( XSEL_MAN_PATH,[xsel-0.9.6/xsel.1x])
|
||||
AC_SUBST( XSEL,[xsel-0.9.6/xsel])
|
||||
AC_SUBST( XSEL_MAN,[xsel.1x])
|
||||
AC_SUBST( XSEL_MAN_PATH,[xsel-0.9.6/xsel.1x])
|
||||
else
|
||||
AC_SUBST( XSEL,[ ])
|
||||
AC_SUBST( XSEL_MAN,[ ])
|
||||
AC_SUBST( XSEL_MAN_PATH,[ ])
|
||||
AC_SUBST( XSEL,[ ])
|
||||
AC_SUBST( XSEL_MAN,[ ])
|
||||
AC_SUBST( XSEL_MAN_PATH,[ ])
|
||||
fi
|
||||
|
||||
|
||||
#
|
||||
# Optionally drop gettext support
|
||||
#
|
||||
|
||||
AC_ARG_WITH(
|
||||
gettext,
|
||||
AC_HELP_STRING(
|
||||
[--without-gettext],
|
||||
[do not translate messages, even if gettext is available]
|
||||
),
|
||||
[local_gettext=$withval],
|
||||
[local_gettext=yes]
|
||||
)
|
||||
|
||||
if test x$local_gettext != xno; then
|
||||
AC_DEFINE([USE_GETTEXT],[1],[Perform string translations with gettext])
|
||||
fi
|
||||
|
||||
|
||||
@@ -226,6 +245,14 @@ AC_CACHE_VAL(
|
||||
]
|
||||
)
|
||||
|
||||
#
|
||||
# Try to enale large file support. This will make sure that on systems
|
||||
# where off_t can be either 32 or 64 bit, the latter size is used. On
|
||||
# other systems, this should do nothing. (Hopefully)
|
||||
#
|
||||
|
||||
CFLAGS="$CFLAGS -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64"
|
||||
|
||||
AC_MSG_RESULT($local_cv_has__std_c99)
|
||||
case x$local_cv_has__std_c99 in
|
||||
xno)
|
||||
@@ -260,6 +287,12 @@ if test "$CC" = gcc; then
|
||||
|
||||
CFLAGS="$CFLAGS -Wall"
|
||||
|
||||
#
|
||||
# This is needed in order to get the really cool backtraces
|
||||
#
|
||||
|
||||
LDFLAGS="$LDFLAGS -rdynamic"
|
||||
|
||||
fi
|
||||
|
||||
|
||||
@@ -320,7 +353,7 @@ fi
|
||||
AC_CANONICAL_TARGET
|
||||
|
||||
if test $target_cpu = powerpc; then
|
||||
AC_DEFINE([TPUTS_KLUDGE],[1],[Evil kludge to get Power based machines to work])
|
||||
AC_DEFINE([TPUTS_KLUDGE],[1],[Evil kludge to get Power based machines to work])
|
||||
fi
|
||||
|
||||
|
||||
@@ -418,7 +451,10 @@ AC_DEFINE(
|
||||
# Check presense of various libraries
|
||||
#
|
||||
|
||||
AC_SEARCH_LIBS( gettext, intl,,)
|
||||
# Only link with gettext if we are using it
|
||||
if test x$local_gettext != xno; then
|
||||
AC_SEARCH_LIBS( gettext, intl,,)
|
||||
fi
|
||||
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( setupterm, [ncurses curses], , [AC_MSG_ERROR([Could not find a curses implementation, needed to build fish])] )
|
||||
@@ -429,7 +465,7 @@ AC_SEARCH_LIBS( iconv_open, iconv, , [AC_MSG_ERROR([Could not find an iconv impl
|
||||
# Check presense of various header files
|
||||
#
|
||||
|
||||
AC_CHECK_HEADERS([getopt.h termio.h sys/resource.h term.h ncurses/term.h libintl.h ncurses.h curses.h stropts.h siginfo.h sys/select.h sys/ioctl.h sys/termios.h])
|
||||
AC_CHECK_HEADERS([getopt.h termio.h sys/resource.h term.h ncurses/term.h ncurses.h curses.h stropts.h siginfo.h sys/select.h sys/ioctl.h sys/termios.h libintl.h execinfo.h])
|
||||
|
||||
AC_CHECK_HEADER(
|
||||
[regex.h],
|
||||
@@ -438,9 +474,9 @@ AC_CHECK_HEADER(
|
||||
[HAVE_REGEX_H],
|
||||
[1],
|
||||
[Define to 1 if you have the <regex.h> header file.]
|
||||
)],
|
||||
[AC_MSG_ERROR([Could not find the header regex.h, needed to build fish])
|
||||
]
|
||||
)
|
||||
],
|
||||
[AC_MSG_ERROR([Could not find the header regex.h, needed to build fish])]
|
||||
)
|
||||
|
||||
|
||||
@@ -448,7 +484,7 @@ AC_CHECK_HEADER(
|
||||
# On some platforms (Solaris 10) adding -std=c99 in turn requires that
|
||||
# _POSIX_C_SOURCE be defined to 200112L otherwise several
|
||||
# POSIX-specific, non-ISO-C99 types/prototypes are made unavailable
|
||||
# e.g. siginfo_t. Defining _XOPEN_SOURCE to 600 is compatible with
|
||||
# e.g. siginfo_t. Defining _XOPEN_SOURCE to 600 is compatible with
|
||||
# the _POSIX_C_SOURCE value and provides a little assurance that
|
||||
# extension functions' prototypes are available, e.g. killpg().
|
||||
#
|
||||
@@ -570,17 +606,19 @@ fi
|
||||
# Check for presense of various functions used by fish
|
||||
#
|
||||
|
||||
AC_CHECK_FUNCS( gettext wcsdup wcsndup wcslen wcscasecmp wcsncasecmp fwprintf )
|
||||
AC_CHECK_FUNCS( wcsdup wcsndup wcslen wcscasecmp wcsncasecmp fwprintf )
|
||||
AC_CHECK_FUNCS( futimes wcwidth wcswidth wcstok fputwc fgetwc )
|
||||
AC_CHECK_FUNCS( wcstol dcgettext wcslcat wcslcpy lrand48_r killpg)
|
||||
|
||||
AC_CHECK_FUNCS( wcstol wcslcat wcslcpy lrand48_r killpg gettext )
|
||||
AC_CHECK_FUNCS( dcgettext backtrace backtrace_symbols)
|
||||
|
||||
#
|
||||
# The Makefile also needs to know if we have gettext, so it knows if
|
||||
# the translations should be installed.
|
||||
#
|
||||
|
||||
AC_CHECK_FUNC( gettext, AC_SUBST( HAVE_GETTEXT, 1 ), AC_SUBST( HAVE_GETTEXT, 0 ) )
|
||||
if test x$local_gettext != xno; then
|
||||
AC_CHECK_FUNC( gettext, AC_SUBST( HAVE_GETTEXT, 1 ), AC_SUBST( HAVE_GETTEXT, 0 ) )
|
||||
fi
|
||||
|
||||
#
|
||||
# Here follows a list of small programs used to test for various
|
||||
@@ -682,10 +720,10 @@ if test "$ac_cv_func_fwprintf" = yes; then
|
||||
]
|
||||
)
|
||||
],
|
||||
[
|
||||
[
|
||||
AC_MSG_RESULT(no)
|
||||
],
|
||||
[
|
||||
[
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_BROKEN_FWPRINTF], [1], [Define to 1 one if the implemented fwprintf is broken])
|
||||
]
|
||||
@@ -718,7 +756,32 @@ if test "$have__nl_msg_cat_cntr" = yes; then
|
||||
[Define to 1 if the _nl_msg_cat_cntr symbol is exported.]
|
||||
)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
# Check for __environ symbol
|
||||
AC_MSG_CHECKING([for __environ symbol])
|
||||
AC_TRY_LINK(
|
||||
[
|
||||
#include <unistd.h>
|
||||
],
|
||||
[
|
||||
extern char **__environ;
|
||||
char **tmp = __environ;
|
||||
exit(tmp!=0);
|
||||
],
|
||||
have___environ=yes,
|
||||
have___environ=no
|
||||
)
|
||||
if test "$have___environ" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(
|
||||
[HAVE___ENVIRON],
|
||||
[1],
|
||||
[Define to 1 if the __environ symbol is exported.]
|
||||
)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
# Check if getopt_long exists and works
|
||||
@@ -754,7 +817,7 @@ if test "$have_working_getopt_long" = yes; then
|
||||
[Define to 1 if getopt_long exists and works.]
|
||||
)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
# Check if del_curterm is broken - in that case we redefine
|
||||
@@ -776,7 +839,7 @@ case $target_os in
|
||||
esac
|
||||
|
||||
# Tell the world what we know
|
||||
AC_CONFIG_FILES([Makefile fish.spec doc_src/Doxyfile seq])
|
||||
AC_CONFIG_FILES([Makefile fish.spec Doxyfile.help seq])
|
||||
AC_OUTPUT
|
||||
|
||||
if test ! x$local_found_posix_switch = xyes; then
|
||||
|
||||
18
doc_src/alias.txt
Normal file
18
doc_src/alias.txt
Normal file
@@ -0,0 +1,18 @@
|
||||
\section alias alias - create a function
|
||||
|
||||
\subsection alias-synopsis Synopsis
|
||||
<pre>alias NAME DEFINITION
|
||||
alias NAME=DEFINITION</pre>
|
||||
|
||||
\subsection alias-description Description
|
||||
|
||||
Alias is a shellscript wrapper around the function builtin.
|
||||
It exists for backwards compatibility with Posix
|
||||
shells. For other uses, it is recommended to define a <a
|
||||
href='#function'>function</a>.
|
||||
|
||||
Alias does not keep track of which functions have been defined using
|
||||
alias, nor does it allow erasing of aliases.
|
||||
|
||||
- NAME is the name of the function to define
|
||||
- DEFINITION is the body of the function. The string " $argv" will be appended to the body.
|
||||
@@ -23,11 +23,11 @@ scope, they will be automatically deleted when the block ends.
|
||||
|
||||
<pre>
|
||||
begin
|
||||
set -x PIRATE Yarrr
|
||||
set -l PIRATE Yarrr
|
||||
...
|
||||
end
|
||||
# This will not output anything, since PIRATE went out of scope at the end of
|
||||
# the block and was killed
|
||||
# This will not output anything, since the PIRATE variable went out
|
||||
# of scope at the end of the block
|
||||
echo $PIRATE
|
||||
</pre>
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
- <tt>-n</tt> or <tt>--names</tt> List the names of all defined builtins
|
||||
|
||||
Prefixing a command with the word 'builtin' forces fish to ignore any aliases with the same name.
|
||||
Prefixing a command with the word 'builtin' forces fish to ignore any functions with the same name.
|
||||
|
||||
\subsection builtin-example Example
|
||||
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
<tt>command COMMANDNAME [OPTIONS...]</tt>
|
||||
|
||||
\subsection command-description Description
|
||||
prefixing a command with the word 'command' forces fish to ignore any aliases or builtins with the same name.
|
||||
prefixing a command with the word 'command' forces fish to ignore any functions or builtins with the same name.
|
||||
|
||||
\subsection command-example Example
|
||||
|
||||
|
||||
<tt>command ls</tt>
|
||||
|
||||
causes fish to execute the ls program, even if there exists a 'ls' alias.
|
||||
causes fish to execute the ls program, even if there exists a 'ls' function.
|
||||
|
||||
@@ -20,7 +20,7 @@ The following switches change what the commandline builtin does
|
||||
will cause any additional arguments to be interpreted as readline
|
||||
functions, and these functions will be injected into the reader, so
|
||||
that they will be returned to the reader before any additional
|
||||
actual keypresses are read.
|
||||
actual key presses are read.
|
||||
|
||||
|
||||
The following switches change the way \c commandline updates the
|
||||
|
||||
6
doc_src/commands.hdr.in
Normal file
6
doc_src/commands.hdr.in
Normal file
@@ -0,0 +1,6 @@
|
||||
/** \page commands Commands, functions and builtins bundled with fish
|
||||
Fish ships with a large number of builtin commands, shellscript functions and external commands. These are all described below.
|
||||
|
||||
@command_list@
|
||||
|
||||
*/
|
||||
@@ -22,6 +22,7 @@ the fish manual.
|
||||
- <tt>-p</tt> or <tt>--path</tt> implies that the string COMMAND is the full path of the command
|
||||
- <tt>-r</tt> or <tt>--require-parameter</tt> specifies that the option specified by this completion always must have an option argument, i.e. may not be followed by another option
|
||||
- <tt>-u</tt> or <tt>--unauthorative</tt> implies that there may be more options than the ones specified, and that fish should not assume that options not listed are spelling errors
|
||||
- <tt>-A</tt> or <tt>--authorative</tt> implies that there may be no more options than the ones specified, and that fish should assume that options not listed are spelling errors
|
||||
- <tt>-x</tt> or <tt>--exclusive</tt> implies both <tt>-r</tt> and <tt>-f</tt>
|
||||
|
||||
Command specific tab-completions in \c fish are based on the notion
|
||||
|
||||
@@ -71,6 +71,8 @@ in a nonstandard location. Please contact the <a
|
||||
href='mailto:fish-users@lists.sf.net'>fish mailing list</a>, and
|
||||
hopefully this can be resolved.
|
||||
|
||||
<hr>
|
||||
|
||||
\section faq-default How do I make fish my default shell?
|
||||
|
||||
If you installed fish manually (e.g. by compiling it, not by using a
|
||||
@@ -78,6 +80,23 @@ package manager), you first need to add fish to the list of shells by
|
||||
executing the following command (assuming you installed fish in
|
||||
/usr/local) as root:
|
||||
|
||||
|
||||
<code>echo /usr/local/bin/fish >>/etc/shells</code>
|
||||
|
||||
If you installed a prepackaged version of fish, the package manager
|
||||
should have already done this for you.
|
||||
|
||||
In order to change your default shell, type:
|
||||
|
||||
<code>chsh -s /usr/local/bin/fish</code>
|
||||
|
||||
You may need to adjust the above path to e.g. /usr/bin/fish. Use the command <code>which fish</code> if you are unsure of where fish is installed.
|
||||
|
||||
You will need to log out and back in again for the change to take
|
||||
effect.
|
||||
|
||||
<hr>
|
||||
|
||||
\section faq-titlebar I'm seeing weird output before each prompt when using screen. What's wrong?
|
||||
|
||||
Quick answer:
|
||||
@@ -106,21 +125,6 @@ Note that fish has a default titlebar message, which will be used if
|
||||
the fish_title function is undefined. So simply unsetting the
|
||||
fish_title function will not work.
|
||||
|
||||
|
||||
<code>echo /usr/local/bin/fish >>/etc/shells</code>
|
||||
|
||||
If you installed a prepackaged version of fish, the package manager
|
||||
should have already done this for you.
|
||||
|
||||
In order to change your default shell, type:
|
||||
|
||||
<code>chsh -s /usr/bin/fish</code>
|
||||
|
||||
You may need to adjust the above path to e.g. /usr/local/bin/fish.
|
||||
|
||||
You will need to log out and back in again for the change to take
|
||||
effect.
|
||||
|
||||
<hr>
|
||||
|
||||
\section faq-greeting How do I change the greeting message?
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
.TH fish 1 "February 25, 2005" "version @PACKAGE_VERSION@" "USER COMMANDS"
|
||||
.SH NAME
|
||||
fish - friendly interactive shell
|
||||
.SH SYNOPSIS
|
||||
.B fish
|
||||
[\-h] [\-v] [\-c command] [FILE [ARGUMENTS...]]
|
||||
.SH DESCRIPTION
|
||||
A shell written mainly with interactive use in mind. The complete fish manuals are written in HTML format. You can find them by using the
|
||||
.I
|
||||
help
|
||||
command from inside the fish shell.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\-h
|
||||
display help and exit
|
||||
.TP
|
||||
\-c
|
||||
Evaluate the specified commands instead of reading from the commandline
|
||||
.TP
|
||||
\-i
|
||||
Specify that fish is to run in interactive mode
|
||||
.TP
|
||||
\-v
|
||||
display version and exit
|
||||
.SH AUTHOR
|
||||
Axel Liljencrantz ( @PACKAGE_BUGREPORT@ )
|
||||
@@ -1,3 +1,10 @@
|
||||
/** \mainpage Fish user documentation
|
||||
|
||||
\section toc Table of contents
|
||||
|
||||
- <a href="index.html" name="toc-index">Fish user documentation</a>
|
||||
@toc@
|
||||
|
||||
\section introduction Introduction
|
||||
|
||||
This is the documentation for \c fish, the friendly interactive
|
||||
@@ -26,7 +33,7 @@ assigning variables, commands for treating a group of commands as a
|
||||
single command, etc.. And every single command follows the same simple
|
||||
syntax.
|
||||
|
||||
If you wish to find out more about the echo command used above, read
|
||||
If you want to find out more about the echo command used above, read
|
||||
the manual page for the echo command by writing:
|
||||
|
||||
<code>man echo</code>
|
||||
@@ -63,7 +70,7 @@ A switch is a very common special type of argument. Switches almost
|
||||
always start with one or more hyphens (-) and alter the way a command
|
||||
operates. For example, the \c ls command usually lists all the files
|
||||
and directories in the current working directory, but by using the \c
|
||||
-l switch, the behaviour of ls is changed to not only display the
|
||||
-l switch, the behavior of ls is changed to not only display the
|
||||
filename, but also the size, permissions, owner and modification time
|
||||
of each file. Switches differ between commands and are documented in
|
||||
the manual page for each command. Some switches are common to most
|
||||
@@ -128,11 +135,12 @@ these characters, so called escape sequences are provided. These are:
|
||||
- <code>'\\\<'</code>, escapes the less than character
|
||||
- <code>'\\\>'</code>, escapes the more than character
|
||||
- <code>'\\^'</code>, escapes the circumflex character
|
||||
- <code>'\\x<i>xx</i>'</code>, where <code><i>xx</i></code> is a hexadecimal number, escapes the ascii character with the specified value
|
||||
- <code>'\\x<i>xx</i>'</code>, where <code><i>xx</i></code> is a hexadecimal number, escapes the ascii character with the specified value. For example, \\x9 is the tab character.
|
||||
- <code>'\\X<i>xx</i>'</code>, where <code><i>xx</i></code> is a hexadecimal number, escapes a byte of data with the specified value. If you are using a mutibyte encoding, this can be used to enter invalid strings. Only use this if you know what you are doing.
|
||||
- <code>'\\<i>ooo</i>'</code>, where <code><i>ooo</i></code> is an octal number, escapes the ascii character with the specified value
|
||||
- <code>'\\u<i>xxxx</i>'</code>, where <code><i>xxxx</i></code> is a hexadecimal number, escapes the 16-bit unicode character with the specified value
|
||||
- <code>'\\U<i>xxxxxxxx</i>'</code>, where <code><i>xxxxxxxx</i></code> is a hexadecimal number, escapes the 32-bit unicode character with the specified value
|
||||
- <code>'\\<i>ooo</i>'</code>, where <code><i>ooo</i></code> is an octal number, escapes the ascii character with the specified value. For example, \\011 is the tab character.
|
||||
- <code>'\\u<i>xxxx</i>'</code>, where <code><i>xxxx</i></code> is a hexadecimal number, escapes the 16-bit unicode character with the specified value. For example, \\u9 is the tab character.
|
||||
- <code>'\\U<i>xxxxxxxx</i>'</code>, where <code><i>xxxxxxxx</i></code> is a hexadecimal number, escapes the 32-bit unicode character with the specified value. For example, \\U9 is the tab character.
|
||||
- <code>'\\c<i>x</i>'</code>, where <code><i>x</i></code> is a letter of the alphabet, escapes the control sequence generated by pressing the control key and the specified letter. For example, \\ci is the tab character
|
||||
|
||||
\subsection redirects IO redirection
|
||||
|
||||
@@ -265,7 +273,7 @@ href='commands.html#function'>function</a> builtin.
|
||||
\subsubsection syntax-function-wrappers Defining wrapper functions
|
||||
|
||||
One of the most common used for functions is to slightly alter the
|
||||
behaviour of an already existing command. For example, one might want
|
||||
behavior of an already existing command. For example, one might want
|
||||
to redefine the \c ls command to display colors. The switch for
|
||||
turning on colors on GNU systems is \c '--color=auto'. A wrapper
|
||||
around \c ls might look like this:
|
||||
@@ -286,7 +294,7 @@ functions:
|
||||
Functions can be defined on the commandline or in a configuration
|
||||
file, but they can also be automatically loaded. This method of
|
||||
defining functions has several advantages. An autoloaded function
|
||||
becomes avaialble automatically to all running shells, if the function
|
||||
becomes available automatically to all running shells, if the function
|
||||
definition is changed, all running shells will automatically reload
|
||||
the altered version, startup time and memory usage is improved, etc.
|
||||
|
||||
@@ -342,7 +350,7 @@ This is a short explanation of some of the commonly used words in fish.
|
||||
- job, a running pipeline or command
|
||||
- pipeline, a set of commands stringed together so that the output of one command is the input of the next command
|
||||
- redirection, a operation that changes one of the input/output streams associated with a job
|
||||
- switch, a special flag sent as an argument to a command that will alter the behavious of the command. A switch almost always begins with one or two hyphens.
|
||||
- switch, a special flag sent as an argument to a command that will alter the behavior of the command. A switch almost always begins with one or two hyphens.
|
||||
|
||||
\section help Help
|
||||
|
||||
@@ -431,6 +439,65 @@ For examples of how to write your own complex completions, study the
|
||||
completions in /usr/share/fish/completions. (The exact path depends on
|
||||
your chosen installation prefix and may be slightly different)
|
||||
|
||||
\subsection completion-func Useful functions for writing completions
|
||||
|
||||
Fish ships with several functions that are very useful when writing
|
||||
command specific completions. Most of these functions name begins with
|
||||
the string '__fish_'. Such functions are internal to fish and their
|
||||
name and interface may change in future fish versions. Still, some of
|
||||
them may be very useful when writing completions. A few of these
|
||||
functions are described here. Be aware that they may be removed or
|
||||
changed in future versions of fish.
|
||||
|
||||
Functions beginning with the string '__fish_print_' print a
|
||||
newline-separated list of strings. For example,
|
||||
__fish_print_filesystems prints a list of all known file systems. Functions
|
||||
beginning with '__fish_complete_' print out a newline separated list of
|
||||
completions with descriptions. The description is separated from the
|
||||
completion by a tab character.
|
||||
|
||||
<pre>__fish_complete_directories STRING DESCRIPTION</pre>
|
||||
|
||||
performs path completion on STRING, allowing only directories, and giving them the description DESCRIPTION.
|
||||
|
||||
<pre>__fish_complete_groups</pre>
|
||||
|
||||
prints a list of all user groups with the groups members as description.
|
||||
|
||||
<pre>__fish_complete_pids</pre>
|
||||
|
||||
prints a list of all procceses IDs with the command name as description.
|
||||
|
||||
<pre>__fish_complete_suffix SUFFIX</pre>
|
||||
|
||||
performs file completion allowing only files ending in SUFFIX. The mimetype database is usded to find a suitable description.
|
||||
|
||||
<pre>__fish_complete_users</pre>
|
||||
|
||||
prints a list of all users with their full name as description.
|
||||
|
||||
<pre>__fish_print_filesystems</pre>
|
||||
|
||||
prints a list of all known file systems. Currently, this is a static
|
||||
list, and not dependent on what file systems the host operating system
|
||||
actually understands.
|
||||
|
||||
<pre>__fish_print_hostnames</pre>
|
||||
|
||||
prints a list of all known hostnames. This functions searches the
|
||||
fstab for nfs servers, ssh for known hosts and checks the /etc/hosts file.
|
||||
|
||||
<pre>__fish_print_interfaces</pre>
|
||||
|
||||
prints a list of all known network interfaces.
|
||||
|
||||
<pre>__fish_print_packages</pre>
|
||||
|
||||
prints a list of all installed packages. This function currently handles
|
||||
debian, rpm and gentoo packages.
|
||||
|
||||
|
||||
|
||||
\subsection completion-path Where to put completions
|
||||
|
||||
Completions can be defined on the commandline or in a configuration
|
||||
@@ -459,8 +526,11 @@ href='mailto: fish-users@lists.sf.net'>the fish mailinglist</a>.
|
||||
|
||||
When an argument for a program is given on the commandline, it
|
||||
undergoes the process of parameter expansion before it is sent on to
|
||||
the command. There are many ways in which the user can specify a
|
||||
parameter to be expanded. These include:
|
||||
the command. Parameter expansion is a powerful set of mechamisms that
|
||||
allow you to expand the parameter in various ways, including
|
||||
performing wildcard matching on files, inserting the value of
|
||||
environment variables into the parameter or even using the output of
|
||||
another command as a parameter list.
|
||||
|
||||
\subsection expand-wildcard Wildcards
|
||||
|
||||
@@ -472,6 +542,11 @@ way that:
|
||||
- '*' can match any string of characters not containing '/'. This includes matching an empty string.
|
||||
- '**' matches any string of characters. This includes matching an empty string. The string may include the '/' character but does not need to.
|
||||
|
||||
Wildcard matches are sorted case insensitively. When sorting matches
|
||||
containing numbers, consecutive digits are considered to be one
|
||||
element, so that the strings '1' '5' and '12' would be sorted in the
|
||||
order given.
|
||||
|
||||
File names beginning with a dot are not considered when wildcarding
|
||||
unless a dot is specifically given as the first character of the file
|
||||
name.
|
||||
@@ -493,7 +568,7 @@ warning will also be printed.
|
||||
\subsection expand-command-substitution Command substitution
|
||||
|
||||
If a parameter contains a set of parenthesis, the text enclosed by the
|
||||
parenthesis will be interpreted as a list of commands. Om expansion,
|
||||
parenthesis will be interpreted as a list of commands. On expansion,
|
||||
this list is executed, and substituted by the output. If the output is
|
||||
more than one line long, each line will be expanded to a new
|
||||
parameter.
|
||||
@@ -588,11 +663,11 @@ end
|
||||
</pre>
|
||||
|
||||
The above code demonstrates how to use multiple '$' symbols to expand
|
||||
the value of a variable as a variable name. One can simply think of
|
||||
the value of a variable as a variable name. One can think of
|
||||
the $-symbol as a variable dereference operator. When using this
|
||||
feature together with array brackets, the brackets will always match
|
||||
the innermost $ dereference. Thus, $$foo[5] will always mean the fift
|
||||
element of the foo variable should be dereferenced and never that the fift
|
||||
the innermost $ dereference. Thus, $$foo[5] will always mean the fifth
|
||||
element of the foo variable should be dereferenced and never that the fifth
|
||||
element of the doubly dereferenced variable foo. The latter can
|
||||
instead be expressed as $$foo[1][5].
|
||||
|
||||
@@ -635,6 +710,17 @@ All of the above expansions can be combined. If several expansions
|
||||
result in more than one parameter, all possible combinations are
|
||||
created.
|
||||
|
||||
When combining multiple parameter expansions, expansions are performed in the following order:
|
||||
|
||||
- Command substitutions
|
||||
- Variable expansions
|
||||
- Bracket expansion
|
||||
- Pid expansion
|
||||
- Wildcard expansion
|
||||
|
||||
Expansions are performed from right to left, nested bracket expansions
|
||||
are performed from the inside and out.
|
||||
|
||||
Example:
|
||||
|
||||
If the current directory contains the files 'foo' and 'bar', the command
|
||||
@@ -913,7 +999,7 @@ To make errors highlighted and red, use:
|
||||
\subsection variables-locale Locale variables
|
||||
|
||||
The most common way to set the locale to use a command like 'set -x
|
||||
LANG en_GB.utf8', which sets the current locale to be the english
|
||||
LANG en_GB.utf8', which sets the current locale to be the English
|
||||
language, as used in Great Britain, using the UTF-8 character set. For
|
||||
a list of available locales, use 'locale -a'.
|
||||
|
||||
@@ -969,7 +1055,7 @@ Here are some of the commands available in the editor:
|
||||
You can change these key bindings by making an inputrc file. To do
|
||||
this, copy the file /etc/fish/fish_inputrc to your home directory and
|
||||
rename it to '.config/fish/fish_inputrc'. Now you can edit the file
|
||||
to change your key bindings. The fileformat of this file is described
|
||||
to change your key bindings. The file format of this file is described
|
||||
in the manual page for readline. Use the command <code>man readline</code>
|
||||
to read up on this syntax. Please note that the list of key binding
|
||||
functions in fish is different to that offered by readline. Currently,
|
||||
@@ -1031,7 +1117,7 @@ the string entered into the command line are shown.
|
||||
By pressing Alt-up and Alt-down, a history search is also performed,
|
||||
but instead of searching for a complete commandline, each commandline
|
||||
is tokenized into separate elements just like it would be before
|
||||
execution, and each such token is matched agains the token under the
|
||||
execution, and each such token is matched against the token under the
|
||||
cursor when the search began.
|
||||
|
||||
History searches can be aborted by pressing the escape key.
|
||||
@@ -1066,7 +1152,7 @@ fish will be stopped until the program finishes. Sometimes this is not
|
||||
desirable. For example, you may wish to start an application with a
|
||||
graphical user interface from the terminal, and then be able to
|
||||
continue using the shell. In such cases, there are several ways in
|
||||
which the user can change <code>fish</code>'s behaviour.
|
||||
which the user can change <code>fish</code>'s behavior.
|
||||
|
||||
-# By ending a command with the \& (ampersand) symbol, the user tells \c fish to put the specified command into the background. A background process will be run simultaneous with \c fish. \c fish will retain control of the terminal, so the program will not be able to read from the keyboard.
|
||||
-# By pressing ^Z, the user stops a currently running foreground program and returns control to \c fish. Some programs do not support this feature, or remap it to another key. Gnu emacs uses ^X z to stop running.
|
||||
@@ -1161,7 +1247,7 @@ function fish_prompt -d "Write out the prompt"
|
||||
end
|
||||
</pre>
|
||||
|
||||
where \c prompt_pwd is a shellscript function that displays a condensed version of the current working direcotry.
|
||||
where \c prompt_pwd is a shellscript function that displays a condensed version of the current working directory.
|
||||
|
||||
</p>
|
||||
|
||||
@@ -1264,7 +1350,7 @@ msgid "%ls: No suitable job\n"
|
||||
msgstr ""
|
||||
</pre>
|
||||
|
||||
The first line is the english string to translate, the second line
|
||||
The first line is the English string to translate, the second line
|
||||
should contain your translation. For example, in swedish the above
|
||||
might become:
|
||||
|
||||
@@ -1288,31 +1374,32 @@ href='fish-users@lists.sf.net'>fish-users@lists.sf.net</a>.
|
||||
|
||||
\subsection todo-features Missing features
|
||||
|
||||
- A limited interactive mode for really dumb terminals
|
||||
- The completion autoloader does not remember which completions where actually autoloaded, and may unload manually specified completions.
|
||||
- Use a struct to describe a possible completion instead of a weirdly formated string
|
||||
- Complete vi-mode key bindings
|
||||
- More completions (for example xterm, vim,
|
||||
konsole, gnome-terminal, dcop, cron,
|
||||
rlogin, rsync, arch, finger, nice, locate,
|
||||
bibtex, aspell, xpdf,
|
||||
konsole, gnome-terminal, cron,
|
||||
rlogin, rsync, arch, finger, bibtex, aspell, xpdf,
|
||||
compress, wine, xmms, dig, batch, cron,
|
||||
g++, javac, java, gcj, lpr, doxygen, whois, find)
|
||||
g++, javac, java, gcj, lpr, doxygen, whois)
|
||||
- Undo support
|
||||
- Check keybinding commands for output - if nothing has happened, don't repaint to reduce flicker
|
||||
- wait shellscript
|
||||
- Support for the screen clipboard
|
||||
- Files begining with '-' should not be colored red if a '--' argument has been given
|
||||
- It should be possible to test in a script if a function is autoloaded or manually defined
|
||||
- A pretty-printer. It should among other things be able to indent a piece of code.
|
||||
- Up/down to move between lines in multiline mode
|
||||
- a 'funced' function, which works like the vared function. Needs the above three features in order to work well.
|
||||
- The validator should be better about error reporting unclosed quotes. They are usually reported as something else.
|
||||
|
||||
\subsection todo-possible Possible features
|
||||
|
||||
- tab completion could use smart casing
|
||||
- Completions could support options beginning with a plus (like xterm
|
||||
+fbx) and options without dashes (like top p) Do we really want to
|
||||
complicate the code additionally for such a small number of programs?
|
||||
- mouse support like zsh has with http://stchaz.free.fr/mouse.zsh
|
||||
installed would be awesome
|
||||
- suggest a completion on unique matches by writing it out in an understated color
|
||||
- With a bit of tweakage, quite a few of the readline key-binding functions could be implemented in shellscript.
|
||||
- Highlight beginning/end of block when moving over a block command
|
||||
- Inclusion guards for the init files to make them evaluate only once, even if the user has installed fish both in /etc and in $HOME
|
||||
- command specific wildcarding (use case * instead of case '*', etc.)
|
||||
- Map variables. (export only the values. When expanding with no key specified, expand to all values.)
|
||||
- Descriptions for variables using 'set -d'.
|
||||
@@ -1324,9 +1411,6 @@ g++, javac, java, gcj, lpr, doxygen, whois, find)
|
||||
- Per process output redirection
|
||||
- Reduce the space of the pager by one line to allow the commandline to remain visible.
|
||||
- down-arrow could be used to save the current command to the history. Or give the next command in-sequnce. Or both.
|
||||
- A pretty-printer.
|
||||
- Help messages for builtin should not be compiled into fish, they should be kept in a separate directory
|
||||
- Shellscript functions should be able to show help on the commandline instead of launching a browser
|
||||
- Drop support for inputrc-files. Use shellscripts and the bind builtin. Also, redo the syntax for the bind builtin to something more sane.
|
||||
- History could reload itself when the file is updated. This would need to be done in a clever way to avoid chain reactions
|
||||
- The error function should probably be moved into it's own library, and be made mere general purpose.
|
||||
@@ -1334,20 +1418,20 @@ g++, javac, java, gcj, lpr, doxygen, whois, find)
|
||||
- The parser_is_* functions should be moved to parse_util. Possibly, they should be made into a single function, i.e. parse_util_classify( "begin", BLOCK_COMMAND);
|
||||
- Try to remove more malloc calls to reduce memory usage. The time_t arrays used by the autoloader sound like a good candidate.
|
||||
- The code validator should warn about unknown commands.
|
||||
- The large number of interned strings means that autounloading frees less memory than it should. Completion strings should probably be either refcounted or not shared at all.
|
||||
- Auto-newlines
|
||||
- Completions for uncompressing archives, like unrar could look into the compressed file and allow you to select what files to extract
|
||||
- A fault injector could be written to increase robustness and testing of error recovery paths
|
||||
- The parser/validator could be more clever in order to make things like writing 'function --help' work as expected
|
||||
- Some event handler functions make much more sense as oneshots - maybe they should be automatically deleted after firing?
|
||||
- exec_subshell should be either merged with eval or moved to parser.c
|
||||
|
||||
\subsection bugs Known bugs and issues
|
||||
|
||||
- Completion for gcc -\#\#\# option doesn't work.
|
||||
- Suspending and then resuming pipelines containing a builtin is broken. How should this be handled?
|
||||
- screen handling code can't handle tabs in input.
|
||||
- The completion pager doesn't work if stderr is redirected.
|
||||
- Can't complete directories as commands unless there is a slash
|
||||
- ls should use dircolors
|
||||
- Doxygen called when it shouldn't?
|
||||
- Delete-word is broken on the commandline 'sudo update-alternatives --config x-'
|
||||
- Suspending and then resuming pipelines containing a builtin or a shellscript function is broken. Ideally, the exec function in exec.c should be able to resume execution of a partially executed job.
|
||||
- delete-word is broken on the commandline 'sudo update-alternatives --config x-'
|
||||
- When a builtin has its output redirected to a file, and the builtin does not produce any IO, then the file is never opened. Thus tha file may not be cleared.
|
||||
- No '--' completion
|
||||
- else is not indented properly
|
||||
- if an if fails inside an if, the out if's else may trigger
|
||||
|
||||
If you think you have found a bug not described here, please send a
|
||||
report to <a href="mailto:fish-users@lists.sf.net">fish-users@lists.sf.net</a>.
|
||||
@@ -1,4 +1,4 @@
|
||||
\section isatty isatty - test if the specidied file descriptor is a tty
|
||||
\section isatty isatty - test if the specified file descriptor is a tty
|
||||
|
||||
\subsection isatty-synopsis Synopsis
|
||||
<tt>isatty [FILE DESCRIPTOR]</tt>
|
||||
|
||||
20
doc_src/math.txt
Normal file
20
doc_src/math.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
\section math math - Perform mathematics calculations
|
||||
|
||||
\subsection math-synopsis Synopsis
|
||||
<tt>math EXPRESSION</tt>
|
||||
|
||||
\subsection math-description Description
|
||||
|
||||
math is used to perform mathematical calcualtions. It is only a very
|
||||
thin wrapper for the bc program, that makes it possible to specify an
|
||||
expression from the command line without using non-standard extensions
|
||||
or a pipeline. Simply use a command like <code>math 1+1</code>.
|
||||
|
||||
For a description of the syntax supported by math, see the manual for
|
||||
the bc program. Keep in mind that parameter expansion takes place on
|
||||
any expressions before they are evaluated. This can be very useful in
|
||||
order to perform calculations involving environment variables or the
|
||||
output of command substitutions, but it also means that parenthesis
|
||||
have to be escaped.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
\section psub psub - perform process substitution
|
||||
|
||||
\subsection psub-synopsis Synopsis
|
||||
<tt>COMMAND1 (COMMAND2|psub) </tt>
|
||||
<tt>COMMAND1 (COMMAND2|psub [-f]) </tt>
|
||||
|
||||
\subsection psub-description Description
|
||||
|
||||
@@ -14,6 +14,12 @@ filename of the named pipe sent as an argument to the calling
|
||||
program. The psub shellscript function, which when combined with a
|
||||
regular command substitution provides the same functionality.
|
||||
|
||||
If the \c -f or \c --file switch is given to psub, psub will use a
|
||||
regular file instead of a named pipe to communicate with the calling
|
||||
process. This will cause psub to be significantly slower when large
|
||||
amounts of data are involved, but has the advantage that the reading
|
||||
process can seek in the stream.
|
||||
|
||||
\subsection psub-example Example
|
||||
|
||||
<tt>diff (sort a.txt|psub) (sort b.txt|psub)</tt> shows the difference
|
||||
|
||||
@@ -11,7 +11,9 @@ input and store the result in one or more environment variables.
|
||||
- <tt>-c CMD</tt> or <tt>--command=CMD</tt> specifies that the initial string in the interactive mode command buffer should be CMD.
|
||||
- <tt>-e</tt> or <tt>--export</tt> specifies that the variables will be exported to subshells.
|
||||
- <tt>-g</tt> or <tt>--global</tt> specifies that the variables will be made global.
|
||||
- <tt>-m NAME</tt> or <tt>--mode-name=NAME</tt> specifies that the name NAME should be used to save/load the hiustory file. If NAME is fish, the regular fish history will be available.
|
||||
- <tt>-p PROMPT_CMD</tt> or <tt>--prompt=PROMPT_CMD</tt> specifies that the output of the shell command PROMPT_CMD should be used as the prompt for the interactive mode prompt. The default prompt command is <tt>set_color green; echo read; set_color normal; echo "> "</tt>.
|
||||
- <code>-s</code> or <code>--shell</code> Use syntax highlighting, tab completions and command termination suitable for entering shellscript code
|
||||
- <code>-u</code> or <code>--unexport</code> causes the specified environment not to be exported to child processes
|
||||
- <code>-U</code> or <code>--universal</code> causes the specified environment variable to be made universal. If this option is supplied, the variable will be shared between all the current users fish instances on the current computer, and will be preserved across restarts of the shell.
|
||||
- <code>-x</code> or <code>--export</code> causes the specified environment variable to be exported to child processes
|
||||
|
||||
12
doc_src/save_function.txt
Normal file
12
doc_src/save_function.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
\section save_function save_function - save the definition of a function to the users autoload directory
|
||||
|
||||
\subsection save_function-synopsis Synopsis
|
||||
<tt>save_function FUNCTION_NAME</tt>
|
||||
|
||||
\subsection save_function-description Description
|
||||
|
||||
save_function is used to save the current definition of a function to
|
||||
a file which will be autoloaded by current and future fish
|
||||
sessions. This can be useful if you have interactively created a new
|
||||
function and wish to save it for later use.
|
||||
|
||||
@@ -5,21 +5,12 @@
|
||||
|
||||
\subsection ulimit-description Description
|
||||
|
||||
The ulimit builtin provides control over the resources available to
|
||||
the shell and to processes started by it. The -H and -S options
|
||||
specify that the hard or soft limit is set for the given resource. A
|
||||
hard limit cannot be increased once it is set; a soft limit may be
|
||||
increased up to the value of the hard limit. If neither -H nor -S is
|
||||
specified, both the soft and hard limits are set. The value of limit
|
||||
can be a number in the unit specified for the resource or one of the
|
||||
special values hard, soft, or unlimited, which stand for the current
|
||||
hard limit, the current soft limit, and no limit, respectively. If
|
||||
limit is omitted, the current value of the soft limit of the resource
|
||||
is printed, unless the -H option is given. When more than one
|
||||
resource is specified, the limit name and unit are printed before the
|
||||
value. Other options are interpreted as follows:
|
||||
The ulimit builtin is used to set the resource usage limits of the
|
||||
shell and any processes spawned by it. If a new limit value is
|
||||
omitted, the current value of the limit of the resource is printed.
|
||||
|
||||
Use one of the following switches to specify which resource limit to set or report:
|
||||
|
||||
- <code>-a</code> or <code>--all</code> Set or get all current limits
|
||||
- <code>-c</code> or <code>--core-size</code> The maximum size of core files created
|
||||
- <code>-d</code> or <code>--data-size</code> The maximum size of a process's data segment
|
||||
- <code>-f</code> or <code>--file-size</code> The maximum size of files created by the shell
|
||||
@@ -31,17 +22,41 @@ value. Other options are interpreted as follows:
|
||||
- <code>-u</code> or <code>--process-count</code> The maximum number of processes available to a single user
|
||||
- <code>-v</code> or <code>--virtual-memory-size</code> The maximum amount of virtual memory available to the shell. If supported by OS.
|
||||
|
||||
Note that not all these limits are available in all operating systems.
|
||||
|
||||
The value of limit can be a number in the unit specified for
|
||||
the resource or one of the special values hard, soft, or unlimited,
|
||||
which stand for the current hard limit, the current soft limit, and no
|
||||
limit, respectively.
|
||||
|
||||
If limit is given, it is the new value of the specified resource. If
|
||||
no option is given, then -f is assumed. Values are in kilobytes,
|
||||
except for -t, which is in seconds and -n and -u, which are unscaled
|
||||
values. The return status is 0 unless an invalid option or argument is
|
||||
supplied, or an error occurs while setting a new limit.
|
||||
|
||||
The fish implementation of ulimit should behave identically to the implementation in bash, except for these differences:
|
||||
ulimit also accepts the following switches that determine what type of limit to set:
|
||||
|
||||
- <code>-H</code> or <code>--hard</code> Set hard resource limit
|
||||
- <code>-S</code> or <code>--soft</code> Set soft resource limit
|
||||
|
||||
A hard limit cannot be increased once it is set; a soft limit may be
|
||||
increased up to the value of the hard limit. If neither -H nor -S is
|
||||
specified, both the soft and hard limits are updated when assigning a
|
||||
new limit value, and the soft limit is used when reporting the current
|
||||
value.
|
||||
|
||||
The following additional options are also understood by ulimit:
|
||||
|
||||
- <code>-a</code> or <code>--all</code> Print all current limits
|
||||
- <code>-h</code> or <code>--help</code> Display help and exit
|
||||
|
||||
The fish implementation of ulimit should behave identically to the
|
||||
implementation in bash, except for these differences:
|
||||
|
||||
- Fish ulimit supports GNU-style long options for all switches
|
||||
- Fish ulimit does not support the -p option for getting the pipe size. The bash implementation consists of a compile-time check that empirically guesses this number by writing to a pipe and waiting for SIGPIPE.
|
||||
- Fish ulimit does not support getting the values of multiple limits in one command, except by using the -a switch
|
||||
- Fish ulimit does not support the -p option for getting the pipe size. The bash implementation consists of a compile-time check that empirically guesses this number by writing to a pipe and waiting for SIGPIPE. Depending on bash version, there may also be further additional limits to set in bash that do not exist in fish.
|
||||
- Fish ulimit does not support getting or setting multiple limits in one command, except reporting all values using the -a switch
|
||||
|
||||
\subsection ulimit-example Example
|
||||
|
||||
|
||||
231
env.c
231
env.c
@@ -1,7 +1,6 @@
|
||||
/** \file env.c
|
||||
Functions for setting and getting environment variables.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -67,9 +66,13 @@
|
||||
#define ENV_NULL L"\x1d"
|
||||
|
||||
/**
|
||||
At init, we read all the environment variables from this array
|
||||
At init, we read all the environment variables from this array.
|
||||
*/
|
||||
extern char **environ;
|
||||
/**
|
||||
This should be the same thing as \c environ, but it is possible only one of the two work...
|
||||
*/
|
||||
extern char **__environ;
|
||||
|
||||
|
||||
/**
|
||||
@@ -108,6 +111,8 @@ typedef struct env_node
|
||||
typedef struct var_entry
|
||||
{
|
||||
int export; /**< Whether the variable should be exported */
|
||||
size_t size; /**< The maximum length (excluding the NULL) that will fit into this var_entry_t */
|
||||
|
||||
#if __STDC_VERSION__ < 199901L
|
||||
wchar_t val[1]; /**< The value of the variable */
|
||||
#else
|
||||
@@ -200,7 +205,9 @@ static void clear_hash_entry( void *key, void *data )
|
||||
{
|
||||
var_entry_t *entry = (var_entry_t *)data;
|
||||
if( entry->export )
|
||||
{
|
||||
has_changed = 1;
|
||||
}
|
||||
|
||||
free( (void *)key );
|
||||
free( (void *)data );
|
||||
@@ -255,8 +262,12 @@ static int is_locale( const wchar_t *key )
|
||||
{
|
||||
int i;
|
||||
for( i=0; locale_variable[i]; i++ )
|
||||
{
|
||||
if( wcscmp(locale_variable[i], key ) == 0 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -301,8 +312,11 @@ static void handle_locale()
|
||||
for( i=2; locale_variable[i]; i++ )
|
||||
{
|
||||
const wchar_t *val = env_get( locale_variable[i] );
|
||||
|
||||
if( val )
|
||||
{
|
||||
wsetlocale( cat[i], val );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,8 +330,10 @@ static void handle_locale()
|
||||
strings should be reloaded. We do both and hope for the
|
||||
best.
|
||||
*/
|
||||
|
||||
extern int _nl_msg_cat_cntr;
|
||||
++_nl_msg_cat_cntr;
|
||||
_nl_msg_cat_cntr++;
|
||||
|
||||
dcgettext( "fish", "Changing language to English", LC_MESSAGES );
|
||||
|
||||
if( is_interactive )
|
||||
@@ -341,17 +357,24 @@ static void universal_callback( int type,
|
||||
wchar_t *str=0;
|
||||
|
||||
if( is_locale( name ) )
|
||||
{
|
||||
handle_locale();
|
||||
}
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case SET:
|
||||
case SET_EXPORT:
|
||||
{
|
||||
str=L"SET";
|
||||
break;
|
||||
}
|
||||
|
||||
case ERASE:
|
||||
{
|
||||
str=L"ERASE";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( str )
|
||||
@@ -402,19 +425,27 @@ static void setup_path()
|
||||
al_init( &l );
|
||||
|
||||
if( path )
|
||||
{
|
||||
tokenize_variable_array( path, &l );
|
||||
}
|
||||
|
||||
for( j=0; path_el[j]; j++ )
|
||||
{
|
||||
|
||||
int has_el=0;
|
||||
|
||||
for( i=0; i<al_get_count( &l); i++ )
|
||||
{
|
||||
wchar_t * el = (wchar_t *)al_get( &l, i );
|
||||
size_t len = wcslen( el );
|
||||
|
||||
while( (len > 0) && (el[len-1]==L'/') )
|
||||
{
|
||||
len--;
|
||||
if( (wcslen( path_el[j] ) == len) && (wcsncmp( el, path_el[j], len)==0) )
|
||||
}
|
||||
|
||||
if( (wcslen( path_el[j] ) == len) &&
|
||||
(wcsncmp( el, path_el[j], len)==0) )
|
||||
{
|
||||
has_el = 1;
|
||||
}
|
||||
@@ -454,6 +485,7 @@ static void setup_path()
|
||||
|
||||
static void env_set_defaults()
|
||||
{
|
||||
|
||||
if( !env_get( L"USER" ) )
|
||||
{
|
||||
struct passwd *pw = getpwuid( getuid());
|
||||
@@ -461,6 +493,7 @@ static void env_set_defaults()
|
||||
env_set( L"USER", unam, ENV_GLOBAL );
|
||||
free( unam );
|
||||
}
|
||||
|
||||
if( !env_get( L"HOME" ) )
|
||||
{
|
||||
wchar_t *unam = env_get( L"USER" );
|
||||
@@ -471,6 +504,7 @@ static void env_set_defaults()
|
||||
free( dir );
|
||||
free( unam_narrow );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void env_init()
|
||||
@@ -480,7 +514,6 @@ void env_init()
|
||||
wchar_t *uname;
|
||||
wchar_t *version;
|
||||
|
||||
|
||||
sb_init( &dyn_var );
|
||||
b_init( &export_buffer );
|
||||
|
||||
@@ -522,7 +555,7 @@ void env_init()
|
||||
hash_init( &top->env, &hash_wcs_func, &hash_wcs_cmp );
|
||||
global_env = top;
|
||||
global = &top->env;
|
||||
|
||||
|
||||
/*
|
||||
Now the environemnt variable handling is set up, the next step
|
||||
is to insert valid data
|
||||
@@ -531,7 +564,7 @@ void env_init()
|
||||
/*
|
||||
Import environment variables
|
||||
*/
|
||||
for( p=environ; *p; p++ )
|
||||
for( p=environ?environ:__environ; p && *p; p++ )
|
||||
{
|
||||
wchar_t *key, *val;
|
||||
wchar_t *pos;
|
||||
@@ -539,13 +572,16 @@ void env_init()
|
||||
key = str2wcs(*p);
|
||||
|
||||
if( !key )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
val = wcschr( key, L'=' );
|
||||
|
||||
|
||||
if( val == 0 )
|
||||
{
|
||||
env_set( key, L"", ENV_EXPORT );
|
||||
}
|
||||
else
|
||||
{
|
||||
*val = L'\0';
|
||||
@@ -555,7 +591,9 @@ void env_init()
|
||||
while( *pos )
|
||||
{
|
||||
if( *pos == L':' )
|
||||
{
|
||||
*pos = ARRAY_SEP;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
|
||||
@@ -563,7 +601,7 @@ void env_init()
|
||||
}
|
||||
free(key);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Set up the PATH variable
|
||||
*/
|
||||
@@ -607,8 +645,10 @@ void env_destroy()
|
||||
b_destroy( &export_buffer );
|
||||
|
||||
while( &top->env != global )
|
||||
{
|
||||
env_pop();
|
||||
|
||||
}
|
||||
|
||||
hash_destroy( &env_read_only );
|
||||
|
||||
hash_destroy( &env_electric );
|
||||
@@ -622,8 +662,8 @@ void env_destroy()
|
||||
}
|
||||
|
||||
/**
|
||||
Find the scope hashtable containing the variable with the specified
|
||||
key
|
||||
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 wchar_t *key )
|
||||
{
|
||||
@@ -641,9 +681,13 @@ static env_node_t *env_get_node( const wchar_t *key )
|
||||
}
|
||||
|
||||
if( env->new_scope )
|
||||
{
|
||||
env = global_env;
|
||||
}
|
||||
else
|
||||
{
|
||||
env = env->next;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -663,7 +707,7 @@ int env_set( const wchar_t *key,
|
||||
|
||||
event_t ev;
|
||||
int is_universal = 0;
|
||||
|
||||
|
||||
CHECK( key, ENV_INVALID );
|
||||
|
||||
if( (var_mode & ENV_USER ) &&
|
||||
@@ -691,13 +735,15 @@ int env_set( const wchar_t *key,
|
||||
}
|
||||
}
|
||||
/*
|
||||
Do not actually create a umask variable, on env_get, it will be calculated dynamically
|
||||
Do not actually create a umask variable, on env_get, it will
|
||||
be calculated dynamically
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Zero element arrays are internaly not coded as null but as this placeholder string
|
||||
Zero element arrays are internaly not coded as null but as this
|
||||
placeholder string
|
||||
*/
|
||||
if( !val )
|
||||
{
|
||||
@@ -714,7 +760,9 @@ int env_set( const wchar_t *key,
|
||||
env_universal_get_export( key );
|
||||
}
|
||||
else
|
||||
{
|
||||
export = (var_mode & ENV_EXPORT );
|
||||
}
|
||||
|
||||
env_universal_set( key, val, export );
|
||||
is_universal = 1;
|
||||
@@ -723,14 +771,6 @@ int env_set( const wchar_t *key,
|
||||
else
|
||||
{
|
||||
|
||||
if( val == 0 )
|
||||
{
|
||||
wchar_t *prev_val;
|
||||
free_val = 1;
|
||||
prev_val = env_get( key );
|
||||
val = wcsdup( prev_val?prev_val:L"" );
|
||||
}
|
||||
|
||||
node = env_get_node( key );
|
||||
if( node && &node->env != 0 )
|
||||
{
|
||||
@@ -738,15 +778,15 @@ int env_set( const wchar_t *key,
|
||||
key );
|
||||
|
||||
if( e->export )
|
||||
{
|
||||
has_changed_new = 1;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if( (var_mode & ENV_LOCAL) ||
|
||||
(var_mode & ENV_GLOBAL) )
|
||||
{
|
||||
node = ( var_mode & ENV_GLOBAL )?global_env:top;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -776,8 +816,10 @@ int env_set( const wchar_t *key,
|
||||
env_universal_get_export( key );
|
||||
}
|
||||
else
|
||||
{
|
||||
export = (var_mode & ENV_EXPORT );
|
||||
|
||||
}
|
||||
|
||||
env_universal_set( key, val, export );
|
||||
is_universal = 1;
|
||||
|
||||
@@ -788,12 +830,15 @@ int env_set( const wchar_t *key,
|
||||
{
|
||||
/*
|
||||
New variable with unspecified scope. The default
|
||||
scope is the innermost scope that is shadowing
|
||||
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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -801,24 +846,59 @@ int env_set( const wchar_t *key,
|
||||
if( !done )
|
||||
{
|
||||
void *k, *v;
|
||||
hash_remove( &node->env, key, &k, &v );
|
||||
free( k );
|
||||
free( v );
|
||||
var_entry_t *old_entry;
|
||||
size_t val_len = wcslen(val);
|
||||
|
||||
entry = malloc( sizeof( var_entry_t ) +
|
||||
sizeof(wchar_t )*(wcslen(val)+1));
|
||||
|
||||
if( var_mode & ENV_EXPORT)
|
||||
hash_remove( &node->env, key, &k, &v );
|
||||
|
||||
/*
|
||||
Try to reuse previous key string
|
||||
*/
|
||||
if( !k )
|
||||
{
|
||||
entry->export = 1;
|
||||
has_changed_new = 1;
|
||||
k = wcsdup(key);
|
||||
}
|
||||
|
||||
old_entry = (var_entry_t *)v;
|
||||
if( old_entry && old_entry->size >= val_len )
|
||||
{
|
||||
entry = old_entry;
|
||||
|
||||
if( !!(var_mode & ENV_EXPORT) || entry->export )
|
||||
{
|
||||
entry->export = !!(var_mode & ENV_EXPORT);
|
||||
has_changed_new = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
entry->export = 0;
|
||||
{
|
||||
free( v );
|
||||
|
||||
entry = malloc( sizeof( var_entry_t ) +
|
||||
sizeof(wchar_t )*(val_len+1));
|
||||
|
||||
if( !entry )
|
||||
{
|
||||
DIE_MEM();
|
||||
}
|
||||
|
||||
entry->size = val_len;
|
||||
|
||||
if( var_mode & ENV_EXPORT)
|
||||
{
|
||||
entry->export = 1;
|
||||
has_changed_new = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry->export = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
wcscpy( entry->val, val );
|
||||
|
||||
hash_put( &node->env, wcsdup(key), entry );
|
||||
|
||||
hash_put( &node->env, k, entry );
|
||||
|
||||
if( entry->export )
|
||||
{
|
||||
@@ -826,8 +906,10 @@ int env_set( const wchar_t *key,
|
||||
}
|
||||
|
||||
if( free_val )
|
||||
{
|
||||
free((void *)val);
|
||||
|
||||
}
|
||||
|
||||
has_changed = has_changed_old || has_changed_new;
|
||||
}
|
||||
|
||||
@@ -873,8 +955,10 @@ static int try_remove( env_node_t *n,
|
||||
wchar_t *old_key, *old_val;
|
||||
|
||||
if( n == 0 )
|
||||
{
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
hash_remove( &n->env,
|
||||
key,
|
||||
&old_key_void,
|
||||
@@ -897,12 +981,18 @@ static int try_remove( env_node_t *n,
|
||||
}
|
||||
|
||||
if( var_mode & ENV_LOCAL )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( n->new_scope )
|
||||
{
|
||||
return try_remove( global_env, key, var_mode );
|
||||
}
|
||||
else
|
||||
{
|
||||
return try_remove( n->next, key, var_mode );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -996,7 +1086,10 @@ wchar_t *env_get( const wchar_t *key )
|
||||
}
|
||||
|
||||
if( i!=0)
|
||||
{
|
||||
sb_append( &dyn_var, ARRAY_SEP_STR );
|
||||
}
|
||||
|
||||
sb_append( &dyn_var, next );
|
||||
}
|
||||
|
||||
@@ -1038,13 +1131,19 @@ wchar_t *env_get( const wchar_t *key )
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return res->val;
|
||||
}
|
||||
}
|
||||
|
||||
if( env->new_scope )
|
||||
{
|
||||
env = global_env;
|
||||
}
|
||||
else
|
||||
{
|
||||
env = env->next;
|
||||
}
|
||||
}
|
||||
if( !proc_had_barrier)
|
||||
{
|
||||
@@ -1059,7 +1158,9 @@ wchar_t *env_get( const wchar_t *key )
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
int env_exist( const wchar_t *key, int mode )
|
||||
@@ -1096,12 +1197,18 @@ int env_exist( const wchar_t *key, int mode )
|
||||
}
|
||||
|
||||
if( mode & ENV_LOCAL )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if( env->new_scope )
|
||||
{
|
||||
env = global_env;
|
||||
}
|
||||
else
|
||||
{
|
||||
env = env->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1314,16 +1421,31 @@ void env_get_names( array_list_t *l, int flags )
|
||||
static void export_func1( void *k, void *v, void *aux )
|
||||
{
|
||||
var_entry_t *val_entry = (var_entry_t *)v;
|
||||
if( val_entry->export )
|
||||
{
|
||||
hash_table_t *h = (hash_table_t *)aux;
|
||||
|
||||
if( !hash_get( h, k ) )
|
||||
hash_put( h, k, val_entry->val );
|
||||
hash_table_t *h = (hash_table_t *)aux;
|
||||
|
||||
hash_remove( h, k, 0, 0 );
|
||||
|
||||
if( val_entry->export && wcscmp( val_entry->val, ENV_NULL ) )
|
||||
{
|
||||
hash_put( h, k, val_entry->val );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void get_exported( env_node_t *n, hash_table_t *h )
|
||||
{
|
||||
if( !n )
|
||||
return;
|
||||
|
||||
if( n->new_scope )
|
||||
get_exported( global_env, h );
|
||||
else
|
||||
get_exported( n->next, h );
|
||||
|
||||
hash_foreach2( &n->env, &export_func1, h );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Function used by env_export_arr to iterate over hashtable of variables
|
||||
*/
|
||||
@@ -1376,7 +1498,6 @@ char **env_export_arr( int recalc )
|
||||
{
|
||||
array_list_t uni;
|
||||
hash_table_t vals;
|
||||
env_node_t *n=top;
|
||||
int prev_was_null=1;
|
||||
int pos=0;
|
||||
int i;
|
||||
@@ -1385,15 +1506,7 @@ char **env_export_arr( int recalc )
|
||||
|
||||
hash_init( &vals, &hash_wcs_func, &hash_wcs_cmp );
|
||||
|
||||
while( n )
|
||||
{
|
||||
hash_foreach2( &n->env, &export_func1, &vals );
|
||||
|
||||
if( n->new_scope )
|
||||
n = global_env;
|
||||
else
|
||||
n = n->next;
|
||||
}
|
||||
get_exported( top, &vals );
|
||||
|
||||
al_init( &uni );
|
||||
env_universal_get_names( &uni, 1, 0 );
|
||||
@@ -1401,7 +1514,7 @@ char **env_export_arr( int recalc )
|
||||
{
|
||||
wchar_t *key = (wchar_t *)al_get( &uni, i );
|
||||
wchar_t *val = env_universal_get( key );
|
||||
if( !hash_get( &vals, key ) )
|
||||
if( wcscmp( val, ENV_NULL) && !hash_get( &vals, key ) )
|
||||
hash_put( &vals, key, val );
|
||||
}
|
||||
al_destroy( &uni );
|
||||
|
||||
@@ -70,6 +70,11 @@ static int barrier_reply = 0;
|
||||
|
||||
void env_universal_barrier();
|
||||
|
||||
static int is_dead()
|
||||
{
|
||||
return env_universal_server.fd < 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Get a socket for reading from the server
|
||||
@@ -140,18 +145,18 @@ static int get_socket( int fork_ok )
|
||||
return get_socket( 0 );
|
||||
}
|
||||
|
||||
debug( 2, L"Could not connect to socket %d, already tried manual restart (or no command supplied), giving up", s );
|
||||
debug( 1, L"Could not connect to universal variable server, already tried manual restart (or no command supplied). You will not be able to share variable values between fish sessions. Is fish properly installed?" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( fcntl( s, F_SETFL, O_NONBLOCK ) != 0 )
|
||||
if( (fcntl( s, F_SETFL, O_NONBLOCK ) != 0) || (fcntl( s, F_SETFD, FD_CLOEXEC ) != 0) )
|
||||
{
|
||||
wperror( L"fcntl" );
|
||||
close( s );
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
debug( 3, L"Connected to fd %d", s );
|
||||
|
||||
return s;
|
||||
@@ -198,6 +203,31 @@ static void check_connection()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Remove all universal variables.
|
||||
*/
|
||||
static void env_universal_remove_all()
|
||||
{
|
||||
array_list_t lst;
|
||||
int i;
|
||||
|
||||
al_init( &lst );
|
||||
|
||||
env_universal_common_get_names( &lst,
|
||||
1,
|
||||
1 );
|
||||
|
||||
for( i=0; i<al_get_count( &lst ); i++ )
|
||||
{
|
||||
wchar_t *key = (wchar_t *)al_get( &lst, i );
|
||||
env_universal_common_remove( key );
|
||||
}
|
||||
|
||||
al_destroy( &lst );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Try to establish a new connection to fishd. If successfull, end
|
||||
with call to env_universal_barrier(), to make sure everything is in
|
||||
@@ -216,6 +246,7 @@ static void reconnect()
|
||||
init = 1;
|
||||
if( env_universal_server.fd >= 0 )
|
||||
{
|
||||
env_universal_remove_all();
|
||||
env_universal_barrier();
|
||||
}
|
||||
}
|
||||
@@ -317,7 +348,7 @@ void env_universal_barrier()
|
||||
message_t *msg;
|
||||
fd_set fds;
|
||||
|
||||
if( !init || ( env_universal_server.fd == -1 ))
|
||||
if( !init || is_dead() )
|
||||
return;
|
||||
|
||||
barrier_reply = 0;
|
||||
@@ -384,20 +415,27 @@ void env_universal_set( const wchar_t *name, const wchar_t *value, int export )
|
||||
CHECK( name, );
|
||||
|
||||
debug( 3, L"env_universal_set( \"%ls\", \"%ls\" )", name, value );
|
||||
|
||||
msg = create_message( export?SET_EXPORT:SET,
|
||||
name,
|
||||
value);
|
||||
|
||||
if( !msg )
|
||||
if( is_dead() )
|
||||
{
|
||||
debug( 1, L"Could not create universal variable message" );
|
||||
return;
|
||||
env_universal_common_set( name, value, export );
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = create_message( export?SET_EXPORT:SET,
|
||||
name,
|
||||
value);
|
||||
|
||||
if( !msg )
|
||||
{
|
||||
debug( 1, L"Could not create universal variable message" );
|
||||
return;
|
||||
}
|
||||
|
||||
msg->count=1;
|
||||
q_put( &env_universal_server.unsent, msg );
|
||||
env_universal_barrier();
|
||||
}
|
||||
|
||||
msg->count=1;
|
||||
q_put( &env_universal_server.unsent, msg );
|
||||
env_universal_barrier();
|
||||
}
|
||||
|
||||
int env_universal_remove( const wchar_t *name )
|
||||
@@ -411,16 +449,22 @@ int env_universal_remove( const wchar_t *name )
|
||||
CHECK( name, 1 );
|
||||
|
||||
res = !env_universal_common_get( name );
|
||||
|
||||
debug( 3,
|
||||
L"env_universal_remove( \"%ls\" )",
|
||||
name );
|
||||
|
||||
msg= create_message( ERASE, name, 0);
|
||||
msg->count=1;
|
||||
q_put( &env_universal_server.unsent, msg );
|
||||
env_universal_barrier();
|
||||
|
||||
|
||||
if( is_dead() )
|
||||
{
|
||||
env_universal_common_remove( name );
|
||||
}
|
||||
else
|
||||
{
|
||||
msg= create_message( ERASE, name, 0);
|
||||
msg->count=1;
|
||||
q_put( &env_universal_server.unsent, msg );
|
||||
env_universal_barrier();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -430,6 +474,8 @@ void env_universal_get_names( array_list_t *l,
|
||||
{
|
||||
if( !init )
|
||||
return;
|
||||
|
||||
CHECK( l, );
|
||||
|
||||
env_universal_common_get_names( l,
|
||||
show_exported,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/** \file env_universal.h
|
||||
Universal variable client library
|
||||
Universal variable client library.
|
||||
*/
|
||||
|
||||
#ifndef ENV_UNIVERSAL_H
|
||||
|
||||
@@ -423,7 +423,7 @@ void read_message( connection_t *src )
|
||||
/**
|
||||
Remove variable with specified name
|
||||
*/
|
||||
static void remove_entry( wchar_t *name )
|
||||
void env_universal_common_remove( const wchar_t *name )
|
||||
{
|
||||
void *k, *v;
|
||||
hash_remove( &env_universal_var,
|
||||
@@ -449,6 +449,34 @@ static int match( const wchar_t *msg, const wchar_t *cmd )
|
||||
return 1;
|
||||
}
|
||||
|
||||
void env_universal_common_set( const wchar_t *key, const wchar_t *val, int export )
|
||||
{
|
||||
var_uni_entry_t *entry;
|
||||
wchar_t *name;
|
||||
|
||||
CHECK( key, );
|
||||
CHECK( val, );
|
||||
|
||||
entry = malloc( sizeof(var_uni_entry_t) + sizeof(wchar_t)*(wcslen(val)+1) );
|
||||
name = wcsdup(key);
|
||||
|
||||
if( !entry || !name )
|
||||
DIE_MEM();
|
||||
|
||||
entry->export=export;
|
||||
|
||||
wcscpy( entry->val, val );
|
||||
env_universal_common_remove( name );
|
||||
|
||||
hash_put( &env_universal_var, name, entry );
|
||||
|
||||
if( callback )
|
||||
{
|
||||
callback( export?SET_EXPORT:SET, name, val );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Parse message msg
|
||||
*/
|
||||
@@ -462,7 +490,7 @@ static void parse_message( wchar_t *msg,
|
||||
|
||||
if( match( msg, SET_STR ) || match( msg, SET_EXPORT_STR ))
|
||||
{
|
||||
wchar_t *name, *val, *tmp;
|
||||
wchar_t *name, *tmp;
|
||||
int export = match( msg, SET_EXPORT_STR );
|
||||
|
||||
name = msg+(export?wcslen(SET_EXPORT_STR):wcslen(SET_STR));
|
||||
@@ -472,31 +500,20 @@ static void parse_message( wchar_t *msg,
|
||||
tmp = wcschr( name, L':' );
|
||||
if( tmp )
|
||||
{
|
||||
wchar_t *key =malloc( sizeof( wchar_t)*(tmp-name+1));
|
||||
wchar_t *key;
|
||||
wchar_t *val;
|
||||
|
||||
key = malloc( sizeof( wchar_t)*(tmp-name+1));
|
||||
memcpy( key, name, sizeof( wchar_t)*(tmp-name));
|
||||
key[tmp-name]=0;
|
||||
|
||||
val = tmp+1;
|
||||
|
||||
|
||||
val = unescape( val, 0 );
|
||||
|
||||
var_uni_entry_t *entry =
|
||||
malloc( sizeof(var_uni_entry_t) + sizeof(wchar_t)*(wcslen(val)+1) );
|
||||
if( !entry )
|
||||
DIE_MEM();
|
||||
entry->export=export;
|
||||
env_universal_common_set( key, val, export );
|
||||
|
||||
wcscpy( entry->val, val );
|
||||
remove_entry( key );
|
||||
|
||||
hash_put( &env_universal_var, key, entry );
|
||||
|
||||
if( callback )
|
||||
{
|
||||
callback( export?SET_EXPORT:SET, key, val );
|
||||
}
|
||||
free(val );
|
||||
free( val );
|
||||
free( key );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -522,7 +539,7 @@ static void parse_message( wchar_t *msg,
|
||||
debug( 1, PARSE_ERR, msg );
|
||||
}
|
||||
|
||||
remove_entry( name );
|
||||
env_universal_common_remove( name );
|
||||
|
||||
if( callback )
|
||||
{
|
||||
@@ -853,8 +870,16 @@ void connection_destroy( connection_t *c)
|
||||
{
|
||||
q_destroy( &c->unsent );
|
||||
b_destroy( &c->input );
|
||||
if( close( c->fd ) )
|
||||
|
||||
/*
|
||||
A connection need not always be open - we only try to close it
|
||||
if it is open.
|
||||
*/
|
||||
if( c->fd >= 0 )
|
||||
{
|
||||
wperror( L"close" );
|
||||
if( close( c->fd ) )
|
||||
{
|
||||
wperror( L"close" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,19 +143,50 @@ void env_universal_common_destroy();
|
||||
|
||||
/**
|
||||
Add all variable names to the specified list
|
||||
|
||||
This function operate agains the local copy of all universal
|
||||
variables, it does not communicate with any other process.
|
||||
*/
|
||||
void env_universal_common_get_names( array_list_t *l,
|
||||
int show_exported,
|
||||
int show_unexported );
|
||||
|
||||
/**
|
||||
Perform the specified variable assignment.
|
||||
|
||||
This function operate agains the local copy of all universal
|
||||
variables, it does not communicate with any other process.
|
||||
|
||||
Do not call this function. Create a message to do it. This function
|
||||
is only to be used when fishd is dead.
|
||||
*/
|
||||
void env_universal_common_set( const wchar_t *key, const wchar_t *val, int export );
|
||||
|
||||
/**
|
||||
Remove the specified variable.
|
||||
|
||||
This function operate agains the local copy of all universal
|
||||
variables, it does not communicate with any other process.
|
||||
|
||||
Do not call this function. Create a message to do it. This function
|
||||
is only to be used when fishd is dead.
|
||||
*/
|
||||
void env_universal_common_remove( const wchar_t *key );
|
||||
|
||||
/**
|
||||
Get the value of the variable with the specified name
|
||||
|
||||
This function operate agains the local copy of all universal
|
||||
variables, it does not communicate with any other process.
|
||||
*/
|
||||
wchar_t *env_universal_common_get( const wchar_t *name );
|
||||
|
||||
/**
|
||||
Get the export flag of the variable with the specified
|
||||
name. Returns 0 if the variable doesn't exist.
|
||||
|
||||
This function operate agains the local copy of all universal
|
||||
variables, it does not communicate with any other process.
|
||||
*/
|
||||
int env_universal_common_get_export( const wchar_t *name );
|
||||
|
||||
@@ -164,8 +195,17 @@ int env_universal_common_get_export( const wchar_t *name );
|
||||
*/
|
||||
void enqueue_all( connection_t *c );
|
||||
|
||||
/**
|
||||
Fill in the specified connection_t struct. Use the specified file
|
||||
descriptor for communication.
|
||||
*/
|
||||
void connection_init( connection_t *c, int fd );
|
||||
|
||||
/**
|
||||
Close and destroy the specified connection struct. This frees
|
||||
allstructures allocated by the connection, such as ques of unsent
|
||||
messages.
|
||||
*/
|
||||
void connection_destroy( connection_t *c);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
476
exec.c
476
exec.c
@@ -22,6 +22,7 @@
|
||||
#include <sys/wait.h>
|
||||
#include <assert.h>
|
||||
#include <dirent.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef HAVE_SIGINFO_H
|
||||
#include <siginfo.h>
|
||||
@@ -42,20 +43,11 @@
|
||||
#include "sanity.h"
|
||||
#include "expand.h"
|
||||
#include "signal.h"
|
||||
#include "env_universal.h"
|
||||
|
||||
#include "halloc.h"
|
||||
#include "halloc_util.h"
|
||||
#include "parse_util.h"
|
||||
|
||||
/**
|
||||
Prototype for the getpgid library function. The prototype for this
|
||||
function seems to be missing in glibc, at least I've not found any
|
||||
combination of includes, macros and compiler switches that will
|
||||
include it.
|
||||
*/
|
||||
pid_t getpgid( pid_t pid );
|
||||
|
||||
/**
|
||||
file descriptor redirection error message
|
||||
*/
|
||||
@@ -69,10 +61,20 @@ pid_t getpgid( pid_t pid );
|
||||
*/
|
||||
#define FORK_ERROR _( L"Could not create child process - exiting" )
|
||||
|
||||
/**
|
||||
The number of times to try to call fork() before giving up
|
||||
*/
|
||||
#define FORK_LAPS 5
|
||||
|
||||
/**
|
||||
The number of nanoseconds to sleep between attempts to call fork()
|
||||
*/
|
||||
#define FORK_SLEEP_TIME 1000000
|
||||
|
||||
/**
|
||||
Base open mode to pass to calls to open
|
||||
*/
|
||||
#define BASE_MASK 0666
|
||||
#define OPEN_MASK 0666
|
||||
|
||||
/**
|
||||
List of all pipes used by internal pipes. These must be closed in
|
||||
@@ -86,6 +88,12 @@ static int set_child_group( job_t *j, process_t *p, int print_errors );
|
||||
void exec_close( int fd )
|
||||
{
|
||||
int i;
|
||||
|
||||
if( fd < 0 )
|
||||
{
|
||||
debug( 0, L"Called close on invalid file descriptor " );
|
||||
return;
|
||||
}
|
||||
|
||||
while( close(fd) == -1 )
|
||||
{
|
||||
@@ -113,7 +121,6 @@ void exec_close( int fd )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int exec_pipe( int fd[2])
|
||||
@@ -201,7 +208,7 @@ void free_fd( io_data_t *io, int fd )
|
||||
if( !io )
|
||||
return;
|
||||
|
||||
if( io->io_mode == IO_PIPE )
|
||||
if( ( io->io_mode == IO_PIPE ) || ( io->io_mode == IO_BUFFER ) )
|
||||
{
|
||||
int i;
|
||||
for( i=0; i<2; i++ )
|
||||
@@ -212,21 +219,24 @@ void free_fd( io_data_t *io, int fd )
|
||||
{
|
||||
if( (io->param1.pipe_fd[i] = dup(fd)) == -1)
|
||||
{
|
||||
if( errno != EINTR )
|
||||
if( errno != EINTR )
|
||||
{
|
||||
debug( 1,
|
||||
FD_ERROR,
|
||||
fd );
|
||||
wperror( L"dup" );
|
||||
exit(1);
|
||||
FATAL_EXIT();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free_fd( io->next, fd );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -238,11 +248,10 @@ void free_fd( io_data_t *io, int fd )
|
||||
redirections described by \c io.
|
||||
|
||||
\param io the list of IO redirections for the child
|
||||
\param exit_on_error whether to call exit() on errors
|
||||
|
||||
\return 0 on sucess, -1 on failiure
|
||||
*/
|
||||
static int handle_child_io( io_data_t *io, int exit_on_error )
|
||||
static int handle_child_io( io_data_t *io )
|
||||
{
|
||||
|
||||
close_unused_internal_pipes( io );
|
||||
@@ -267,31 +276,27 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
|
||||
switch( io->io_mode )
|
||||
{
|
||||
case IO_CLOSE:
|
||||
{
|
||||
if( close(io->fd) )
|
||||
{
|
||||
debug( 0, _(L"Failed to close file descriptor %d"), io->fd );
|
||||
wperror( L"close" );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case IO_FILE:
|
||||
{
|
||||
if( (tmp=wopen( io->param1.filename,
|
||||
io->param2.flags, BASE_MASK ) )==-1 )
|
||||
io->param2.flags, OPEN_MASK ) )==-1 )
|
||||
{
|
||||
debug( 1,
|
||||
FILE_ERROR,
|
||||
io->param1.filename );
|
||||
|
||||
wperror( L"open" );
|
||||
if( exit_on_error )
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
else if( tmp != io->fd)
|
||||
{
|
||||
/*
|
||||
@@ -306,14 +311,7 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
|
||||
FD_ERROR,
|
||||
io->fd );
|
||||
wperror( L"dup2" );
|
||||
if( exit_on_error )
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
exec_close( tmp );
|
||||
}
|
||||
@@ -334,14 +332,7 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
|
||||
FD_ERROR,
|
||||
io->fd );
|
||||
wperror( L"dup2" );
|
||||
if( exit_on_error )
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -349,30 +340,26 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
|
||||
case IO_BUFFER:
|
||||
case IO_PIPE:
|
||||
{
|
||||
int fd_to_dup = io->fd;
|
||||
|
||||
/*
|
||||
This call will sometimes fail, but that is ok,
|
||||
this is just a precausion.
|
||||
*/
|
||||
close(io->fd);
|
||||
int write_pipe;
|
||||
|
||||
if( dup2( io->param1.pipe_fd[fd_to_dup?1:0], io->fd ) == -1 )
|
||||
write_pipe = !io->is_input;
|
||||
/*
|
||||
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->param1.pipe_fd[0],
|
||||
io->param1.pipe_fd[1]);
|
||||
*/
|
||||
if( dup2( io->param1.pipe_fd[write_pipe], io->fd ) != io->fd )
|
||||
{
|
||||
debug( 1, PIPE_ERROR );
|
||||
wperror( L"dup2" );
|
||||
if( exit_on_error )
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( fd_to_dup != 0 )
|
||||
if( write_pipe )
|
||||
{
|
||||
exec_close( io->param1.pipe_fd[0]);
|
||||
exec_close( io->param1.pipe_fd[1]);
|
||||
@@ -381,31 +368,31 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
|
||||
{
|
||||
exec_close( io->param1.pipe_fd[0] );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if( env_universal_server.fd >= 0 )
|
||||
exec_close( env_universal_server.fd );
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Initialize a new child process. This should be called right away
|
||||
after forking in the child process. If job control is suitable, the
|
||||
process is put in the jobs group, all signal handlers are reset,
|
||||
SIGCHLD is unblocked (the exec call blocks blocks SIGCHLD), and all
|
||||
IO redirections and other file descriptor actions are performed.
|
||||
after forking in the child process. If job control is enabled for
|
||||
this job, the process is put in the process group of the job, all
|
||||
signal handlers are reset, signals are unblocked (this function may
|
||||
only be called inside the exec function, which blocks all signals),
|
||||
and all IO redirections and other file descriptor actions are
|
||||
performed.
|
||||
|
||||
\param j the job to set up the IO for
|
||||
\param p the child process to set up
|
||||
|
||||
\return 0 on sucess, -1 on failiure
|
||||
\return 0 on sucess, -1 on failiure. When this function returns,
|
||||
signals are always unblocked. On failiure, signal handlers, io
|
||||
redirections and process group of the process is undefined.
|
||||
*/
|
||||
static int setup_child_process( job_t *j, process_t *p )
|
||||
{
|
||||
@@ -418,7 +405,11 @@ static int setup_child_process( job_t *j, process_t *p )
|
||||
|
||||
if( !res )
|
||||
{
|
||||
res = handle_child_io( j->io, (p!=0) );
|
||||
res = handle_child_io( j->io );
|
||||
if( p != 0 && res )
|
||||
{
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the handling for job control signals back to the default. */
|
||||
@@ -443,16 +434,67 @@ static int setup_child_process( job_t *j, process_t *p )
|
||||
*/
|
||||
static void launch_process( process_t *p )
|
||||
{
|
||||
FILE* f;
|
||||
int err;
|
||||
|
||||
// debug( 1, L"exec '%ls'", p->argv[0] );
|
||||
|
||||
|
||||
execve ( wcs2str(p->actual_cmd),
|
||||
wcsv2strv( (const wchar_t **) p->argv),
|
||||
env_export_arr( 0 ) );
|
||||
|
||||
err = errno;
|
||||
|
||||
/*
|
||||
Something went wrong with execve, check for a ":", and run
|
||||
/bin/sh if encountered. This is a weird predecessor to the shebang
|
||||
that is still sometimes used since it is supported on Windows.
|
||||
*/
|
||||
f = wfopen(p->actual_cmd, "r");
|
||||
if( f )
|
||||
{
|
||||
char begin[1] = {0};
|
||||
size_t read;
|
||||
|
||||
read = fread(begin, 1, 1, f);
|
||||
fclose( f );
|
||||
|
||||
if( (read==1) && (begin[0] == ':') )
|
||||
{
|
||||
int count = 0;
|
||||
int i = 1;
|
||||
wchar_t **res;
|
||||
|
||||
while( p->argv[count] != 0 )
|
||||
count++;
|
||||
|
||||
res = malloc( sizeof(wchar_t*)*(count+2));
|
||||
|
||||
res[0] = L"/bin/sh";
|
||||
res[1] = p->actual_cmd;
|
||||
|
||||
for( i=1; p->argv[i]; i++ ){
|
||||
res[i+1] = p->argv[i];
|
||||
}
|
||||
|
||||
res[i+1] = 0;
|
||||
p->argv = res;
|
||||
p->actual_cmd = L"/bin/sh";
|
||||
|
||||
execve ( wcs2str(p->actual_cmd),
|
||||
wcsv2strv( (const wchar_t **) p->argv),
|
||||
env_export_arr( 0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
debug( 0,
|
||||
_( L"Failed to execute process '%ls'" ),
|
||||
p->actual_cmd );
|
||||
|
||||
errno = err;
|
||||
|
||||
wperror( L"execve" );
|
||||
exit(1);
|
||||
FATAL_EXIT();
|
||||
}
|
||||
|
||||
|
||||
@@ -490,7 +532,8 @@ static void io_untransmogrify( io_data_t * in, io_data_t *out )
|
||||
Make a copy of the specified io redirection chain, but change file
|
||||
redirection into fd redirection. This makes the redirection chain
|
||||
suitable for use as block-level io, since the file won't be
|
||||
repeatedly reopened for every command in the block.
|
||||
repeatedly reopened for every command in the block, which would
|
||||
reset the cursor position.
|
||||
|
||||
\return the transmogrified chain on sucess, or 0 on failiure
|
||||
*/
|
||||
@@ -531,7 +574,7 @@ static io_data_t *io_transmogrify( io_data_t * in )
|
||||
{
|
||||
int fd;
|
||||
|
||||
if( (fd=wopen( in->param1.filename, in->param2.flags, BASE_MASK ) )==-1 )
|
||||
if( (fd=wopen( in->param1.filename, in->param2.flags, OPEN_MASK ) )==-1 )
|
||||
{
|
||||
debug( 1,
|
||||
FILE_ERROR,
|
||||
@@ -657,6 +700,75 @@ static int set_child_group( job_t *j, process_t *p, int print_errors )
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
This function is a wrapper around fork. If the fork calls fails
|
||||
with EAGAIN, it is retried FORK_LAPS times, with a very slight
|
||||
delay between each lap. If fork fails even then, the process will
|
||||
exit with an error message.
|
||||
*/
|
||||
static pid_t exec_fork()
|
||||
{
|
||||
pid_t pid;
|
||||
struct timespec pollint;
|
||||
int i;
|
||||
|
||||
for( i=0; i<FORK_LAPS; i++ )
|
||||
{
|
||||
pid = fork();
|
||||
if( pid >= 0)
|
||||
{
|
||||
return pid;
|
||||
}
|
||||
|
||||
if( errno != EAGAIN )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
pollint.tv_sec = 0;
|
||||
pollint.tv_nsec = FORK_SLEEP_TIME;
|
||||
|
||||
/*
|
||||
Don't sleep on the final lap - sleeping might change the
|
||||
value of errno, which will break the error reporting below.
|
||||
*/
|
||||
if( i != FORK_LAPS-1 )
|
||||
{
|
||||
nanosleep( &pollint, NULL );
|
||||
}
|
||||
}
|
||||
|
||||
debug( 0, FORK_ERROR );
|
||||
wperror (L"fork");
|
||||
FATAL_EXIT();
|
||||
}
|
||||
|
||||
|
||||
static void do_builtin_io( wchar_t *out, wchar_t *err )
|
||||
{
|
||||
|
||||
if( out )
|
||||
{
|
||||
if( fwprintf( stdout, L"%ls", out ) == -1 || fflush( stdout ) == EOF )
|
||||
{
|
||||
debug( 0, L"Error while writing to stdout" );
|
||||
wperror( L"fwprintf" );
|
||||
show_stackframe();
|
||||
}
|
||||
}
|
||||
|
||||
if( err )
|
||||
{
|
||||
if( fwprintf( stderr, L"%ls", err ) == -1 || fflush( stderr ) == EOF )
|
||||
{
|
||||
/*
|
||||
Can't really show any error message here, since stderr is
|
||||
dead.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void exec( job_t *j )
|
||||
@@ -673,7 +785,8 @@ void exec( job_t *j )
|
||||
io_data_t *io_buffer =0;
|
||||
|
||||
/*
|
||||
Set to 1 if something goes wrong while exec:ing the job, in which case the cleanup code will kick in.
|
||||
Set to 1 if something goes wrong while exec:ing the job, in
|
||||
which case the cleanup code will kick in.
|
||||
*/
|
||||
int exec_error=0;
|
||||
|
||||
@@ -695,29 +808,37 @@ void exec( job_t *j )
|
||||
if( block_io )
|
||||
{
|
||||
if( j->io )
|
||||
{
|
||||
j->io = io_add( io_duplicate( j, block_io), j->io );
|
||||
}
|
||||
else
|
||||
{
|
||||
j->io=io_duplicate( j, block_io);
|
||||
}
|
||||
}
|
||||
|
||||
io_data_t *input_redirect = io_get( j->io, 0 );
|
||||
|
||||
if( input_redirect &&
|
||||
(input_redirect->io_mode == IO_BUFFER) &&
|
||||
input_redirect->is_input )
|
||||
{
|
||||
/*
|
||||
Input redirection - create a new gobetween process to take
|
||||
care of buffering
|
||||
*/
|
||||
|
||||
process_t *fake = halloc( j, sizeof(process_t) );
|
||||
fake->type = INTERNAL_BUFFER;
|
||||
fake->pipe_fd = 1;
|
||||
fake->next = j->first_process;
|
||||
j->first_process = fake;
|
||||
}
|
||||
io_data_t *input_redirect;
|
||||
|
||||
for( input_redirect = j->io; input_redirect; input_redirect = input_redirect->next )
|
||||
{
|
||||
if( (input_redirect->io_mode == IO_BUFFER) &&
|
||||
input_redirect->is_input )
|
||||
{
|
||||
/*
|
||||
Input redirection - create a new gobetween process to take
|
||||
care of buffering
|
||||
*/
|
||||
process_t *fake = halloc( j, sizeof(process_t) );
|
||||
fake->type = INTERNAL_BUFFER;
|
||||
fake->pipe_write_fd = 1;
|
||||
j->first_process->pipe_read_fd = input_redirect->fd;
|
||||
fake->next = j->first_process;
|
||||
j->first_process = fake;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( j->first_process->type==INTERNAL_EXEC )
|
||||
{
|
||||
/*
|
||||
@@ -732,7 +853,7 @@ void exec( job_t *j )
|
||||
if( !setup_child_process( j, 0 ) )
|
||||
{
|
||||
/*
|
||||
launch_process never returns
|
||||
launch_process _never_ returns
|
||||
*/
|
||||
launch_process( j->first_process );
|
||||
}
|
||||
@@ -750,14 +871,13 @@ void exec( job_t *j )
|
||||
pipe_read.io_mode=IO_PIPE;
|
||||
pipe_read.param1.pipe_fd[0] = -1;
|
||||
pipe_read.param1.pipe_fd[1] = -1;
|
||||
pipe_read.is_input = 1;
|
||||
|
||||
pipe_write.io_mode=IO_PIPE;
|
||||
pipe_write.is_input = 0;
|
||||
pipe_read.next=0;
|
||||
pipe_write.next=0;
|
||||
pipe_write.param1.pipe_fd[0]=pipe_write.param1.pipe_fd[1]=-1;
|
||||
|
||||
|
||||
|
||||
//fwprintf( stderr, L"Run command %ls\n", j->command );
|
||||
pipe_write.param1.pipe_fd[0]=pipe_write.param1.pipe_fd[1]=-1;
|
||||
|
||||
j->io = io_add( j->io, &pipe_write );
|
||||
|
||||
@@ -788,7 +908,7 @@ void exec( job_t *j )
|
||||
|
||||
if( needs_keepalive )
|
||||
{
|
||||
keepalive.pid = fork();
|
||||
keepalive.pid = exec_fork();
|
||||
|
||||
if( keepalive.pid == 0 )
|
||||
{
|
||||
@@ -797,13 +917,6 @@ void exec( job_t *j )
|
||||
pause();
|
||||
exit(0);
|
||||
}
|
||||
else if( keepalive.pid < 0 )
|
||||
{
|
||||
/* The fork failed. */
|
||||
debug( 0, FORK_ERROR );
|
||||
wperror (L"fork");
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_child_group( j, &keepalive, 0 );
|
||||
@@ -823,13 +936,19 @@ void exec( job_t *j )
|
||||
mypipe[1]=-1;
|
||||
skip_fork=0;
|
||||
|
||||
pipe_write.fd = p->pipe_fd;
|
||||
pipe_write.fd = p->pipe_write_fd;
|
||||
pipe_read.fd = p->pipe_read_fd;
|
||||
// debug( 0, L"Pipe created from fd %d to fd %d", pipe_write.fd, pipe_read.fd );
|
||||
|
||||
|
||||
/*
|
||||
This call is used so the global environment variable array is
|
||||
regenerated, if needed, before the fork. That way, we avoid a
|
||||
lot of duplicate work where EVERY child would need to generate
|
||||
it
|
||||
This call is used so the global environment variable array
|
||||
is regenerated, if needed, before the fork. That way, we
|
||||
avoid a lot of duplicate work where EVERY child would need
|
||||
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( 1 );
|
||||
@@ -875,6 +994,12 @@ void exec( job_t *j )
|
||||
const wchar_t * orig_def;
|
||||
wchar_t * def=0;
|
||||
|
||||
/*
|
||||
Calls to function_get_definition might need to
|
||||
source a file as a part of autoloading, hence there
|
||||
must be no blocks.
|
||||
*/
|
||||
|
||||
signal_unblock();
|
||||
orig_def = function_get_definition( p->argv[0] );
|
||||
signal_block();
|
||||
@@ -930,7 +1055,12 @@ void exec( job_t *j )
|
||||
int builtin_stdin=0;
|
||||
int fg;
|
||||
int close_stdin=0;
|
||||
|
||||
|
||||
/*
|
||||
If this is the first process, check the io
|
||||
redirections and see where we should be reading
|
||||
from.
|
||||
*/
|
||||
if( p == j->first_process )
|
||||
{
|
||||
io_data_t *in = io_get( j->io, 0 );
|
||||
@@ -954,7 +1084,7 @@ void exec( job_t *j )
|
||||
case IO_FILE:
|
||||
{
|
||||
builtin_stdin=wopen( in->param1.filename,
|
||||
in->param2.flags, BASE_MASK );
|
||||
in->param2.flags, OPEN_MASK );
|
||||
if( builtin_stdin == -1 )
|
||||
{
|
||||
debug( 1,
|
||||
@@ -994,16 +1124,29 @@ void exec( job_t *j )
|
||||
}
|
||||
else
|
||||
{
|
||||
builtin_push_io( builtin_stdin );
|
||||
|
||||
int old_out = builtin_out_redirect;
|
||||
int old_err = builtin_err_redirect;
|
||||
|
||||
/*
|
||||
Since this may be the foreground job, and since a
|
||||
builtin may execute another foreground job, we need to
|
||||
pretend to suspend this job while running the builtin.
|
||||
Since this may be the foreground job, and since
|
||||
a builtin may execute another foreground job,
|
||||
we need to pretend to suspend this job while
|
||||
running the builtin, in order to avoid a
|
||||
situation where two jobs are running at once.
|
||||
|
||||
The reason this is done here, and not by the
|
||||
relevant builtins, is that this 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.
|
||||
*/
|
||||
|
||||
builtin_push_io( builtin_stdin );
|
||||
|
||||
builtin_out_redirect = has_fd( j->io, 1 );
|
||||
builtin_err_redirect = has_fd( j->io, 2 );
|
||||
|
||||
fg = job_get_flag( j, JOB_FOREGROUND );
|
||||
job_set_flag( j, JOB_FOREGROUND, 0 );
|
||||
|
||||
@@ -1011,6 +1154,9 @@ void exec( job_t *j )
|
||||
|
||||
p->status = builtin_run( p->argv );
|
||||
|
||||
builtin_out_redirect=old_out;
|
||||
builtin_err_redirect=old_err;
|
||||
|
||||
signal_block();
|
||||
|
||||
/*
|
||||
@@ -1021,6 +1167,10 @@ void exec( job_t *j )
|
||||
job_set_flag( j, JOB_FOREGROUND, fg );
|
||||
}
|
||||
|
||||
/*
|
||||
If stdin has been redirected, close the redirection
|
||||
stream.
|
||||
*/
|
||||
if( close_stdin )
|
||||
{
|
||||
exec_close( builtin_stdin );
|
||||
@@ -1030,8 +1180,10 @@ void exec( job_t *j )
|
||||
}
|
||||
|
||||
if( exec_error )
|
||||
{
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
switch( p->type )
|
||||
{
|
||||
|
||||
@@ -1066,7 +1218,7 @@ void exec( job_t *j )
|
||||
|
||||
if( io_buffer->param2.out_buffer->used != 0 )
|
||||
{
|
||||
pid = fork();
|
||||
pid = exec_fork();
|
||||
|
||||
if( pid == 0 )
|
||||
{
|
||||
@@ -1080,13 +1232,6 @@ void exec( job_t *j )
|
||||
io_buffer->param2.out_buffer->used );
|
||||
exit( status );
|
||||
}
|
||||
else if( pid < 0 )
|
||||
{
|
||||
/* The fork failed. */
|
||||
debug( 0, FORK_ERROR );
|
||||
wperror (L"fork");
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
@@ -1120,12 +1265,13 @@ void exec( job_t *j )
|
||||
case INTERNAL_BUFFER:
|
||||
{
|
||||
|
||||
pid = fork();
|
||||
pid = exec_fork();
|
||||
|
||||
if( pid == 0 )
|
||||
{
|
||||
/*
|
||||
This is the child process. Write out the contents of the pipeline.
|
||||
This is the child process. Write out the
|
||||
contents of the pipeline.
|
||||
*/
|
||||
p->pid = getpid();
|
||||
setup_child_process( j, p );
|
||||
@@ -1135,13 +1281,6 @@ void exec( job_t *j )
|
||||
input_redirect->param2.out_buffer->used );
|
||||
exit( 0 );
|
||||
}
|
||||
else if( pid < 0 )
|
||||
{
|
||||
/* The fork failed. */
|
||||
debug( 0, FORK_ERROR );
|
||||
wperror (L"fork");
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
@@ -1161,7 +1300,17 @@ void exec( job_t *j )
|
||||
int skip_fork=0;
|
||||
|
||||
/*
|
||||
If a builtin didn't produce any output, and it is not inside a pipeline, there is no need to fork
|
||||
Handle output from builtin commands. In the general
|
||||
case, this means forking of a worker process, that
|
||||
will write out the contents of the stdout and stderr
|
||||
buffers to the correct file descriptor. Since
|
||||
forking is expensive, fish tries to avoid it wehn
|
||||
possible.
|
||||
*/
|
||||
|
||||
/*
|
||||
If a builtin didn't produce any output, and it is
|
||||
not inside a pipeline, there is no need to fork
|
||||
*/
|
||||
skip_fork =
|
||||
( !sb_out->used ) &&
|
||||
@@ -1198,10 +1347,13 @@ void exec( job_t *j )
|
||||
proc_set_last_status( job_get_flag( j, JOB_NEGATE )?(!p->status):p->status );
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
pid = fork();
|
||||
|
||||
/*
|
||||
Ok, unfortunatly, we have to do a real fork. Bummer.
|
||||
*/
|
||||
|
||||
pid = exec_fork();
|
||||
if( pid == 0 )
|
||||
{
|
||||
|
||||
@@ -1210,24 +1362,13 @@ void exec( job_t *j )
|
||||
print correct output to stdout and stderr, and
|
||||
then exit.
|
||||
*/
|
||||
|
||||
p->pid = getpid();
|
||||
setup_child_process( j, p );
|
||||
if( sb_out->used )
|
||||
fwprintf( stdout, L"%ls", sb_out->buff );
|
||||
if( sb_err->used )
|
||||
fwprintf( stderr, L"%ls", sb_err->buff );
|
||||
do_builtin_io( sb_out->used ? (wchar_t *)sb_out->buff : 0, sb_err->used ? (wchar_t *)sb_err->buff : 0 );
|
||||
|
||||
exit( p->status );
|
||||
|
||||
}
|
||||
else if( pid < 0 )
|
||||
{
|
||||
/* The fork failed. */
|
||||
debug( 0, FORK_ERROR );
|
||||
wperror (L"fork");
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
@@ -1246,7 +1387,7 @@ void exec( job_t *j )
|
||||
|
||||
case EXTERNAL:
|
||||
{
|
||||
pid = fork();
|
||||
pid = exec_fork();
|
||||
if( pid == 0 )
|
||||
{
|
||||
/*
|
||||
@@ -1260,13 +1401,6 @@ void exec( job_t *j )
|
||||
launch_process _never_ returns...
|
||||
*/
|
||||
}
|
||||
else if( pid < 0 )
|
||||
{
|
||||
/* The fork failed. */
|
||||
debug( 0, FORK_ERROR );
|
||||
wperror( L"fork" );
|
||||
exit( 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
@@ -1288,12 +1422,14 @@ void exec( job_t *j )
|
||||
builtin_pop_io();
|
||||
|
||||
/*
|
||||
Close the pipe the current process uses to read from the previous process_t
|
||||
Close the pipe the current process uses to read from the
|
||||
previous process_t
|
||||
*/
|
||||
if( pipe_read.param1.pipe_fd[0] >= 0 )
|
||||
exec_close( pipe_read.param1.pipe_fd[0] );
|
||||
/*
|
||||
Set up the pipe the next process uses to read from the current process_t
|
||||
Set up the pipe the next process uses to read from the
|
||||
current process_t
|
||||
*/
|
||||
if( p->next )
|
||||
pipe_read.param1.pipe_fd[0] = mypipe[0];
|
||||
@@ -1344,7 +1480,7 @@ void exec( job_t *j )
|
||||
}
|
||||
|
||||
int exec_subshell( const wchar_t *cmd,
|
||||
array_list_t *l )
|
||||
array_list_t *lst )
|
||||
{
|
||||
char *begin, *end;
|
||||
char z=0;
|
||||
@@ -1352,14 +1488,8 @@ int exec_subshell( const wchar_t *cmd,
|
||||
int status, prev_status;
|
||||
io_data_t *io_buffer;
|
||||
|
||||
if( !cmd )
|
||||
{
|
||||
debug( 1,
|
||||
_( L"Sent null command to subshell. This is a fish bug. If it can be reproduced, please send a bug report to %s." ),
|
||||
PACKAGE_BUGREPORT );
|
||||
return -1;
|
||||
}
|
||||
|
||||
CHECK( cmd, -1 );
|
||||
|
||||
is_subshell=1;
|
||||
io_buffer= io_buffer_create( 0 );
|
||||
|
||||
@@ -1384,7 +1514,7 @@ int exec_subshell( const wchar_t *cmd,
|
||||
|
||||
begin=end=io_buffer->param2.out_buffer->buff;
|
||||
|
||||
if( l )
|
||||
if( lst )
|
||||
{
|
||||
while( 1 )
|
||||
{
|
||||
@@ -1397,7 +1527,7 @@ int exec_subshell( const wchar_t *cmd,
|
||||
wchar_t *el = str2wcs( begin );
|
||||
if( el )
|
||||
{
|
||||
al_push( l, el );
|
||||
al_push( lst, el );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1415,7 +1545,7 @@ int exec_subshell( const wchar_t *cmd,
|
||||
el = str2wcs( begin );
|
||||
if( el )
|
||||
{
|
||||
al_push( l, el );
|
||||
al_push( lst, el );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
67
expand.c
67
expand.c
@@ -272,16 +272,18 @@ static int iswnumeric( const wchar_t *n )
|
||||
*/
|
||||
static int match_pid( const wchar_t *cmd,
|
||||
const wchar_t *proc,
|
||||
int flags )
|
||||
int flags,
|
||||
int *offset)
|
||||
{
|
||||
/* Test for direct match */
|
||||
|
||||
|
||||
if( wcsncmp( cmd, proc, wcslen( proc ) ) == 0 )
|
||||
{
|
||||
if( offset )
|
||||
*offset = 0;
|
||||
return 1;
|
||||
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Test if the commandline is a path to the command, if so we try
|
||||
to match against only the command part
|
||||
@@ -309,7 +311,11 @@ static int match_pid( const wchar_t *cmd,
|
||||
|
||||
if( wcsncmp( start+1, proc, wcslen( proc ) ) == 0 )
|
||||
{
|
||||
if( offset )
|
||||
*offset = start+1-first_token;
|
||||
|
||||
free( first_token );
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -381,8 +387,12 @@ static int find_process( const wchar_t *proc,
|
||||
else
|
||||
{
|
||||
|
||||
int jid = wcstol( proc, 0, 10 );
|
||||
if( jid > 0 )
|
||||
int jid;
|
||||
wchar_t *end;
|
||||
|
||||
errno = 0;
|
||||
jid = wcstol( proc, &end, 10 );
|
||||
if( jid > 0 && !errno && !*end )
|
||||
{
|
||||
j = job_get( jid );
|
||||
if( (j != 0) && (j->command != 0 ) )
|
||||
@@ -403,14 +413,16 @@ static int find_process( const wchar_t *proc,
|
||||
|
||||
for( j=first_job; j != 0; j=j->next )
|
||||
{
|
||||
int offset;
|
||||
|
||||
if( j->command == 0 )
|
||||
continue;
|
||||
|
||||
if( match_pid( j->command, proc, flags ) )
|
||||
|
||||
if( match_pid( j->command, proc, flags, &offset ) )
|
||||
{
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
{
|
||||
wchar_t *res = wcsdupcat2( j->command + wcslen(proc),
|
||||
wchar_t *res = wcsdupcat2( j->command + offset + wcslen(proc),
|
||||
COMPLETE_SEP_STR,
|
||||
COMPLETE_JOB_DESC,
|
||||
(void *)0 );
|
||||
@@ -438,15 +450,16 @@ static int find_process( const wchar_t *proc,
|
||||
continue;
|
||||
for( p=j->first_process; p; p=p->next )
|
||||
{
|
||||
|
||||
int offset;
|
||||
|
||||
if( p->actual_cmd == 0 )
|
||||
continue;
|
||||
|
||||
if( match_pid( p->actual_cmd, proc, flags ) )
|
||||
if( match_pid( p->actual_cmd, proc, flags, &offset ) )
|
||||
{
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
{
|
||||
wchar_t *res = wcsdupcat2( p->actual_cmd + wcslen(proc),
|
||||
wchar_t *res = wcsdupcat2( p->actual_cmd + offset + wcslen(proc),
|
||||
COMPLETE_SEP_STR,
|
||||
COMPLETE_CHILD_PROCESS_DESC,
|
||||
(void *)0);
|
||||
@@ -556,16 +569,19 @@ static int find_process( const wchar_t *proc,
|
||||
|
||||
if( cmd != 0 )
|
||||
{
|
||||
if( match_pid( cmd, proc, flags ) )
|
||||
int offset;
|
||||
|
||||
if( match_pid( cmd, proc, flags, &offset ) )
|
||||
{
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
{
|
||||
wchar_t *res = wcsdupcat2( cmd + wcslen(proc),
|
||||
wchar_t *res = wcsdupcat2( cmd + offset + wcslen(proc),
|
||||
COMPLETE_SEP_STR,
|
||||
COMPLETE_PROCESS_DESC,
|
||||
(void *)0);
|
||||
if( res )
|
||||
al_push( out, res );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1568,8 +1584,14 @@ int expand_string( void *context,
|
||||
{
|
||||
wchar_t *next;
|
||||
|
||||
next = expand_unescape( (wchar_t *)al_get( in, i ),
|
||||
1);
|
||||
/*
|
||||
We accept incomplete strings here, since complete uses
|
||||
expand_string to expand incomplete strings from the
|
||||
commandline.
|
||||
*/
|
||||
int unescape_flags = UNESCAPE_SPECIAL | UNESCAPE_INCOMPLETE;
|
||||
|
||||
next = expand_unescape( (wchar_t *)al_get( in, i ), unescape_flags );
|
||||
|
||||
free( (void *)al_get( in, i ) );
|
||||
|
||||
@@ -1731,6 +1753,15 @@ int expand_string( void *context,
|
||||
al_truncate( out, 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
case -1:
|
||||
{
|
||||
al_foreach( out, &free );
|
||||
al_destroy( in );
|
||||
al_destroy( out );
|
||||
return EXPAND_ERROR;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
19
fallback.c
19
fallback.c
@@ -47,6 +47,12 @@
|
||||
#include "util.h"
|
||||
|
||||
|
||||
#ifndef HAVE___ENVIRON
|
||||
|
||||
char **__environ = 0;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TPUTS_KLUDGE
|
||||
|
||||
int tputs(const char *str, int affcnt, int (*fish_putc)(tputs_arg_t))
|
||||
@@ -1091,3 +1097,16 @@ int getopt_long( int argc,
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_BACKTRACE
|
||||
int backtrace (void **buffer, int size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_BACKTRACE_SYMBOLS
|
||||
char ** backtrace_symbols (void *const *buffer, int size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -150,11 +150,18 @@ fi
|
||||
%dir %_datadir/fish/functions
|
||||
%_datadir/fish/functions/*.fish
|
||||
|
||||
# Documentation for builtins and shellscript functions
|
||||
%dir %_datadir/fish/man
|
||||
%_datadir/fish/man/*.1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
%changelog
|
||||
* Thu Feb 8 2007 Axel Liljencrantz<axel@liljencrantz.se> 1.22.3-0
|
||||
- Tell rpm about the help pages in %_datadir/fish/man/
|
||||
|
||||
* Sat Oct 14 2006 Axel Liljencrantz<axel@liljencrantz.se> 1.22.0-0
|
||||
- Update names of various configuration files
|
||||
|
||||
|
||||
410
fish_pager.c
410
fish_pager.c
@@ -42,6 +42,11 @@
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "fallback.h"
|
||||
#include "util.h"
|
||||
@@ -54,6 +59,7 @@
|
||||
#include "env_universal.h"
|
||||
#include "halloc.h"
|
||||
#include "halloc_util.h"
|
||||
#include "print_help.h"
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -92,7 +98,7 @@ enum
|
||||
;
|
||||
|
||||
/**
|
||||
The minimum number of columns the terminal may have for fish_pager to not refuse showing the completions
|
||||
The minimum width (in characters) the terminal may have for fish_pager to not refuse showing the completions
|
||||
*/
|
||||
#define PAGER_MIN_WIDTH 16
|
||||
|
||||
@@ -101,11 +107,20 @@ enum
|
||||
*/
|
||||
#define PAGER_MAX_COLS 6
|
||||
|
||||
/**
|
||||
The string describing the single-character options accepted by fish_pager
|
||||
*/
|
||||
#define GETOPT_STRING "c:hr:qvp:"
|
||||
|
||||
/**
|
||||
Error to use when given an invalid file descriptor for reading completions or writing output
|
||||
*/
|
||||
#define ERR_NOT_FD _( L"%ls: Argument '%s' is not a valid file descriptor\n" )
|
||||
|
||||
/**
|
||||
This struct should be continually updated by signals as the term
|
||||
resizes, and as such always contain the correct current size.
|
||||
*/
|
||||
|
||||
static struct winsize termsize;
|
||||
|
||||
/**
|
||||
@@ -151,7 +166,7 @@ static FILE *out_file;
|
||||
|
||||
/**
|
||||
Data structure describing one or a group of related completions
|
||||
*/
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
@@ -603,8 +618,22 @@ static int completion_try_print( int cols,
|
||||
( pref_tot_width-termsize.ws_col< 4 && cols < 3 ) ) )
|
||||
{
|
||||
/*
|
||||
Terminal almost wide enough, or squeezing makes the whole list fit on-screen
|
||||
Terminal almost wide enough, or squeezing makes the
|
||||
whole list fit on-screen.
|
||||
|
||||
This part of the code is really important. People hate
|
||||
having to scroll through the completion list. In cases
|
||||
where there are a huge number of completions, it can't
|
||||
be helped, but it is not uncommon for the completions to
|
||||
_almost_ fit on one screen. In those cases, it is almost
|
||||
always desirable to 'squeeze' the completions into a
|
||||
single page.
|
||||
|
||||
If we are using N columns and can get everything to
|
||||
fit using squeezing, but everything would also fit
|
||||
using N-1 columns, don't try.
|
||||
*/
|
||||
|
||||
int tot_width = min_tot_width;
|
||||
width = min_width;
|
||||
|
||||
@@ -916,6 +945,7 @@ static void mangle_completions( array_list_t *l, const wchar_t *prefix )
|
||||
{
|
||||
*end = 0;
|
||||
wchar_t * str = escape( start, 1 );
|
||||
|
||||
comp->comp_width += my_wcswidth( str );
|
||||
halloc_register( global_context, str );
|
||||
al_push( comp->comp, str );
|
||||
@@ -973,45 +1003,52 @@ static int interrupt_handler()
|
||||
it with a copy of stderr, so the reading of completion strings must
|
||||
be done before init is called.
|
||||
*/
|
||||
static void init()
|
||||
static void init( int mangle_descriptors, int out )
|
||||
{
|
||||
struct sigaction act;
|
||||
|
||||
static struct termios pager_modes;
|
||||
|
||||
|
||||
program_name = L"fish_pager";
|
||||
wsetlocale( LC_ALL, L"" );
|
||||
|
||||
/*
|
||||
Make fd 1 output to screen, and use some other fd for writing
|
||||
the resulting output back to the caller
|
||||
*/
|
||||
int out = dup( 1 );
|
||||
int in = dup( 0 );
|
||||
close(1);
|
||||
close(0);
|
||||
|
||||
if( (in = open( ttyname(2), O_RDWR )) != -1 )
|
||||
if( mangle_descriptors )
|
||||
{
|
||||
if( dup2( 2, 1 ) == -1 )
|
||||
{
|
||||
debug( 0, _(L"Could not set up output file descriptors for pager") );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
if( dup2( in, 0 ) == -1 )
|
||||
{
|
||||
debug( 0, _(L"Could not set up input file descriptors for pager %d"), in );
|
||||
/*
|
||||
Make fd 1 output to screen, and use some other fd for writing
|
||||
the resulting output back to the caller
|
||||
*/
|
||||
int in;
|
||||
out = dup( 1 );
|
||||
close(1);
|
||||
close(0);
|
||||
|
||||
if( (in = open( ttyname(2), O_RDWR )) != -1 )
|
||||
{
|
||||
if( dup2( 2, 1 ) == -1 )
|
||||
{
|
||||
debug( 0, _(L"Could not set up output file descriptors for pager") );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
if( dup2( in, 0 ) == -1 )
|
||||
{
|
||||
debug( 0, _(L"Could not set up input file descriptors for pager") );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
debug( 0, _(L"Could not open tty for pager") );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if( !(out_file = fdopen( out, "w" )) )
|
||||
{
|
||||
debug( 0, _(L"Could not open tty for pager") );
|
||||
debug( 0, _(L"Could not initialize result pipe" ) );
|
||||
exit( 1 );
|
||||
}
|
||||
out_file = fdopen( out, "w" );
|
||||
|
||||
|
||||
/**
|
||||
Init the stringbuffer used to keep any output in
|
||||
@@ -1071,7 +1108,6 @@ static void destroy()
|
||||
{
|
||||
env_universal_destroy();
|
||||
input_common_destroy();
|
||||
halloc_util_destroy();
|
||||
wutil_destroy();
|
||||
if( del_curterm( cur_term ) == ERR )
|
||||
{
|
||||
@@ -1136,99 +1172,281 @@ static void read_array( FILE* file, array_list_t *comp )
|
||||
|
||||
}
|
||||
|
||||
static int get_fd( const char *str )
|
||||
{
|
||||
char *end;
|
||||
long fd;
|
||||
|
||||
errno = 0;
|
||||
fd = strtol( str, &end, 10 );
|
||||
if( fd < 0 || *end || errno )
|
||||
{
|
||||
debug( 0, ERR_NOT_FD, program_name, optarg );
|
||||
exit( 1 );
|
||||
}
|
||||
return (int)fd;
|
||||
}
|
||||
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
int i;
|
||||
int is_quoted=0;
|
||||
array_list_t *comp;
|
||||
wchar_t *prefix;
|
||||
wchar_t *prefix = 0;
|
||||
|
||||
int mangle_descriptors = 0;
|
||||
int result_fd = -1;
|
||||
|
||||
/*
|
||||
This initialization is made early, so that the other init code
|
||||
can use global_context for memory managment
|
||||
*/
|
||||
halloc_util_init();
|
||||
program_name = L"fish_pager";
|
||||
|
||||
if( argc < 3 )
|
||||
|
||||
wsetlocale( LC_ALL, L"" );
|
||||
comp = al_halloc( global_context );
|
||||
|
||||
/*
|
||||
The call signature for fish_pager is a mess. Because we want
|
||||
to be able to upgrade fish without breaking running
|
||||
instances, we need to support all previous
|
||||
modes. Unfortunatly, the two previous ones are a mess. The
|
||||
third one is designed to be extensible, so hopefully it will
|
||||
be the last.
|
||||
*/
|
||||
|
||||
if( argc > 1 && argv[1][0] == '-' )
|
||||
{
|
||||
debug( 0, _(L"Insufficient arguments") );
|
||||
/*
|
||||
Third mode
|
||||
*/
|
||||
|
||||
int completion_fd = -1;
|
||||
FILE *completion_file;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
static struct option
|
||||
long_options[] =
|
||||
{
|
||||
{
|
||||
"result-fd", required_argument, 0, 'r'
|
||||
}
|
||||
,
|
||||
{
|
||||
"completion-fd", required_argument, 0, 'c'
|
||||
}
|
||||
,
|
||||
{
|
||||
"prefix", required_argument, 0, 'p'
|
||||
}
|
||||
,
|
||||
{
|
||||
"is-quoted", no_argument, 0, 'q'
|
||||
}
|
||||
,
|
||||
{
|
||||
"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
"version", no_argument, 0, 'v'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
int opt_index = 0;
|
||||
|
||||
int opt = getopt_long( argc,
|
||||
argv,
|
||||
GETOPT_STRING,
|
||||
long_options,
|
||||
&opt_index );
|
||||
|
||||
if( opt == -1 )
|
||||
break;
|
||||
|
||||
switch( opt )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
case 'r':
|
||||
{
|
||||
result_fd = get_fd( optarg );
|
||||
break;
|
||||
}
|
||||
|
||||
case 'c':
|
||||
{
|
||||
completion_fd = get_fd( optarg );
|
||||
break;
|
||||
}
|
||||
|
||||
case 'p':
|
||||
{
|
||||
prefix = str2wcs(optarg);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'h':
|
||||
{
|
||||
print_help( argv[0], 1 );
|
||||
exit(0);
|
||||
}
|
||||
|
||||
case 'v':
|
||||
{
|
||||
debug( 0, L"%ls, version %s\n", program_name, PACKAGE_VERSION );
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
case 'q':
|
||||
{
|
||||
is_quoted = 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if( completion_fd == -1 || result_fd == -1 )
|
||||
{
|
||||
debug( 0, _(L"Unspecified file descriptors") );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
|
||||
if( (completion_file = fdopen( completion_fd, "r" ) ) )
|
||||
{
|
||||
read_array( completion_file, comp );
|
||||
fclose( completion_file );
|
||||
}
|
||||
else
|
||||
{
|
||||
debug( 0, _(L"Could not read completions") );
|
||||
wperror( L"fdopen" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
if( !prefix )
|
||||
{
|
||||
prefix = wcsdup( L"" );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Second or first mode. These suck, but we need to support
|
||||
them for backwards compatibility. At least for some
|
||||
time.
|
||||
|
||||
comp = al_halloc( global_context );
|
||||
prefix = str2wcs( argv[2] );
|
||||
is_quoted = strcmp( "1", argv[1] )==0;
|
||||
is_quoted = 0;
|
||||
Third mode was implemented in January 2007, and previous
|
||||
modes should be considered deprecated from that point
|
||||
forward. A reasonable time frame for removal of the code
|
||||
below has yet to be determined.
|
||||
*/
|
||||
|
||||
if( argc < 3 )
|
||||
{
|
||||
print_help( argv[0], 1 );
|
||||
exit( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
mangle_descriptors = 1;
|
||||
|
||||
prefix = str2wcs( argv[2] );
|
||||
is_quoted = strcmp( "1", argv[1] )==0;
|
||||
|
||||
if( argc > 3 )
|
||||
{
|
||||
/*
|
||||
First mode
|
||||
*/
|
||||
for( i=3; i<argc; i++ )
|
||||
{
|
||||
wchar_t *wcs = str2wcs( argv[i] );
|
||||
if( wcs )
|
||||
{
|
||||
al_push( comp, wcs );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Second mode
|
||||
*/
|
||||
read_array( stdin, comp );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// debug( 3, L"prefix is '%ls'", prefix );
|
||||
|
||||
if( argc > 3 )
|
||||
init( mangle_descriptors, result_fd );
|
||||
|
||||
mangle_descriptions( comp );
|
||||
|
||||
if( wcscmp( prefix, L"-" ) == 0 )
|
||||
join_completions( comp );
|
||||
|
||||
mangle_completions( comp, prefix );
|
||||
|
||||
/**
|
||||
Try to print the completions. Start by trying to print the
|
||||
list in PAGER_MAX_COLS columns, if the completions won't
|
||||
fit, reduce the number of columns by one. Printing a single
|
||||
column never fails.
|
||||
*/
|
||||
for( i = PAGER_MAX_COLS; i>0; i-- )
|
||||
{
|
||||
switch( completion_try_print( i, prefix, is_quoted, comp ) )
|
||||
{
|
||||
for( i=3; i<argc; i++ )
|
||||
{
|
||||
wchar_t *wcs = str2wcs( argv[i] );
|
||||
if( wcs )
|
||||
{
|
||||
al_push( comp, wcs );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
read_array( stdin, comp );
|
||||
}
|
||||
|
||||
init();
|
||||
case PAGER_RETRY:
|
||||
break;
|
||||
|
||||
mangle_descriptions( comp );
|
||||
case PAGER_DONE:
|
||||
i=0;
|
||||
break;
|
||||
|
||||
if( wcscmp( prefix, L"-" ) == 0 )
|
||||
join_completions( comp );
|
||||
case PAGER_RESIZE:
|
||||
/*
|
||||
This means we got a resize event, so we start
|
||||
over from the beginning. Since it the screen got
|
||||
bigger, we might be able to fit all completions
|
||||
on-screen.
|
||||
*/
|
||||
i=PAGER_MAX_COLS+1;
|
||||
break;
|
||||
|
||||
mangle_completions( comp, prefix );
|
||||
|
||||
/**
|
||||
Try to print the completions. Start by trying to print the
|
||||
list in PAGER_MAX_COLS columns, if the completions won't
|
||||
fit, reduce the number of columns by one. Printing a single
|
||||
column never fails.
|
||||
*/
|
||||
for( i = PAGER_MAX_COLS; i>0; i-- )
|
||||
{
|
||||
switch( completion_try_print( i, prefix, is_quoted, comp ) )
|
||||
{
|
||||
|
||||
case PAGER_RETRY:
|
||||
break;
|
||||
|
||||
case PAGER_DONE:
|
||||
i=0;
|
||||
break;
|
||||
|
||||
case PAGER_RESIZE:
|
||||
/*
|
||||
This means we got a resize event, so we start
|
||||
over from the beginning. Since it the screen got
|
||||
bigger, we might be able to fit all completions
|
||||
on-screen.
|
||||
*/
|
||||
i=PAGER_MAX_COLS+1;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
free(prefix );
|
||||
|
||||
fwprintf( out_file, L"%ls", (wchar_t *)out_buff.buff );
|
||||
if( is_ca_mode )
|
||||
{
|
||||
writembs(exit_ca_mode);
|
||||
pager_flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(prefix );
|
||||
|
||||
fwprintf( out_file, L"%ls", (wchar_t *)out_buff.buff );
|
||||
if( is_ca_mode )
|
||||
{
|
||||
writembs(exit_ca_mode);
|
||||
pager_flush();
|
||||
}
|
||||
destroy();
|
||||
|
||||
halloc_util_destroy();
|
||||
|
||||
}
|
||||
|
||||
|
||||
8
fishd.c
8
fishd.c
@@ -73,6 +73,7 @@ time the original barrier request was sent have been received.
|
||||
#include "halloc.h"
|
||||
#include "halloc_util.h"
|
||||
#include "path.h"
|
||||
#include "print_help.h"
|
||||
|
||||
/**
|
||||
Maximum length of socket filename
|
||||
@@ -140,11 +141,6 @@ static int sock;
|
||||
*/
|
||||
static int quit=0;
|
||||
|
||||
/**
|
||||
Dynamically generated function, made from the documentation in doc_src.
|
||||
*/
|
||||
void print_help();
|
||||
|
||||
/**
|
||||
Constructs the fish socket filename
|
||||
*/
|
||||
@@ -620,7 +616,7 @@ int main( int argc, char ** argv )
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
print_help();
|
||||
print_help( argv[0], 1 );
|
||||
exit(0);
|
||||
|
||||
case 'v':
|
||||
|
||||
45
function.c
45
function.c
@@ -1,5 +1,10 @@
|
||||
/** \file function.c
|
||||
Functions for storing and retrieving function information.
|
||||
|
||||
Prototypes for functions for storing and retrieving function
|
||||
information. These functions also take care of autoloading
|
||||
functions in the $fish_function_path. Actual function evaluation
|
||||
is taken care of by the parser and to some degree the builtin
|
||||
handling library.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -25,6 +30,8 @@
|
||||
#include "parse_util.h"
|
||||
#include "env.h"
|
||||
#include "expand.h"
|
||||
#include "halloc.h"
|
||||
#include "halloc_util.h"
|
||||
|
||||
|
||||
/**
|
||||
@@ -135,19 +142,6 @@ static void autoload_names( array_list_t *out, int get_hidden )
|
||||
al_destroy( &path_list );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Free all contents of an entry to the function hash table
|
||||
*/
|
||||
static void clear_function_entry( void *key,
|
||||
void *data )
|
||||
{
|
||||
function_data_t *d = (function_data_t *)data;
|
||||
free( (void *)d->cmd );
|
||||
free( (void *)d->desc );
|
||||
free( (void *)d );
|
||||
}
|
||||
|
||||
void function_init()
|
||||
{
|
||||
hash_init( &function,
|
||||
@@ -155,9 +149,14 @@ void function_init()
|
||||
&hash_wcs_cmp );
|
||||
}
|
||||
|
||||
static void clear_entry( void *key, void *value )
|
||||
{
|
||||
halloc_free( value );
|
||||
}
|
||||
|
||||
void function_destroy()
|
||||
{
|
||||
hash_foreach( &function, &clear_function_entry );
|
||||
hash_foreach( &function, &clear_entry );
|
||||
hash_destroy( &function );
|
||||
}
|
||||
|
||||
@@ -176,13 +175,13 @@ void function_add( const wchar_t *name,
|
||||
|
||||
function_remove( name );
|
||||
|
||||
d = malloc( sizeof( function_data_t ) );
|
||||
d = halloc( 0, sizeof( function_data_t ) );
|
||||
d->definition_offset = parse_util_lineno( parser_get_buffer(), current_block->tok_pos )-1;
|
||||
d->cmd = wcsdup( val );
|
||||
d->cmd = halloc_wcsdup( d, val );
|
||||
|
||||
cmd_end = d->cmd + wcslen(d->cmd)-1;
|
||||
|
||||
d->desc = desc?wcsdup( desc ):0;
|
||||
d->desc = desc?halloc_wcsdup( d, desc ):0;
|
||||
d->definition_file = intern(reader_current_filename());
|
||||
d->is_autoload = is_autoload;
|
||||
|
||||
@@ -230,7 +229,7 @@ void function_remove( const wchar_t *name )
|
||||
ev.function_name=name;
|
||||
event_remove( &ev );
|
||||
|
||||
clear_function_entry( key, d );
|
||||
halloc_free( d );
|
||||
|
||||
/*
|
||||
Notify the autoloader that the specified function is erased, but
|
||||
@@ -282,7 +281,7 @@ void function_set_desc( const wchar_t *name, const wchar_t *desc )
|
||||
if( data == 0 )
|
||||
return;
|
||||
|
||||
data->desc =wcsdup(desc);
|
||||
data->desc = halloc_wcsdup( data, desc );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -294,9 +293,9 @@ static int al_contains_str( array_list_t *list, const wchar_t * str )
|
||||
for( i=0; i<al_get_count( list ); i++ )
|
||||
{
|
||||
if( wcscmp( al_get( list, i ), str) == 0 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
29
function.h
29
function.h
@@ -1,8 +1,10 @@
|
||||
/** \file function.h
|
||||
|
||||
Prototypes for functions for storing and retrieving function
|
||||
information. Actual function evaluation is taken care of by the
|
||||
parser and to some degree the builtin handling library.
|
||||
information. These functions also take care of autoloading
|
||||
functions in the $fish_function_path. Actual function evaluation
|
||||
is taken care of by the parser and to some degree the builtin
|
||||
handling library.
|
||||
*/
|
||||
|
||||
#ifndef FISH_FUNCTION_H
|
||||
@@ -16,13 +18,15 @@
|
||||
Initialize function data
|
||||
*/
|
||||
void function_init();
|
||||
|
||||
/**
|
||||
Destroy function data
|
||||
*/
|
||||
void function_destroy();
|
||||
|
||||
/**
|
||||
Add an function. The parameters values are copied and should be freed by the caller.
|
||||
Add an function. The parameters values are copied and should be
|
||||
freed by the caller.
|
||||
*/
|
||||
void function_add( const wchar_t *name,
|
||||
const wchar_t *val,
|
||||
@@ -34,11 +38,6 @@ void function_add( const wchar_t *name,
|
||||
*/
|
||||
void function_remove( const wchar_t *name );
|
||||
|
||||
/**
|
||||
Returns true if the function with the name name uses internal variables, false otherwise.
|
||||
*/
|
||||
int function_use_vars( const wchar_t *name );
|
||||
|
||||
/**
|
||||
Returns the definition of the function with the name \c name.
|
||||
*/
|
||||
@@ -55,12 +54,13 @@ const wchar_t *function_get_desc( const wchar_t *name );
|
||||
void function_set_desc( const wchar_t *name, const wchar_t *desc );
|
||||
|
||||
/**
|
||||
Returns true if the function witrh the name name exists.
|
||||
Returns true if the function with the name name exists.
|
||||
*/
|
||||
int function_exists( const wchar_t *name );
|
||||
|
||||
/**
|
||||
Insert all function names into l. These are not copies of the strings and should not be freed after use.
|
||||
Insert all function names into l. These are not copies of the
|
||||
strings and should not be freed after use.
|
||||
|
||||
\param list the list to add the names to
|
||||
\param get_hidden whether to include hidden functions, i.e. ones starting with an underscore
|
||||
@@ -71,11 +71,18 @@ void function_get_names( array_list_t *list,
|
||||
/**
|
||||
Returns tha absolute path of the file where the specified function
|
||||
was defined. Returns 0 if the file was defined on the commandline.
|
||||
|
||||
This function does not autoload functions, it will only work on
|
||||
functions that have already been defined.
|
||||
*/
|
||||
const wchar_t *function_get_definition_file( const wchar_t *name );
|
||||
|
||||
/**
|
||||
Returns the linenumber where the definition of the specified function started
|
||||
Returns the linenumber where the definition of the specified
|
||||
function started.
|
||||
|
||||
This function does not autoload functions, it will only work on
|
||||
functions that have already been defined.
|
||||
*/
|
||||
int function_get_definition_offset( const wchar_t *name );
|
||||
|
||||
|
||||
12
gen_hdr.sh
12
gen_hdr.sh
@@ -1,12 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This little script calls the man command to render a manual page and
|
||||
# pipes the result into the gen_hdr2 program to convert the output
|
||||
# into a C string literal.
|
||||
|
||||
# NAME is the name of the function we are generating documentation for.
|
||||
NAME=`basename $1 .doxygen`
|
||||
|
||||
# Render the page
|
||||
nroff -man doc_src/builtin_doc/man/man1/${NAME}.1 | col -b | cat -s | sed -e '$d' | ./gen_hdr2
|
||||
|
||||
76
gen_hdr2.c
76
gen_hdr2.c
@@ -1,76 +0,0 @@
|
||||
/** \file gen_hdr2.c
|
||||
A program that reads data from stdin and outputs it as a C string.
|
||||
|
||||
It is used as a part of the build process to generate help texts
|
||||
for the built in commands.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
/**
|
||||
The main function, does all the work
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
int line = 0;
|
||||
printf( "\t\t\"" );
|
||||
int c;
|
||||
int count=0;
|
||||
while( (c=getchar()) != EOF )
|
||||
{
|
||||
if( c == '\n' )
|
||||
line++;
|
||||
|
||||
if( line > 4 )
|
||||
break;
|
||||
}
|
||||
|
||||
while( (c=getchar()) != EOF )
|
||||
{
|
||||
if( (c >= 'a' && c <= 'z' ) ||
|
||||
(c >= 'A' && c <= 'Z' ) ||
|
||||
(c >= '0' && c <= '9' ) ||
|
||||
( strchr(" ,.!;:-_#$%&(){}[]<>=?+-*/'",c) != 0) )
|
||||
{
|
||||
count++;
|
||||
putchar(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(c)
|
||||
{
|
||||
case '\n':
|
||||
printf( "\\n" );
|
||||
printf( "\"\n\t\t\"" );
|
||||
count =0;
|
||||
break;
|
||||
case '\t':
|
||||
printf( "\\t" );
|
||||
count +=2;
|
||||
break;
|
||||
case '\r':
|
||||
printf( "\\r" );
|
||||
count +=2;
|
||||
break;
|
||||
|
||||
case '\"':
|
||||
case '\\':
|
||||
printf( "\\%c",c );
|
||||
count +=2;
|
||||
break;
|
||||
|
||||
default:
|
||||
count +=7;
|
||||
printf( "\\x%02x\" \"", c );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( count > 60 )
|
||||
{
|
||||
count=0;
|
||||
printf( "\"\n\t\t\"" );
|
||||
}
|
||||
}
|
||||
printf( "\"" );
|
||||
return 0;
|
||||
}
|
||||
6
halloc.c
6
halloc.c
@@ -179,12 +179,16 @@ void *halloc( void *context, size_t size )
|
||||
alloc_spill += parent->scratch_free;
|
||||
#endif
|
||||
res = calloc( 1, size + HALLOC_BLOCK_SIZE );
|
||||
if( !res )
|
||||
DIE_MEM();
|
||||
parent->scratch = (char *)res + size;
|
||||
parent->scratch_free = HALLOC_BLOCK_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = calloc( 1, size );
|
||||
if( !res )
|
||||
DIE_MEM();
|
||||
}
|
||||
al_push( &parent->children, &late_free );
|
||||
al_push( &parent->children, res );
|
||||
@@ -198,7 +202,7 @@ void *halloc( void *context, size_t size )
|
||||
me = (halloc_t *)calloc( 1, align_sz(sizeof(halloc_t)) + align_sz(size) + HALLOC_BLOCK_SIZE );
|
||||
|
||||
if( !me )
|
||||
return 0;
|
||||
DIE_MEM();
|
||||
#ifdef HALLOC_DEBUG
|
||||
parent_count++;
|
||||
#endif
|
||||
|
||||
81
highlight.c
81
highlight.c
@@ -540,6 +540,11 @@ void highlight_shell( wchar_t * buff,
|
||||
|
||||
void *context;
|
||||
wchar_t *cmd=0;
|
||||
int accept_switches = 1;
|
||||
|
||||
int use_function = 1;
|
||||
int use_command = 1;
|
||||
int use_builtin = 1;
|
||||
|
||||
CHECK( buff, );
|
||||
CHECK( color, );
|
||||
@@ -572,10 +577,22 @@ void highlight_shell( wchar_t * buff,
|
||||
wchar_t *param = tok_last( &tok );
|
||||
if( param[0] == L'-' )
|
||||
{
|
||||
if( complete_is_valid_option( last_cmd, param, error ))
|
||||
if (wcscmp( param, L"--" ) == 0 )
|
||||
{
|
||||
accept_switches = 0;
|
||||
color[ tok_get_pos( &tok ) ] = HIGHLIGHT_PARAM;
|
||||
}
|
||||
else if( accept_switches )
|
||||
{
|
||||
if( complete_is_valid_option( last_cmd, param, error ) )
|
||||
color[ tok_get_pos( &tok ) ] = HIGHLIGHT_PARAM;
|
||||
else
|
||||
color[ tok_get_pos( &tok ) ] = HIGHLIGHT_ERROR;
|
||||
}
|
||||
else
|
||||
color[ tok_get_pos( &tok ) ] = HIGHLIGHT_ERROR;
|
||||
{
|
||||
color[ tok_get_pos( &tok ) ] = HIGHLIGHT_PARAM;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -627,21 +644,48 @@ void highlight_shell( wchar_t * buff,
|
||||
|
||||
if( parser_is_subcommand( cmd ) )
|
||||
{
|
||||
|
||||
int sw;
|
||||
|
||||
if( wcscmp( cmd, L"builtin" )==0)
|
||||
{
|
||||
use_function = 0;
|
||||
use_command = 0;
|
||||
use_builtin = 1;
|
||||
}
|
||||
else if( wcscmp( cmd, L"command" )==0)
|
||||
{
|
||||
use_command = 1;
|
||||
use_function = 0;
|
||||
use_builtin = 0;
|
||||
}
|
||||
|
||||
tok_next( &tok );
|
||||
if( ( ! parser_is_block( cmd ) ) &&
|
||||
( ( wcscmp( L"-h", tok_last( &tok ) ) == 0 ) ||
|
||||
( wcsncmp( L"--help", tok_last( &tok ), wcslen( tok_last( &tok ) ) ) == 0 && wcslen( tok_last( &tok ) ) >= 3 ) ) )
|
||||
|
||||
sw = parser_is_switch( tok_last( &tok ) );
|
||||
|
||||
if( !parser_is_block( cmd ) &&
|
||||
sw == ARG_SWITCH )
|
||||
{
|
||||
/*
|
||||
The builtin and command builtins
|
||||
The 'builtin' and 'command' builtins
|
||||
are normally followed by another
|
||||
command, but if they are invoked
|
||||
with the -h option, their help text
|
||||
is displayed instead
|
||||
with a switch, they aren't.
|
||||
|
||||
*/
|
||||
use_command = 1;
|
||||
use_function = 1;
|
||||
use_builtin = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( sw == ARG_SKIP )
|
||||
{
|
||||
color[ tok_get_pos( &tok ) ] = HIGHLIGHT_PARAM;
|
||||
mark = tok_get_pos( &tok );
|
||||
}
|
||||
|
||||
is_subcommand = 1;
|
||||
}
|
||||
tok_set_pos( &tok, mark );
|
||||
@@ -662,8 +706,11 @@ void highlight_shell( wchar_t * buff,
|
||||
function, since we don't have to stat
|
||||
any files for that
|
||||
*/
|
||||
is_cmd |= builtin_exists( cmd );
|
||||
is_cmd |= function_exists( cmd );
|
||||
if( use_builtin )
|
||||
is_cmd |= builtin_exists( cmd );
|
||||
|
||||
if( use_function )
|
||||
is_cmd |= function_exists( cmd );
|
||||
|
||||
/*
|
||||
Moving on to expensive tests
|
||||
@@ -672,13 +719,15 @@ void highlight_shell( wchar_t * buff,
|
||||
/*
|
||||
Check if this is a regular command
|
||||
*/
|
||||
is_cmd |= !!(tmp=path_get_path( context, cmd ));
|
||||
if( use_command )
|
||||
is_cmd |= !!(tmp=path_get_path( context, cmd ));
|
||||
|
||||
/*
|
||||
Could not find the command. Maybe it is
|
||||
a path for a implicit cd command.
|
||||
*/
|
||||
is_cmd |= !!(tmp=path_get_cdpath( context, cmd ));
|
||||
if( use_builtin || (use_function && function_exists( L"cd") ) )
|
||||
is_cmd |= !!(tmp=path_get_cdpath( context, cmd ));
|
||||
|
||||
if( is_cmd )
|
||||
{
|
||||
@@ -791,6 +840,10 @@ void highlight_shell( wchar_t * buff,
|
||||
{
|
||||
color[ tok_get_pos( &tok ) ] = HIGHLIGHT_END;
|
||||
had_cmd = 0;
|
||||
use_command = 1;
|
||||
use_function = 1;
|
||||
use_builtin = 1;
|
||||
accept_switches = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -806,6 +859,10 @@ void highlight_shell( wchar_t * buff,
|
||||
{
|
||||
color[ tok_get_pos( &tok ) ] = HIGHLIGHT_END;
|
||||
had_cmd = 0;
|
||||
use_command = 1;
|
||||
use_function = 1;
|
||||
use_builtin = 1;
|
||||
accept_switches = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
86
history.c
86
history.c
@@ -1,5 +1,5 @@
|
||||
/** \file history.c
|
||||
History functions, part of the user interface.
|
||||
History functions, part of the user interface.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
@@ -345,9 +345,13 @@ static item_t *item_get( history_mode_t *m, void *d )
|
||||
|
||||
if( *time_string )
|
||||
{
|
||||
time_t tm = (time_t)wcstol( time_string, 0, 10 );
|
||||
|
||||
if( tm && !errno )
|
||||
time_t tm;
|
||||
wchar_t *end;
|
||||
|
||||
errno = 0;
|
||||
tm = (time_t)wcstol( time_string, &end, 10 );
|
||||
|
||||
if( tm && !errno && !*end )
|
||||
{
|
||||
narrow_item.timestamp = tm;
|
||||
}
|
||||
@@ -385,10 +389,10 @@ static item_t *item_get( history_mode_t *m, void *d )
|
||||
/**
|
||||
Write the specified item to the specified file.
|
||||
*/
|
||||
static void item_write( FILE *f, history_mode_t *m, void *v )
|
||||
static int item_write( FILE *f, history_mode_t *m, void *v )
|
||||
{
|
||||
item_t *i = item_get( m, v );
|
||||
fwprintf( f, L"# %d\n%ls\n", i->timestamp, history_escape_newlines( i->data ) );
|
||||
return fwprintf( f, L"# %d\n%ls\n", i->timestamp, history_escape_newlines( i->data ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -605,9 +609,11 @@ static void history_save_mode( void *n, history_mode_t *m )
|
||||
FILE *out;
|
||||
history_mode_t *on_disk;
|
||||
int i;
|
||||
int has_new;
|
||||
int has_new=0;
|
||||
wchar_t *tmp_name;
|
||||
|
||||
int ok = 1;
|
||||
|
||||
/*
|
||||
First check if there are any new entries to save. If not, then
|
||||
we can just return
|
||||
@@ -661,12 +667,19 @@ static void history_save_mode( void *n, history_mode_t *m )
|
||||
/*
|
||||
Re-save the old history
|
||||
*/
|
||||
for( i=0; i<al_get_count(&on_disk->item); i++ )
|
||||
for( i=0; ok && (i<al_get_count(&on_disk->item)); i++ )
|
||||
{
|
||||
void *ptr = al_get( &on_disk->item, i );
|
||||
item_t *i = item_get( on_disk, ptr );
|
||||
if( !hash_get( &mine, i ) )
|
||||
item_write( out, on_disk, ptr );
|
||||
{
|
||||
if( item_write( out, on_disk, ptr ) == -1 )
|
||||
{
|
||||
ok = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
hash_destroy( &mine );
|
||||
@@ -674,15 +687,20 @@ static void history_save_mode( void *n, history_mode_t *m )
|
||||
/*
|
||||
Add our own items last
|
||||
*/
|
||||
for( i=0; i<al_get_count(&m->item); i++ )
|
||||
for( i=0; ok && (i<al_get_count(&m->item)); i++ )
|
||||
{
|
||||
void *ptr = al_get( &m->item, i );
|
||||
int is_new = item_is_new( m, ptr );
|
||||
if( is_new )
|
||||
item_write( out, m, ptr );
|
||||
{
|
||||
if( item_write( out, m, ptr ) == -1 )
|
||||
{
|
||||
ok = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( fclose( out ) )
|
||||
if( fclose( out ) || !ok )
|
||||
{
|
||||
/*
|
||||
This message does not have high enough priority to
|
||||
@@ -700,26 +718,32 @@ static void history_save_mode( void *n, history_mode_t *m )
|
||||
|
||||
halloc_free( on_disk);
|
||||
|
||||
/*
|
||||
Reset the history. The item_t entries created in this session
|
||||
are not lost or dropped, they are stored in the session_item
|
||||
hash table. On reload, they will be automatically inserted at
|
||||
the end of the history list.
|
||||
*/
|
||||
|
||||
if( m->mmap_start && (m->mmap_start != MAP_FAILED ) )
|
||||
munmap( m->mmap_start, m->mmap_length );
|
||||
|
||||
al_truncate( &m->item, 0 );
|
||||
al_truncate( &m->used, 0 );
|
||||
m->pos = 0;
|
||||
m->has_loaded = 0;
|
||||
m->mmap_start=0;
|
||||
m->mmap_length=0;
|
||||
|
||||
m->save_timestamp=time(0);
|
||||
m->new_count = 0;
|
||||
if( ok )
|
||||
{
|
||||
|
||||
/*
|
||||
Reset the history. The item_t entries created in this session
|
||||
are not lost or dropped, they are stored in the session_item
|
||||
hash table. On reload, they will be automatically inserted at
|
||||
the end of the history list.
|
||||
*/
|
||||
|
||||
if( m->mmap_start && (m->mmap_start != MAP_FAILED ) )
|
||||
{
|
||||
munmap( m->mmap_start, m->mmap_length );
|
||||
}
|
||||
|
||||
al_truncate( &m->item, 0 );
|
||||
al_truncate( &m->used, 0 );
|
||||
m->pos = 0;
|
||||
m->has_loaded = 0;
|
||||
m->mmap_start=0;
|
||||
m->mmap_length=0;
|
||||
|
||||
m->save_timestamp=time(0);
|
||||
m->new_count = 0;
|
||||
}
|
||||
|
||||
signal_unblock();
|
||||
}
|
||||
|
||||
|
||||
16
input.c
16
input.c
@@ -133,7 +133,8 @@ static const wchar_t *name_arr[] =
|
||||
L"vi-arg-digit",
|
||||
L"execute",
|
||||
L"beginning-of-buffer",
|
||||
L"end-of-buffer"
|
||||
L"end-of-buffer",
|
||||
L"repaint"
|
||||
}
|
||||
;
|
||||
|
||||
@@ -214,6 +215,7 @@ static const wchar_t code_arr[] =
|
||||
R_EXECUTE,
|
||||
R_BEGINNING_OF_BUFFER,
|
||||
R_END_OF_BUFFER,
|
||||
R_REPAINT
|
||||
}
|
||||
;
|
||||
|
||||
@@ -255,7 +257,6 @@ static int inputrc_error = 0;
|
||||
*/
|
||||
static int is_init = 0;
|
||||
|
||||
|
||||
/**
|
||||
This is the variable telling us how many timew the next command
|
||||
should bne repeated. Only actually used in vi-mode.
|
||||
@@ -1610,13 +1611,14 @@ static wint_t input_exec_binding( mapping *m, const wchar_t *seq )
|
||||
write( 1, "\r", 1 );
|
||||
tputs(clr_eol,1,&writeb);
|
||||
|
||||
reader_run_command( m->command );
|
||||
|
||||
eval( m->command, 0, TOP );
|
||||
|
||||
/*
|
||||
We still need to return something to the caller, R_NULL
|
||||
tells the reader that nothing happened, but it might be a
|
||||
godd idea to redraw and reexecute the prompt.
|
||||
tells the reader that no key press needs to be handled, but
|
||||
it might be a good idea to redraw.
|
||||
*/
|
||||
|
||||
return R_NULL;
|
||||
}
|
||||
|
||||
@@ -1675,6 +1677,8 @@ wint_t input_readch()
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
CHECK_BLOCK( R_NULL );
|
||||
|
||||
/*
|
||||
Clear the interrupted flag
|
||||
|
||||
3
input.h
3
input.h
@@ -48,7 +48,8 @@ enum
|
||||
R_VI_DELETE_TO,
|
||||
R_EXECUTE,
|
||||
R_BEGINNING_OF_BUFFER,
|
||||
R_END_OF_BUFFER
|
||||
R_END_OF_BUFFER,
|
||||
R_REPAINT
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
@@ -98,6 +98,11 @@ static wint_t readb()
|
||||
{
|
||||
return res;
|
||||
}
|
||||
if( lookahead_count )
|
||||
{
|
||||
return lookahead_arr[--lookahead_count];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +112,7 @@ static wint_t readb()
|
||||
default:
|
||||
{
|
||||
/*
|
||||
The teminal has been closed. Save and exit.
|
||||
The terminal has been closed. Save and exit.
|
||||
*/
|
||||
return R_EOF;
|
||||
}
|
||||
@@ -122,6 +127,11 @@ static wint_t readb()
|
||||
debug( 3, L"Wake up on universal variable event" );
|
||||
env_universal_read_all();
|
||||
do_loop = 1;
|
||||
|
||||
if( lookahead_count )
|
||||
{
|
||||
return lookahead_arr[--lookahead_count];
|
||||
}
|
||||
}
|
||||
}
|
||||
if( FD_ISSET( 0, &fd ) )
|
||||
|
||||
1
io.h
1
io.h
@@ -41,7 +41,6 @@ typedef struct io_data
|
||||
buffer_t *out_buffer;
|
||||
/** Whether to close old_fd for IO_FD */
|
||||
int close_old;
|
||||
|
||||
} param2
|
||||
;
|
||||
|
||||
|
||||
11
main.c
11
main.c
@@ -195,8 +195,12 @@ static int fish_parse_opt( int argc, char **argv, char **cmd_ptr )
|
||||
case 'd':
|
||||
{
|
||||
char *end;
|
||||
int tmp = strtol(optarg, &end, 10);
|
||||
if( tmp >= 0 && tmp <=10 && !*end )
|
||||
int tmp;
|
||||
|
||||
errno = 0;
|
||||
tmp = strtol(optarg, &end, 10);
|
||||
|
||||
if( tmp >= 0 && tmp <=10 && !*end && !errno )
|
||||
{
|
||||
debug_level=tmp;
|
||||
}
|
||||
@@ -210,7 +214,7 @@ static int fish_parse_opt( int argc, char **argv, char **cmd_ptr )
|
||||
|
||||
case 'h':
|
||||
{
|
||||
*cmd_ptr = "help";
|
||||
*cmd_ptr = "__fish_print_help fish";
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -308,7 +312,6 @@ int main( int argc, char **argv )
|
||||
reader_init();
|
||||
history_init();
|
||||
|
||||
|
||||
if( read_init() )
|
||||
{
|
||||
if( cmd != 0 )
|
||||
|
||||
88
make_completions.py
Executable file
88
make_completions.py
Executable file
@@ -0,0 +1,88 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
import commands
|
||||
import re
|
||||
|
||||
def escape_quotes(s):
|
||||
return re.sub('\'', '\\\'', s)
|
||||
|
||||
def escape(s):
|
||||
return re.sub('([\'"#%*?])', r"\\\1", s)
|
||||
|
||||
def print_completion( cmd, switch_name, desc ):
|
||||
|
||||
offset=1
|
||||
switch_type = "o"
|
||||
|
||||
if len(switch_name) == 2:
|
||||
switch_type = "s"
|
||||
|
||||
if switch_name[1] == "-":
|
||||
switch_type = "l"
|
||||
offset=2
|
||||
|
||||
print "complete -c %s -%s %s --description '%s'" % (cmd, switch_type, escape( switch_name[offset:] ), escape_quotes(desc))
|
||||
|
||||
def clean_whitespace( str ):
|
||||
clean_whitespace_prog0 = re.compile( r"-[ \t]*\n[ \t\r]+" )
|
||||
clean_whitespace_prog1 = re.compile( r"[ \n\t]+" )
|
||||
clean_whitespace_prog2 = re.compile( r"^[ \t\r]*", re.MULTILINE )
|
||||
str = clean_whitespace_prog0.sub( "", str )
|
||||
str = clean_whitespace_prog1.sub( " ", str )
|
||||
str = clean_whitespace_prog2.sub( "", str )
|
||||
return str
|
||||
|
||||
|
||||
|
||||
cmd = sys.argv[1]
|
||||
man = commands.getoutput( "man %s | col -b" % cmd )
|
||||
remainder = man
|
||||
|
||||
re1 = r"\n( *-[^ ,]* *(|\n))+[^.]+"
|
||||
prog1 = re.compile(re1, re.MULTILINE)
|
||||
|
||||
re2 = r"^(|=[^ ]*)( |\n)*(?P<switch>-[^ =./\n]+)( *[^-\n ]*\n|)"
|
||||
prog2 = re.compile(re2, re.MULTILINE)
|
||||
|
||||
while True:
|
||||
|
||||
match = prog1.search( remainder )
|
||||
|
||||
if match == None:
|
||||
break
|
||||
|
||||
# print "yay match!!!\n"
|
||||
str = match.string[match.start():match.end()]
|
||||
|
||||
# print str
|
||||
|
||||
rem2 = str
|
||||
|
||||
switch = []
|
||||
|
||||
while True:
|
||||
match2 = prog2.search( rem2 )
|
||||
|
||||
if match2 == None:
|
||||
break
|
||||
|
||||
sw = match2.expand( r"\g<switch>" )
|
||||
# print "yay switch %s!!!\n" %sw
|
||||
|
||||
switch.append( sw )
|
||||
|
||||
rem2 = rem2[match2.end():]
|
||||
|
||||
desc = clean_whitespace(rem2)
|
||||
|
||||
if len( desc) > 8:
|
||||
|
||||
# print "Yay desc '%s'!!\n" % desc
|
||||
|
||||
for i in switch:
|
||||
print_completion( cmd, i, desc )
|
||||
|
||||
|
||||
remainder = remainder[match.end():]
|
||||
|
||||
211
make_mercurial_completions.fish
Executable file
211
make_mercurial_completions.fish
Executable file
@@ -0,0 +1,211 @@
|
||||
#!/usr/bin/env fish
|
||||
|
||||
#
|
||||
# This file produces command specific completions for either hg or darcs
|
||||
#
|
||||
|
||||
function cap
|
||||
set res (echo $argv |cut -c 1|tr a-z A-Z)(echo $argv |cut -c 2-)
|
||||
echo $res
|
||||
end
|
||||
|
||||
function esc
|
||||
echo $argv | sed -e "s/'/\\\'/g"
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# This function formats a list of completion information into a set of fish completions
|
||||
#
|
||||
# The first argument is the condition string, which will be copied to
|
||||
# the resulting commandline verbatim
|
||||
#
|
||||
# Remaining arguments are tab separated lists of completion
|
||||
# information. Each list contains four elements, the short switch, the
|
||||
# long switch, the argument and the description.
|
||||
#
|
||||
|
||||
function complete_from_list
|
||||
|
||||
set condition $argv[1]
|
||||
set -e argv[1]
|
||||
|
||||
for j in $argv
|
||||
set exploded (echo $j|tr \t \n)
|
||||
set short $exploded[1]
|
||||
set long $exploded[2]
|
||||
set arg $exploded[3]
|
||||
set desc (cap (esc $exploded[4]))
|
||||
|
||||
set str
|
||||
|
||||
switch $short
|
||||
case '-?'
|
||||
set str $str -s (printf "%s\n" $short|cut -c 2)
|
||||
end
|
||||
|
||||
switch $long
|
||||
case '--?*'
|
||||
set str $str -l (printf "%s\n" $long|cut -c 3-)
|
||||
end
|
||||
|
||||
switch $arg
|
||||
case '=DIRECTORY' ' dir'
|
||||
set str $str -x -a "'(__fish_complete_directories (commandline -ct))'"
|
||||
|
||||
case '=COMMAND'
|
||||
set str $str -x -a "'(__fish_complete_command)'"
|
||||
|
||||
case '=USERNAME' ' <user>'
|
||||
set str $str -x -a "'(__fish_complete_users)'"
|
||||
|
||||
case '=FILENAME' '=FILE' ' <file>'
|
||||
set str $str -r
|
||||
|
||||
case ' arg'
|
||||
set str $str -x
|
||||
|
||||
case ' (*):'
|
||||
set str $str -x -a \'(echo $arg| sed -e "s/ (\(.*\)):/\1/" |tr '/' ' ')\'
|
||||
|
||||
case '?*'
|
||||
set str $str -x
|
||||
echo "Don't know how to handle arguments of type '$arg'" >&2
|
||||
end
|
||||
|
||||
switch $desc
|
||||
case '?*'
|
||||
set str $str --description \'$desc\'
|
||||
end
|
||||
|
||||
echo complete -c $cmd $condition $str
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
set cmd $argv[1]; or exit 1
|
||||
|
||||
echo '
|
||||
#
|
||||
# Completions for the '$cmd' command
|
||||
# This file was autogenerated by the file make_mercurial_completions.fish
|
||||
# which is shipped with the fish source code
|
||||
#
|
||||
|
||||
#
|
||||
# Completions from commandline
|
||||
#
|
||||
'
|
||||
set -e argv[1]
|
||||
|
||||
while count $argv >/dev/null
|
||||
echo $argv[1]
|
||||
set -e argv[1]
|
||||
end
|
||||
|
||||
|
||||
eval "function cmd; $cmd \$argv; end"
|
||||
|
||||
set -l cmd_str
|
||||
|
||||
switch $cmd
|
||||
case svn
|
||||
|
||||
function list_subcommand
|
||||
set cmd1 '\([^ ]*\)'
|
||||
set cmd2 '\([^,)]*\)'
|
||||
set cmdn '\(, \([^,)]*\)\|\)'
|
||||
set svn_re '^ *'$cmd1'\( ('$cmd2$cmdn$cmdn')\|\).*$'
|
||||
cmd help|sed -ne 's/'$svn_re'/\1\n\3\n\5\n\7/p'| grep .
|
||||
end
|
||||
|
||||
function list_subcommand_help
|
||||
set short_exp '\(-.\|\)'
|
||||
set long_exp '\(--[^ =,]*\)'
|
||||
set arg_exp '\(\|[= ][^ ][^ ]*\)'
|
||||
set desc_exp '\([\t ]*:[\t ]*\|\)\([^ ].*[^.]\)'
|
||||
set re "^ *$short_exp *$long_exp$arg_exp *$desc_exp\(\|\\.\)\$"
|
||||
cmd help $argv | sed -n -e 's/'$re'/\1\t\2\t\3\t\5/p'
|
||||
end
|
||||
|
||||
|
||||
for i in (list_subcommand)
|
||||
set desc (cmd help $i|head -n 1|sed -e 's/[^:]*: *\(.*[^.]\)\(\|\\.\)$/\1/')
|
||||
set desc (esc $desc)
|
||||
set cmd_str $cmd_str "-a $i --description '$desc'"
|
||||
end
|
||||
|
||||
case cvs
|
||||
|
||||
function list_subcommand
|
||||
cmd --help-commands 2>| sed -n -e 's/^ *\([^ ][^ ]*\) .*$/\1/p'
|
||||
end
|
||||
|
||||
set short_exp '\(-.\)'
|
||||
set arg_exp '\(\| [^ \t][^ \t]*\)'
|
||||
set desc_exp '\([\t ]*:[\t ]*\|\)\([^ ].*\)'
|
||||
set re '^[ \t]*'$short_exp$arg_exp'[ \t]*'$desc_exp'$'
|
||||
|
||||
function list_subcommand_help
|
||||
#'s/^[ \t]*\(-.\)[ \t]\([^- \t][^ \t]*\)*[ \t]*\([^-].*\)$/\1\t\2\t\3/p'
|
||||
|
||||
cmd -H $argv 2>| sed -n -e 's/'$re'/\1\t\t\2\t\4/p'
|
||||
end
|
||||
|
||||
echo '
|
||||
#
|
||||
# Global switches
|
||||
#
|
||||
'
|
||||
|
||||
complete_from_list "-n '__fish_use_subcommand'" (cmd --help-options 2>| sed -n -e 's/'$re'/\1\t\t\2\t\4/p')
|
||||
|
||||
set cmd_str_internal (cmd --help-commands 2>| sed -n -e 's/^ *\([^ ][^ ]*\)[\t ]*\([^ ].*\)$/\1\t\2/p')
|
||||
for i in $cmd_str_internal
|
||||
set exploded (echo $i|tr \t \n)
|
||||
set cmd_str $cmd_str "-a $exploded[1] --description '"(esc $exploded[2])"'"
|
||||
end
|
||||
|
||||
case '*'
|
||||
|
||||
function list_subcommand
|
||||
cmd help | sed -n -e 's/^ *\([^ ][^ ]*\) .*$/\1/p'
|
||||
end
|
||||
|
||||
function list_subcommand_help
|
||||
set short_exp '\(-.\|\)\( [^ -][^ ]*\|\)'
|
||||
set long_exp '\(--[^ =,]*\)'
|
||||
set arg_exp '\(\|[= ][^ ][^ ]*\)'
|
||||
set desc_exp '\([\t ]*:[\t ]*\|\)\([^ ].*[^.]\)'
|
||||
set re "^ *$short_exp *$long_exp$arg_exp *$desc_exp\(\|\\.\)\$"
|
||||
|
||||
cmd help $argv | sed -n -e 's/'$re'/\1\t\3\t\4\t\6/p'
|
||||
end
|
||||
|
||||
set cmd_str (cmd help | sed -n -e 's/^ *\([^ ][^ ]*\)[\t ]*\([^ ].*[^.]\)\(\|\\.\)$/-a \1 --description \'\2\'/p')
|
||||
|
||||
end
|
||||
|
||||
echo '
|
||||
#
|
||||
# subcommands
|
||||
#
|
||||
'
|
||||
|
||||
printf "complete -c $cmd -n '__fish_use_subcommand' -x %s\n" $cmd_str
|
||||
|
||||
for i in (list_subcommand)
|
||||
|
||||
echo '
|
||||
|
||||
#
|
||||
# Completions for the \''$i'\' subcommand
|
||||
#
|
||||
'
|
||||
|
||||
complete_from_list "-n 'contains \\'$i\\' (commandline -poc)'" (list_subcommand_help $i)
|
||||
end
|
||||
|
||||
echo \n\n
|
||||
14
mimedb.c
14
mimedb.c
@@ -46,6 +46,7 @@ license. Read the source code of the library for more information.
|
||||
#include "xdgmime.h"
|
||||
#include "fallback.h"
|
||||
#include "util.h"
|
||||
#include "print_help.h"
|
||||
|
||||
|
||||
/**
|
||||
@@ -138,12 +139,11 @@ static int launch_pos=0;
|
||||
/**
|
||||
gettext alias
|
||||
*/
|
||||
#ifdef USE_GETTEXT
|
||||
#define _(string) gettext(string)
|
||||
|
||||
/**
|
||||
Dynamically generated function, made from the documentation in doc_src.
|
||||
*/
|
||||
void print_help();
|
||||
#else
|
||||
#define _(string) (string)
|
||||
#endif
|
||||
|
||||
/**
|
||||
Call malloc, set error flag and print message on failure
|
||||
@@ -1258,7 +1258,7 @@ int main (int argc, char *argv[])
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
print_help();
|
||||
print_help( argv[0], 1 );
|
||||
exit(0);
|
||||
|
||||
case 'v':
|
||||
@@ -1274,7 +1274,7 @@ int main (int argc, char *argv[])
|
||||
if( ( output_type == LAUNCH )&&(input_type==MIMETYPE))
|
||||
{
|
||||
fprintf( stderr, _("%s: Can not launch a mimetype\n"), MIMEDB );
|
||||
print_help();
|
||||
print_help( argv[0], 2 );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
12
output.c
12
output.c
@@ -153,6 +153,16 @@ void set_color( int c, int c2 )
|
||||
int is_bold = 0;
|
||||
int is_underline = 0;
|
||||
|
||||
/*
|
||||
Test if we have at least basic support for setting fonts, colors
|
||||
and related bits - otherwise just give up...
|
||||
*/
|
||||
if( !exit_attribute_mode )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
is_bold |= (c&FISH_COLOR_BOLD)!=0;
|
||||
is_bold |= (c2&FISH_COLOR_BOLD)!=0;
|
||||
|
||||
@@ -367,7 +377,7 @@ int writech( wint_t ch )
|
||||
{
|
||||
mbstate_t state;
|
||||
int i;
|
||||
char buff[MB_CUR_MAX+1];
|
||||
char buff[MB_LEN_MAX+1];
|
||||
size_t bytes;
|
||||
|
||||
if( ( ch >= ENCODE_DIRECT_BASE) &&
|
||||
|
||||
1
output.h
1
output.h
@@ -126,5 +126,4 @@ void output_set_writer( int (*writer)(char) );
|
||||
|
||||
int (*output_get_writer())(char) ;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
129
parse_util.c
129
parse_util.c
@@ -97,7 +97,6 @@ int parse_util_lineno( const wchar_t *str, int len )
|
||||
static int res2 = 1;
|
||||
|
||||
CHECK( str, 0 );
|
||||
|
||||
|
||||
if( str != prev_str || i>len )
|
||||
{
|
||||
@@ -129,7 +128,9 @@ int parse_util_lineno( const wchar_t *str, int len )
|
||||
for( ; str[i] && i<len; i++ )
|
||||
{
|
||||
if( str[i] == L'\n' )
|
||||
{
|
||||
res++;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -169,13 +170,17 @@ int parse_util_locate_cmdsubst( const wchar_t *in,
|
||||
if( *pos == '(' )
|
||||
{
|
||||
if(( paran_count == 0)&&(paran_begin==0))
|
||||
{
|
||||
paran_begin = pos;
|
||||
}
|
||||
|
||||
paran_count++;
|
||||
}
|
||||
else if( *pos == ')' )
|
||||
{
|
||||
|
||||
paran_count--;
|
||||
|
||||
if( (paran_count == 0) && (paran_end == 0) )
|
||||
{
|
||||
paran_end = pos;
|
||||
@@ -208,9 +213,14 @@ int parse_util_locate_cmdsubst( const wchar_t *in,
|
||||
}
|
||||
|
||||
if( begin )
|
||||
{
|
||||
*begin = paran_begin;
|
||||
}
|
||||
|
||||
if( end )
|
||||
{
|
||||
*end = paran_count?(wchar_t *)in+wcslen(in):paran_end;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -228,9 +238,14 @@ void parse_util_cmdsubst_extent( const wchar_t *buff,
|
||||
CHECK( buff, );
|
||||
|
||||
if( a )
|
||||
{
|
||||
*a = (wchar_t *)buff;
|
||||
}
|
||||
|
||||
if( b )
|
||||
{
|
||||
*b = (wchar_t *)buff+wcslen(buff);
|
||||
}
|
||||
|
||||
pos = (wchar_t *)buff;
|
||||
|
||||
@@ -255,10 +270,17 @@ void parse_util_cmdsubst_extent( const wchar_t *buff,
|
||||
if(( begin < cursor ) && (end >= cursor) )
|
||||
{
|
||||
begin++;
|
||||
|
||||
if( a )
|
||||
{
|
||||
*a = begin;
|
||||
}
|
||||
|
||||
if( b )
|
||||
{
|
||||
*b = end;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -291,14 +313,21 @@ static void job_or_process_extent( const wchar_t *buff,
|
||||
CHECK( buff, );
|
||||
|
||||
if( a )
|
||||
{
|
||||
*a=0;
|
||||
}
|
||||
|
||||
if( b )
|
||||
{
|
||||
*b = 0;
|
||||
}
|
||||
|
||||
parse_util_cmdsubst_extent( buff, cursor_pos, &begin, &end );
|
||||
if( !end || !begin )
|
||||
{
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
pos = cursor_pos - (begin - buff);
|
||||
|
||||
if( a )
|
||||
@@ -327,9 +356,13 @@ static void job_or_process_extent( const wchar_t *buff,
|
||||
switch( tok_last_type( &tok ) )
|
||||
{
|
||||
case TOK_PIPE:
|
||||
{
|
||||
if( !process )
|
||||
{
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
case TOK_END:
|
||||
case TOK_BACKGROUND:
|
||||
{
|
||||
@@ -338,15 +371,19 @@ static void job_or_process_extent( const wchar_t *buff,
|
||||
{
|
||||
finished=1;
|
||||
if( b )
|
||||
{
|
||||
*b = (wchar_t *)buff + tok_begin;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( a )
|
||||
{
|
||||
*a = (wchar_t *)buff + tok_begin+1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -398,7 +435,9 @@ void parse_util_token_extent( const wchar_t *buff,
|
||||
parse_util_cmdsubst_extent( buff, cursor_pos, &begin, &end );
|
||||
|
||||
if( !end || !begin )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pos = cursor_pos - (begin - buff);
|
||||
|
||||
@@ -430,7 +469,9 @@ void parse_util_token_extent( const wchar_t *buff,
|
||||
Calculate end of token
|
||||
*/
|
||||
if( tok_last_type( &tok ) == TOK_STRING )
|
||||
{
|
||||
tok_end +=wcslen(tok_last(&tok));
|
||||
}
|
||||
|
||||
/*
|
||||
Cursor was before beginning of this token, means that the
|
||||
@@ -451,9 +492,6 @@ void parse_util_token_extent( const wchar_t *buff,
|
||||
{
|
||||
a = begin + tok_get_pos( &tok );
|
||||
b = a + wcslen(tok_last(&tok));
|
||||
|
||||
// fwprintf( stderr, L"Whee %ls\n", *a );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -472,14 +510,25 @@ void parse_util_token_extent( const wchar_t *buff,
|
||||
tok_destroy( &tok );
|
||||
|
||||
if( tok_begin )
|
||||
{
|
||||
*tok_begin = a;
|
||||
if( tok_end )
|
||||
*tok_end = b;
|
||||
if( prev_begin )
|
||||
*prev_begin = pa;
|
||||
if( prev_end )
|
||||
*prev_end = pb;
|
||||
}
|
||||
|
||||
if( tok_end )
|
||||
{
|
||||
*tok_end = b;
|
||||
}
|
||||
|
||||
if( prev_begin )
|
||||
{
|
||||
*prev_begin = pa;
|
||||
}
|
||||
|
||||
if( prev_end )
|
||||
{
|
||||
*prev_end = pb;
|
||||
}
|
||||
|
||||
assert( pa >= buff );
|
||||
assert( pa <= (buff+wcslen(buff) ) );
|
||||
assert( pb >= pa );
|
||||
@@ -560,7 +609,9 @@ void parse_util_load_reset( const wchar_t *path_var_name,
|
||||
void *key, *data;
|
||||
hash_remove( all_loaded, path_var_name, &key, &data );
|
||||
if( key )
|
||||
{
|
||||
clear_loaded_entry( key, data, (void *)on_load );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -600,6 +651,16 @@ int parse_util_unload( const wchar_t *cmd,
|
||||
return !!val;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Unload all autoloaded items that have expired, that where loaded in
|
||||
the specified path.
|
||||
|
||||
\param path_var_name The variable containing the path to autoload in
|
||||
\param skip unloading the the specified file
|
||||
\param on_load the callback function to call for every unloaded file
|
||||
|
||||
*/
|
||||
static void parse_util_autounload( const wchar_t *path_var_name,
|
||||
const wchar_t *skip,
|
||||
void (*on_load)(const wchar_t *cmd) )
|
||||
@@ -637,8 +698,10 @@ static void parse_util_autounload( const wchar_t *path_var_name,
|
||||
}
|
||||
|
||||
if( !tm[0] )
|
||||
{
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
if( hash_get( &loaded->is_loading, item ) )
|
||||
{
|
||||
continue;
|
||||
@@ -690,7 +753,6 @@ int parse_util_load( const wchar_t *cmd,
|
||||
// debug( 0, L"Autoload %ls in %ls", cmd, path_var_name );
|
||||
|
||||
parse_util_autounload( path_var_name, cmd, on_load );
|
||||
|
||||
path_var = env_get( path_var_name );
|
||||
|
||||
/*
|
||||
@@ -698,7 +760,6 @@ int parse_util_load( const wchar_t *cmd,
|
||||
*/
|
||||
if( !path_var )
|
||||
{
|
||||
// debug( 0, L"Path null" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -846,9 +907,13 @@ static int parse_util_load_internal( const wchar_t *cmd,
|
||||
}
|
||||
|
||||
if( !path )
|
||||
{
|
||||
path = sb_halloc( global_context );
|
||||
}
|
||||
else
|
||||
{
|
||||
sb_clear( path );
|
||||
}
|
||||
|
||||
/*
|
||||
Iterate over path searching for suitable completion files
|
||||
@@ -873,7 +938,9 @@ static int parse_util_load_internal( const wchar_t *cmd,
|
||||
{
|
||||
tm = malloc(sizeof(time_t)*2);
|
||||
if( !tm )
|
||||
{
|
||||
DIE_MEM();
|
||||
}
|
||||
}
|
||||
|
||||
tm[0] = buf.st_mtime;
|
||||
@@ -883,9 +950,10 @@ static int parse_util_load_internal( const wchar_t *cmd,
|
||||
tm );
|
||||
|
||||
if( on_load )
|
||||
{
|
||||
on_load(cmd );
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Source the completion file for the specified completion
|
||||
*/
|
||||
@@ -921,7 +989,9 @@ static int parse_util_load_internal( const wchar_t *cmd,
|
||||
{
|
||||
tm = malloc(sizeof(time_t)*2);
|
||||
if( !tm )
|
||||
{
|
||||
DIE_MEM();
|
||||
}
|
||||
|
||||
tm[0] = 0;
|
||||
tm[1] = time(0);
|
||||
@@ -942,7 +1012,9 @@ void parse_util_set_argv( wchar_t **argv )
|
||||
for( arg=argv; *arg; arg++ )
|
||||
{
|
||||
if( arg != argv )
|
||||
{
|
||||
sb_append( &sb, ARRAY_SEP_STR );
|
||||
}
|
||||
sb_append( &sb, *arg );
|
||||
}
|
||||
|
||||
@@ -965,13 +1037,16 @@ wchar_t *parse_util_unescape_wildcards( const wchar_t *str )
|
||||
unescaped = wcsdup(str);
|
||||
|
||||
if( !unescaped )
|
||||
{
|
||||
DIE_MEM();
|
||||
}
|
||||
|
||||
for( in=out=unescaped; *in; in++ )
|
||||
{
|
||||
switch( *in )
|
||||
{
|
||||
case L'\\':
|
||||
{
|
||||
if( *(in+1) )
|
||||
{
|
||||
in++;
|
||||
@@ -979,20 +1054,26 @@ wchar_t *parse_util_unescape_wildcards( const wchar_t *str )
|
||||
}
|
||||
*(out++)=*in;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
case L'*':
|
||||
{
|
||||
*(out++)=ANY_STRING;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
case L'?':
|
||||
{
|
||||
*(out++)=ANY_CHAR;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
*(out++)=*in;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return unescaped;
|
||||
}
|
||||
|
||||
420
parser.c
420
parser.c
@@ -1,6 +1,6 @@
|
||||
/** \file parser.c
|
||||
|
||||
The fish parser. Contains functions for parsing code.
|
||||
The fish parser. Contains functions for parsing and evaluating code.
|
||||
|
||||
*/
|
||||
|
||||
@@ -57,10 +57,9 @@ The fish parser. Contains functions for parsing code.
|
||||
#define MAX_RECURSION_DEPTH 128
|
||||
|
||||
/**
|
||||
Message about reporting bugs, used on weird internal error to
|
||||
hopefully get them to report stuff.
|
||||
Error message for unknown builtin
|
||||
*/
|
||||
#define BUGREPORT_MSG _( L"If this error can be reproduced, please send a bug report to %s.")
|
||||
#define UNKNOWN_BUILTIN_ERR_MSG _(L"Unknown builtin '%ls'")
|
||||
|
||||
/**
|
||||
Error message for improper use of the exec builtin
|
||||
@@ -113,6 +112,11 @@ The fish parser. Contains functions for parsing code.
|
||||
*/
|
||||
#define ILLEGAL_CMD_ERR_MSG _( L"Illegal command name '%ls'")
|
||||
|
||||
/**
|
||||
Error message when encountering an illegal file descriptor
|
||||
*/
|
||||
#define ILLEGAL_FD_ERR_MSG _( L"Illegal file descriptor '%ls'")
|
||||
|
||||
/**
|
||||
Error message for wildcards with no matches
|
||||
*/
|
||||
@@ -131,7 +135,7 @@ The fish parser. Contains functions for parsing code.
|
||||
/**
|
||||
Error when using return builtin outside of function definition
|
||||
*/
|
||||
#define INVALID_RETURN_ERR_MSG _( L"'return' command command outside of function definition" )
|
||||
#define INVALID_RETURN_ERR_MSG _( L"'return' builtin command outside of function definition" )
|
||||
|
||||
/**
|
||||
Error when using else builtin outside of if block
|
||||
@@ -474,11 +478,9 @@ void parser_pop_block()
|
||||
if( !current_block )
|
||||
{
|
||||
debug( 1,
|
||||
L"function %s called on empty block stack. "
|
||||
L"This is a bug. "
|
||||
L"If you can reproduce it, please send a bug report to %s.",
|
||||
__func__,
|
||||
PACKAGE_BUGREPORT ); \
|
||||
L"function %s called on empty block stack.",
|
||||
__func__);
|
||||
bugreport();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -513,6 +515,15 @@ static int parser_skip_arguments( const wchar_t *cmd )
|
||||
(void *)0 );
|
||||
}
|
||||
|
||||
int parser_is_switch( const wchar_t *cmd )
|
||||
{
|
||||
if( wcscmp( cmd, L"--" ) == 0 )
|
||||
return ARG_SKIP;
|
||||
else
|
||||
return cmd[0] == L'-';
|
||||
}
|
||||
|
||||
|
||||
int parser_is_subcommand( const wchar_t *cmd )
|
||||
{
|
||||
|
||||
@@ -1360,6 +1371,8 @@ static void parse_job_argument_list( process_t *p,
|
||||
{
|
||||
case TOK_PIPE:
|
||||
{
|
||||
wchar_t *end;
|
||||
|
||||
if( (p->type == INTERNAL_EXEC) )
|
||||
{
|
||||
error( SYNTAX_ERROR,
|
||||
@@ -1367,14 +1380,22 @@ static void parse_job_argument_list( process_t *p,
|
||||
EXEC_ERR_MSG );
|
||||
return;
|
||||
}
|
||||
p->pipe_fd = wcstol( tok_last( tok ), 0, 10 );
|
||||
|
||||
errno = 0;
|
||||
p->pipe_write_fd = wcstol( tok_last( tok ), &end, 10 );
|
||||
if( p->pipe_write_fd < 0 || errno || *end )
|
||||
{
|
||||
error( SYNTAX_ERROR,
|
||||
tok_get_pos( tok ),
|
||||
ILLEGAL_FD_ERR_MSG,
|
||||
tok_last( tok ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if( !p->argv )
|
||||
halloc_register( j, p->argv = list_to_char_arr( args ) );
|
||||
p->next = halloc( j, sizeof( process_t ) );
|
||||
if( p->next == 0 )
|
||||
{
|
||||
DIE_MEM();
|
||||
}
|
||||
|
||||
tok_next( tok );
|
||||
|
||||
/*
|
||||
@@ -1499,7 +1520,8 @@ static void parse_job_argument_list( process_t *p,
|
||||
int type = tok_last_type( tok );
|
||||
io_data_t *new_io;
|
||||
wchar_t *target = 0;
|
||||
|
||||
wchar_t *end;
|
||||
|
||||
/*
|
||||
Don't check redirections in skipped part
|
||||
|
||||
@@ -1524,93 +1546,109 @@ static void parse_job_argument_list( process_t *p,
|
||||
if( !new_io )
|
||||
DIE_MEM();
|
||||
|
||||
errno = 0;
|
||||
new_io->fd = wcstol( tok_last( tok ),
|
||||
0,
|
||||
&end,
|
||||
10 );
|
||||
tok_next( tok );
|
||||
|
||||
switch( tok_last_type( tok ) )
|
||||
if( new_io->fd < 0 || errno || *end )
|
||||
{
|
||||
case TOK_STRING:
|
||||
{
|
||||
target = (wchar_t *)expand_one( j, wcsdup( tok_last( tok ) ), 0);
|
||||
|
||||
if( target == 0 && error_code == 0 )
|
||||
{
|
||||
error( SYNTAX_ERROR,
|
||||
tok_get_pos( tok ),
|
||||
REDIRECT_TOKEN_ERR_MSG,
|
||||
tok_last( tok ) );
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
error( SYNTAX_ERROR,
|
||||
tok_get_pos( tok ),
|
||||
REDIRECT_TOKEN_ERR_MSG,
|
||||
tok_get_desc( tok_last_type(tok)) );
|
||||
}
|
||||
|
||||
if( target == 0 || wcslen( target )==0 )
|
||||
{
|
||||
if( error_code == 0 )
|
||||
error( SYNTAX_ERROR,
|
||||
tok_get_pos( tok ),
|
||||
_(L"Invalid IO redirection") );
|
||||
tok_next(tok);
|
||||
error( SYNTAX_ERROR,
|
||||
tok_get_pos( tok ),
|
||||
ILLEGAL_FD_ERR_MSG,
|
||||
tok_last( tok ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
tok_next( tok );
|
||||
|
||||
|
||||
switch( type )
|
||||
switch( tok_last_type( tok ) )
|
||||
{
|
||||
case TOK_REDIRECT_APPEND:
|
||||
new_io->io_mode = IO_FILE;
|
||||
new_io->param2.flags = O_CREAT | O_APPEND | O_WRONLY;
|
||||
new_io->param1.filename = target;
|
||||
break;
|
||||
|
||||
case TOK_REDIRECT_OUT:
|
||||
new_io->io_mode = IO_FILE;
|
||||
new_io->param2.flags = O_CREAT | O_WRONLY | O_TRUNC;
|
||||
new_io->param1.filename = target;
|
||||
break;
|
||||
|
||||
case TOK_REDIRECT_IN:
|
||||
new_io->io_mode = IO_FILE;
|
||||
new_io->param2.flags = O_RDONLY;
|
||||
new_io->param1.filename = target;
|
||||
break;
|
||||
|
||||
case TOK_REDIRECT_FD:
|
||||
case TOK_STRING:
|
||||
{
|
||||
if( wcscmp( target, L"-" ) == 0 )
|
||||
{
|
||||
new_io->io_mode = IO_CLOSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_io->io_mode = IO_FD;
|
||||
new_io->param1.old_fd = wcstol( target,
|
||||
0,
|
||||
10 );
|
||||
if( ( new_io->param1.old_fd < 0 ) ||
|
||||
( new_io->param1.old_fd > 10 ) )
|
||||
{
|
||||
error( SYNTAX_ERROR,
|
||||
tok_get_pos( tok ),
|
||||
_(L"Requested redirection to something that is not a file descriptor %ls"),
|
||||
target );
|
||||
target = (wchar_t *)expand_one( j, wcsdup( tok_last( tok ) ), 0);
|
||||
|
||||
if( target == 0 && error_code == 0 )
|
||||
{
|
||||
error( SYNTAX_ERROR,
|
||||
tok_get_pos( tok ),
|
||||
REDIRECT_TOKEN_ERR_MSG,
|
||||
tok_last( tok ) );
|
||||
|
||||
tok_next(tok);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
error( SYNTAX_ERROR,
|
||||
tok_get_pos( tok ),
|
||||
REDIRECT_TOKEN_ERR_MSG,
|
||||
tok_get_desc( tok_last_type(tok)) );
|
||||
}
|
||||
|
||||
if( target == 0 || wcslen( target )==0 )
|
||||
{
|
||||
if( error_code == 0 )
|
||||
error( SYNTAX_ERROR,
|
||||
tok_get_pos( tok ),
|
||||
_(L"Invalid IO redirection") );
|
||||
tok_next(tok);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case TOK_REDIRECT_APPEND:
|
||||
new_io->io_mode = IO_FILE;
|
||||
new_io->param2.flags = O_CREAT | O_APPEND | O_WRONLY;
|
||||
new_io->param1.filename = target;
|
||||
break;
|
||||
|
||||
case TOK_REDIRECT_OUT:
|
||||
new_io->io_mode = IO_FILE;
|
||||
new_io->param2.flags = O_CREAT | O_WRONLY | O_TRUNC;
|
||||
new_io->param1.filename = target;
|
||||
break;
|
||||
|
||||
case TOK_REDIRECT_IN:
|
||||
new_io->io_mode = IO_FILE;
|
||||
new_io->param2.flags = O_RDONLY;
|
||||
new_io->param1.filename = target;
|
||||
break;
|
||||
|
||||
case TOK_REDIRECT_FD:
|
||||
{
|
||||
if( wcscmp( target, L"-" ) == 0 )
|
||||
{
|
||||
new_io->io_mode = IO_CLOSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
wchar_t *end;
|
||||
|
||||
new_io->io_mode = IO_FD;
|
||||
errno = 0;
|
||||
|
||||
new_io->param1.old_fd = wcstol( target,
|
||||
&end,
|
||||
10 );
|
||||
|
||||
if( ( new_io->param1.old_fd < 0 ) ||
|
||||
errno || *end )
|
||||
{
|
||||
error( SYNTAX_ERROR,
|
||||
tok_get_pos( tok ),
|
||||
_(L"Requested redirection to something that is not a file descriptor %ls"),
|
||||
target );
|
||||
|
||||
tok_next(tok);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1671,14 +1709,14 @@ static void parse_job_argument_list( process_t *p,
|
||||
}
|
||||
|
||||
/*
|
||||
static void print_block_stack( block_t *b )
|
||||
{
|
||||
if( !b )
|
||||
return;
|
||||
print_block_stack( b->outer );
|
||||
static void print_block_stack( block_t *b )
|
||||
{
|
||||
if( !b )
|
||||
return;
|
||||
print_block_stack( b->outer );
|
||||
|
||||
debug( 0, L"Block type %ls, skip: %d", parser_get_block_desc( b->type ), b->skip );
|
||||
}
|
||||
debug( 0, L"Block type %ls, skip: %d", parser_get_block_desc( b->type ), b->skip );
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -1697,6 +1735,7 @@ static int parse_job( process_t *p,
|
||||
array_list_t *args = al_halloc( j ); // The list that will become the argc array for the program
|
||||
int use_function = 1; // May functions be considered when checking what action this command represents
|
||||
int use_builtin = 1; // May builtins be considered when checking what action this command represents
|
||||
int use_command = 1; // May commands be considered when checking what action this command represents
|
||||
int is_new_block=0; // Does this command create a new block?
|
||||
|
||||
block_t *prev_block = current_block;
|
||||
@@ -1778,80 +1817,19 @@ static int parse_job( process_t *p,
|
||||
|
||||
mark = tok_get_pos( tok );
|
||||
|
||||
/*
|
||||
Test if this command is one of the many special builtins
|
||||
that work directly on the parser, like e.g. 'not', that
|
||||
simply flips the status inversion flag in the job.
|
||||
*/
|
||||
if( wcscmp( L"command", nxt )==0 )
|
||||
{
|
||||
tok_next( tok );
|
||||
if( parser_is_help( tok_last( tok ), 0 ) )
|
||||
{
|
||||
tok_set_pos( tok, mark);
|
||||
}
|
||||
else
|
||||
{
|
||||
use_function = 0;
|
||||
use_builtin=0;
|
||||
consumed=1;
|
||||
}
|
||||
}
|
||||
else if( wcscmp( L"builtin", nxt )==0 )
|
||||
{
|
||||
tok_next( tok );
|
||||
if( tok_last(tok)[0] == L'-' )
|
||||
{
|
||||
tok_set_pos( tok, mark);
|
||||
}
|
||||
else
|
||||
{
|
||||
use_function = 0;
|
||||
consumed=1;
|
||||
}
|
||||
}
|
||||
else if( wcscmp( L"not", nxt )==0 )
|
||||
{
|
||||
tok_next( tok );
|
||||
if( tok_last(tok)[0] == L'-' )
|
||||
{
|
||||
tok_set_pos( tok, mark);
|
||||
}
|
||||
else
|
||||
{
|
||||
job_set_flag( j, JOB_NEGATE, !job_get_flag( j, JOB_NEGATE ) );
|
||||
consumed=1;
|
||||
}
|
||||
}
|
||||
else if( wcscmp( L"and", nxt )==0 )
|
||||
{
|
||||
tok_next( tok );
|
||||
if( tok_last(tok)[0] == L'-' )
|
||||
{
|
||||
tok_set_pos( tok, mark);
|
||||
}
|
||||
else
|
||||
{
|
||||
job_set_flag( j, JOB_SKIP, proc_get_last_status());
|
||||
consumed=1;
|
||||
}
|
||||
}
|
||||
else if( wcscmp( L"or", nxt )==0 )
|
||||
{
|
||||
tok_next( tok );
|
||||
if( tok_last(tok)[0] == L'-' )
|
||||
{
|
||||
tok_set_pos( tok, mark);
|
||||
}
|
||||
else
|
||||
{
|
||||
job_set_flag( j, JOB_SKIP, !proc_get_last_status());
|
||||
consumed=1;
|
||||
}
|
||||
}
|
||||
else if( wcscmp( L"exec", nxt )==0 )
|
||||
{
|
||||
if( p != j->first_process )
|
||||
if( contains_str( nxt,
|
||||
L"command",
|
||||
L"builtin",
|
||||
L"not",
|
||||
L"and",
|
||||
L"or",
|
||||
L"exec",
|
||||
(void *)0 ) )
|
||||
{
|
||||
int sw;
|
||||
int is_exec = (wcscmp( L"exec", nxt )==0);
|
||||
|
||||
if( is_exec && (p != j->first_process) )
|
||||
{
|
||||
error( SYNTAX_ERROR,
|
||||
tok_get_pos( tok ),
|
||||
@@ -1861,17 +1839,55 @@ static int parse_job( process_t *p,
|
||||
}
|
||||
|
||||
tok_next( tok );
|
||||
if( tok_last(tok)[0] == L'-' )
|
||||
sw = parser_is_switch( tok_last( tok ) );
|
||||
|
||||
if( sw == ARG_SWITCH )
|
||||
{
|
||||
tok_set_pos( tok, mark);
|
||||
}
|
||||
else
|
||||
{
|
||||
use_function = 0;
|
||||
use_builtin=0;
|
||||
p->type=INTERNAL_EXEC;
|
||||
if( sw == ARG_SKIP )
|
||||
{
|
||||
tok_next( tok );
|
||||
}
|
||||
|
||||
consumed=1;
|
||||
current_tokenizer_pos = prev_tokenizer_pos;
|
||||
|
||||
if( ( wcscmp( L"command", nxt )==0 ) ||
|
||||
( wcscmp( L"builtin", nxt )==0 ) )
|
||||
{
|
||||
use_function = 0;
|
||||
if( wcscmp( L"command", nxt )==0 )
|
||||
{
|
||||
use_builtin = 0;
|
||||
use_command = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
use_builtin = 1;
|
||||
use_command = 0;
|
||||
}
|
||||
}
|
||||
else if( wcscmp( L"not", nxt )==0 )
|
||||
{
|
||||
job_set_flag( j, JOB_NEGATE, !job_get_flag( j, JOB_NEGATE ) );
|
||||
}
|
||||
else if( wcscmp( L"and", nxt )==0 )
|
||||
{
|
||||
job_set_flag( j, JOB_SKIP, proc_get_last_status());
|
||||
}
|
||||
else if( wcscmp( L"or", nxt )==0 )
|
||||
{
|
||||
job_set_flag( j, JOB_SKIP, !proc_get_last_status());
|
||||
}
|
||||
else if( is_exec )
|
||||
{
|
||||
use_function = 0;
|
||||
use_builtin=0;
|
||||
p->type=INTERNAL_EXEC;
|
||||
current_tokenizer_pos = prev_tokenizer_pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( wcscmp( L"while", nxt ) ==0 )
|
||||
@@ -1989,8 +2005,8 @@ static int parse_job( process_t *p,
|
||||
is_new_block |= parser_is_block( (wchar_t *)al_get( args, 0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( !p->type || (p->type == INTERNAL_EXEC) )
|
||||
|
||||
if( (!p->type || (p->type == INTERNAL_EXEC) ) )
|
||||
{
|
||||
/*
|
||||
If we are not executing the current block, allow
|
||||
@@ -2029,7 +2045,7 @@ static int parse_job( process_t *p,
|
||||
If we have defined a wrapper around cd, use it,
|
||||
otherwise use the cd builtin
|
||||
*/
|
||||
if( function_exists( L"cd" ) )
|
||||
if( use_function && function_exists( L"cd" ) )
|
||||
p->type = INTERNAL_FUNCTION;
|
||||
else
|
||||
p->type = INTERNAL_BUILTIN;
|
||||
@@ -2114,8 +2130,17 @@ static int parse_job( process_t *p,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( (p->type == EXTERNAL) && !use_command )
|
||||
{
|
||||
error( SYNTAX_ERROR,
|
||||
tok_get_pos( tok ),
|
||||
UNKNOWN_BUILTIN_ERR_MSG,
|
||||
al_get( args, al_get_count( args ) -1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( is_new_block )
|
||||
{
|
||||
|
||||
@@ -2310,6 +2335,8 @@ static void eval_job( tokenizer *tok )
|
||||
if( profile )
|
||||
{
|
||||
p=malloc( sizeof(profile_element_t));
|
||||
if( !p )
|
||||
DIE_MEM();
|
||||
p->cmd=0;
|
||||
al_push( &profile_data, p );
|
||||
p->skipped=1;
|
||||
@@ -2521,9 +2548,7 @@ int eval( const wchar_t *cmd, io_data_t *io, int block_type )
|
||||
{
|
||||
debug( 1,
|
||||
EVAL_NULL_ERR_MSG );
|
||||
debug( 1,
|
||||
BUGREPORT_MSG,
|
||||
PACKAGE_BUGREPORT );
|
||||
bugreport();
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -2533,10 +2558,7 @@ int eval( const wchar_t *cmd, io_data_t *io, int block_type )
|
||||
debug( 1,
|
||||
INVALID_SCOPE_ERR_MSG,
|
||||
parser_get_block_desc( block_type ) );
|
||||
|
||||
debug( 1,
|
||||
BUGREPORT_MSG,
|
||||
PACKAGE_BUGREPORT );
|
||||
bugreport();
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -2570,16 +2592,14 @@ int eval( const wchar_t *cmd, io_data_t *io, int block_type )
|
||||
{
|
||||
debug( 0,
|
||||
_(L"End of block mismatch. Program terminating.") );
|
||||
debug( 0,
|
||||
BUGREPORT_MSG,
|
||||
PACKAGE_BUGREPORT );
|
||||
exit(1);
|
||||
bugreport();
|
||||
FATAL_EXIT();
|
||||
break;
|
||||
}
|
||||
|
||||
if( (!error_code) && (!exit_status()) && (!proc_get_last_status()) )
|
||||
{
|
||||
char *h;
|
||||
wchar_t *h;
|
||||
|
||||
//debug( 2, L"Status %d\n", proc_get_last_status() );
|
||||
|
||||
@@ -2591,7 +2611,7 @@ int eval( const wchar_t *cmd, io_data_t *io, int block_type )
|
||||
|
||||
h = builtin_help_get( L"end" );
|
||||
if( h )
|
||||
fwprintf( stderr, L"%s", h );
|
||||
fwprintf( stderr, L"%ls", h );
|
||||
break;
|
||||
|
||||
}
|
||||
@@ -2946,6 +2966,7 @@ int parser_test( const wchar_t * buff,
|
||||
{
|
||||
if( !had_cmd )
|
||||
{
|
||||
int is_else;
|
||||
int mark = tok_get_pos( &tok );
|
||||
had_cmd = 1;
|
||||
arg_count=0;
|
||||
@@ -3002,6 +3023,8 @@ int parser_test( const wchar_t * buff,
|
||||
tok_set_pos( &tok, mark );
|
||||
}
|
||||
|
||||
is_else = wcscmp(cmd, L"else")==0;
|
||||
|
||||
/*
|
||||
Store the block level. This needs to be done
|
||||
_after_ checking for end commands, but _before_
|
||||
@@ -3009,10 +3032,9 @@ int parser_test( const wchar_t * buff,
|
||||
*/
|
||||
if( block_level )
|
||||
{
|
||||
block_level[tok_get_pos( &tok )] = count;
|
||||
block_level[tok_get_pos( &tok )] = count + (is_else?-1:0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Handle block commands
|
||||
*/
|
||||
@@ -3105,7 +3127,7 @@ int parser_test( const wchar_t * buff,
|
||||
|
||||
if( out )
|
||||
{
|
||||
char *h;
|
||||
wchar_t *h;
|
||||
|
||||
error( SYNTAX_ERROR,
|
||||
tok_get_pos( &tok ),
|
||||
@@ -3114,7 +3136,7 @@ int parser_test( const wchar_t * buff,
|
||||
print_errors( out, prefix);
|
||||
h = builtin_help_get( L"case" );
|
||||
if( h )
|
||||
sb_printf( out, L"%s", h );
|
||||
sb_printf( out, L"%ls", h );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3268,7 +3290,7 @@ int parser_test( const wchar_t * buff,
|
||||
err = 1;
|
||||
if( out )
|
||||
{
|
||||
char *h;
|
||||
wchar_t *h;
|
||||
|
||||
error( SYNTAX_ERROR,
|
||||
tok_get_pos( &tok ),
|
||||
@@ -3276,7 +3298,7 @@ int parser_test( const wchar_t * buff,
|
||||
print_errors( out, prefix );
|
||||
h = builtin_help_get( L"end" );
|
||||
if( h )
|
||||
sb_printf( out, L"%s", h );
|
||||
sb_printf( out, L"%ls", h );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3547,7 +3569,7 @@ int parser_test( const wchar_t * buff,
|
||||
|
||||
if( out && count>0 )
|
||||
{
|
||||
const char *h;
|
||||
const wchar_t *h;
|
||||
const wchar_t *cmd;
|
||||
|
||||
error( SYNTAX_ERROR,
|
||||
@@ -3562,7 +3584,7 @@ int parser_test( const wchar_t * buff,
|
||||
h = builtin_help_get( cmd );
|
||||
if( cmd )
|
||||
{
|
||||
sb_printf( out, L"%s", h );
|
||||
sb_printf( out, L"%ls", h );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
18
parser.h
18
parser.h
@@ -15,6 +15,17 @@
|
||||
#define PARSER_TEST_ERROR 1
|
||||
#define PARSER_TEST_INCOMPLETE 2
|
||||
|
||||
/**
|
||||
REturn valuse for parser_is_switch()
|
||||
*/
|
||||
enum
|
||||
{
|
||||
ARG_NON_SWITCH,
|
||||
ARG_SWITCH,
|
||||
ARG_SKIP
|
||||
}
|
||||
;
|
||||
|
||||
/**
|
||||
event_block_t represents a block on events of the specified type
|
||||
*/
|
||||
@@ -220,6 +231,13 @@ int eval_args( const wchar_t *line,
|
||||
void error( int ec, int p, const wchar_t *str, ... );
|
||||
|
||||
|
||||
/**
|
||||
Check if the specified argument is a switch. Return ARG_SWITCH if yes,
|
||||
ARG_NON_SWITCH if no and ARG_SKIP if the argument is '--'
|
||||
*/
|
||||
int parser_is_switch( const wchar_t *cmd );
|
||||
|
||||
|
||||
/**
|
||||
Tests if the specified commands parameters should be interpreted as another command, which will be true if the command is either 'command', 'exec', 'if', 'while' or 'builtin'.
|
||||
|
||||
|
||||
22
print_help.c
Normal file
22
print_help.c
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
/** \file print_help.c
|
||||
Print help message for the specified command
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#include "print_help.h"
|
||||
|
||||
#define CMD_LEN 1024
|
||||
|
||||
void print_help( char *c, int fd )
|
||||
{
|
||||
char cmd[ CMD_LEN];
|
||||
int printed = snprintf( cmd, CMD_LEN, "fish -c '__fish_print_help %s >&%d'", c, fd );
|
||||
|
||||
if( printed < CMD_LEN )
|
||||
system( cmd );
|
||||
|
||||
}
|
||||
15
print_help.h
Normal file
15
print_help.h
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
/** \file print_help.h
|
||||
Print help message for the specified command
|
||||
*/
|
||||
|
||||
#ifndef FISH_PRINT_HELP_H
|
||||
#define FISH_PRINT_HELP_H
|
||||
|
||||
/**
|
||||
Print help message for the specified command
|
||||
*/
|
||||
|
||||
void print_help( char *cmd, int fd );
|
||||
|
||||
#endif
|
||||
36
proc.c
36
proc.c
@@ -301,6 +301,40 @@ int job_get_flag( job_t *j, int flag )
|
||||
return j->flags&flag?1:0;
|
||||
}
|
||||
|
||||
int job_signal( job_t *j, int signal )
|
||||
{
|
||||
pid_t my_pid = getpid();
|
||||
int res = 0;
|
||||
|
||||
if( j->pgid != my_pid )
|
||||
{
|
||||
res = killpg( j->pgid, SIGHUP );
|
||||
}
|
||||
else
|
||||
{
|
||||
process_t *p;
|
||||
|
||||
for( p = j->first_process; p; p=p->next )
|
||||
{
|
||||
if( ! p->completed )
|
||||
{
|
||||
if( p->pid )
|
||||
{
|
||||
if( kill( p->pid, SIGHUP ) )
|
||||
{
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Store the status of the process pid that was returned by waitpid.
|
||||
@@ -879,7 +913,7 @@ static int terminal_give_to_job( job_t *j, int cont )
|
||||
}
|
||||
|
||||
/**
|
||||
REturns contol of the terminal
|
||||
Returns contol of the terminal to the shell
|
||||
*/
|
||||
static int terminal_return_from_job( job_t *j)
|
||||
{
|
||||
|
||||
16
proc.h
16
proc.h
@@ -35,7 +35,12 @@
|
||||
#define STATUS_EXEC_FAIL 125
|
||||
|
||||
/**
|
||||
The status code use for erroneous argument combinations in a builtin
|
||||
The status code used for normal exit in a builtin
|
||||
*/
|
||||
#define STATUS_BUILTIN_OK 0
|
||||
|
||||
/**
|
||||
The status code used for erroneous argument combinations in a builtin
|
||||
*/
|
||||
#define STATUS_BUILTIN_ERROR 1
|
||||
|
||||
@@ -128,7 +133,9 @@ typedef struct process
|
||||
/** process ID */
|
||||
pid_t pid;
|
||||
/** File descriptor that pipe output should bind to */
|
||||
int pipe_fd;
|
||||
int pipe_write_fd;
|
||||
/** File descriptor that the _next_ process pipe input should bind to */
|
||||
int pipe_read_fd;
|
||||
/** true if process has completed */
|
||||
volatile int completed;
|
||||
/** true if process has stopped */
|
||||
@@ -366,6 +373,11 @@ int job_reap( int interactive );
|
||||
*/
|
||||
void job_handle_signal( int signal, siginfo_t *info, void *con );
|
||||
|
||||
/**
|
||||
Send the specified signal to all processes in the specified job.
|
||||
*/
|
||||
int job_signal( job_t *j, int signal );
|
||||
|
||||
#ifdef HAVE__PROC_SELF_STAT
|
||||
/**
|
||||
Use the procfs filesystem to look up how many jiffies of cpu time
|
||||
|
||||
208
reader.c
208
reader.c
@@ -37,6 +37,7 @@ commence.
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/poll.h>
|
||||
@@ -114,6 +115,8 @@ commence.
|
||||
*/
|
||||
#define DEFAULT_PROMPT L"whoami; echo @; hostname|cut -d . -f 1; echo \" \"; pwd; printf '> ';"
|
||||
|
||||
#define PROMPT_FUNCTION_NAME L"fish_prompt"
|
||||
|
||||
/**
|
||||
The default title for the reader. This is used by reader_readline.
|
||||
*/
|
||||
@@ -132,8 +135,8 @@ commence.
|
||||
|
||||
/**
|
||||
A struct describing the state of the interactive reader. These
|
||||
states can be stacked, in case reader_readline is called from
|
||||
input_read().
|
||||
states can be stacked, in case reader_readline() calls are
|
||||
nested. This happens when the 'read' builtin is used.
|
||||
*/
|
||||
typedef struct reader_data
|
||||
{
|
||||
@@ -253,6 +256,12 @@ typedef struct reader_data
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
Flag for ending non-interactive shell
|
||||
@@ -397,11 +406,17 @@ static void reader_kill( wchar_t *begin, int length, int mode, int new )
|
||||
void reader_handle_int( int sig )
|
||||
{
|
||||
block_t *c = current_block;
|
||||
while( c )
|
||||
|
||||
if( !is_interactive_read )
|
||||
{
|
||||
c->skip=1;
|
||||
c=c->outer;
|
||||
while( c )
|
||||
{
|
||||
c->type=FAKE;
|
||||
c->skip=1;
|
||||
c=c->outer;
|
||||
}
|
||||
}
|
||||
|
||||
interrupted = 1;
|
||||
|
||||
}
|
||||
@@ -692,7 +707,7 @@ static int insert_str(wchar_t *str)
|
||||
{
|
||||
memmove( &data->buff[data->buff_pos+len],
|
||||
&data->buff[data->buff_pos],
|
||||
sizeof(wchar_t)*(data->buff_len-data->buff_pos) );
|
||||
sizeof(wchar_t)*(old_len-data->buff_pos) );
|
||||
}
|
||||
memmove( &data->buff[data->buff_pos], str, sizeof(wchar_t)*len );
|
||||
data->buff_pos += len;
|
||||
@@ -974,14 +989,15 @@ static void run_pager( wchar_t *prefix, int is_quoted, array_list_t *comp )
|
||||
sb_init( &cmd );
|
||||
sb_init( &msg );
|
||||
sb_printf( &cmd,
|
||||
L"fish_pager %d %ls",
|
||||
L"fish_pager -c 3 -r 4 %ls -p %ls",
|
||||
// L"valgrind --track-fds=yes --log-file=pager.txt --leak-check=full ./fish_pager %d %ls",
|
||||
is_quoted,
|
||||
is_quoted?L"-q":L"",
|
||||
prefix_esc );
|
||||
|
||||
free( prefix_esc );
|
||||
|
||||
io_data_t *in= io_buffer_create( 1 );
|
||||
in->fd = 3;
|
||||
|
||||
for( i=0; i<al_get_count( comp); i++ )
|
||||
{
|
||||
@@ -998,7 +1014,7 @@ static void run_pager( wchar_t *prefix, int is_quoted, array_list_t *comp )
|
||||
|
||||
io_data_t *out = io_buffer_create( 0 );
|
||||
out->next = in;
|
||||
out->fd = 1;
|
||||
out->fd = 4;
|
||||
|
||||
eval( (wchar_t *)cmd.buff, out, TOP);
|
||||
term_steal();
|
||||
@@ -1028,6 +1044,35 @@ static void run_pager( wchar_t *prefix, int is_quoted, array_list_t *comp )
|
||||
io_buffer_destroy( in);
|
||||
}
|
||||
|
||||
/*
|
||||
Flash the screen. This function only changed the color of the
|
||||
current line, since the flash_screen sequnce is rather painful to
|
||||
look at in most terminal emulators.
|
||||
*/
|
||||
static void reader_flash()
|
||||
{
|
||||
struct timespec pollint;
|
||||
|
||||
int i;
|
||||
|
||||
for( i=0; i<data->buff_pos; i++ )
|
||||
{
|
||||
data->color[i] = HIGHLIGHT_SEARCH_MATCH<<16;
|
||||
}
|
||||
|
||||
repaint();
|
||||
|
||||
pollint.tv_sec = 0;
|
||||
pollint.tv_nsec = 100 * 1000000;
|
||||
nanosleep( &pollint, NULL );
|
||||
|
||||
reader_super_highlight_me_plenty( data->buff_pos, 0 );
|
||||
repaint();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Handle the list of completions. This means the following:
|
||||
|
||||
@@ -1050,8 +1095,7 @@ static int handle_completions( array_list_t *comp )
|
||||
|
||||
if( al_get_count( comp ) == 0 )
|
||||
{
|
||||
if( flash_screen != 0 )
|
||||
writembs( flash_screen );
|
||||
reader_flash();
|
||||
return 0;
|
||||
}
|
||||
else if( al_get_count( comp ) == 1 )
|
||||
@@ -1368,12 +1412,31 @@ static void handle_token_history( int forward, int reset )
|
||||
{
|
||||
if( current_pos == -1 )
|
||||
{
|
||||
const wchar_t *item;
|
||||
|
||||
/*
|
||||
Move to previous line
|
||||
*/
|
||||
free( (void *)data->token_history_buff );
|
||||
data->token_history_buff = wcsdup( history_prev_match(L"") );
|
||||
free( (void *)data->token_history_buff );
|
||||
|
||||
/*
|
||||
Search for previous item that contains this substring
|
||||
*/
|
||||
item = history_prev_match(data->search_buff);
|
||||
|
||||
/*
|
||||
If there is no match, the original string is returned
|
||||
|
||||
If so, we clear the match string to avoid infinite loop
|
||||
*/
|
||||
if( wcscmp( item, data->search_buff ) == 0 )
|
||||
{
|
||||
item=L"";
|
||||
}
|
||||
|
||||
data->token_history_buff = wcsdup( item );
|
||||
current_pos = wcslen(data->token_history_buff);
|
||||
|
||||
}
|
||||
|
||||
if( ! wcslen( data->token_history_buff ) )
|
||||
@@ -1397,7 +1460,7 @@ static void handle_token_history( int forward, int reset )
|
||||
else
|
||||
{
|
||||
|
||||
debug( 3, L"new '%ls'", data->token_history_buff );
|
||||
//debug( 3, L"new '%ls'", data->token_history_buff );
|
||||
|
||||
for( tok_init( &tok, data->token_history_buff, TOK_ACCEPT_UNFINISHED );
|
||||
tok_has_next( &tok);
|
||||
@@ -1409,12 +1472,12 @@ static void handle_token_history( int forward, int reset )
|
||||
{
|
||||
if( wcsstr( tok_last( &tok ), data->search_buff ) )
|
||||
{
|
||||
debug( 3, L"Found token at pos %d\n", tok_get_pos( &tok ) );
|
||||
//debug( 3, L"Found token at pos %d\n", tok_get_pos( &tok ) );
|
||||
if( tok_get_pos( &tok ) >= current_pos )
|
||||
{
|
||||
break;
|
||||
}
|
||||
debug( 3, L"ok pos" );
|
||||
//debug( 3, L"ok pos" );
|
||||
|
||||
if( !contains( tok_last( &tok ), &data->search_prev ) )
|
||||
{
|
||||
@@ -1439,7 +1502,7 @@ static void handle_token_history( int forward, int reset )
|
||||
al_push( &data->search_prev, str );
|
||||
data->search_pos = al_get_count( &data->search_prev )-1;
|
||||
}
|
||||
else
|
||||
else if( ! reader_interrupted() )
|
||||
{
|
||||
data->token_history_pos=-1;
|
||||
handle_token_history( 0, 0 );
|
||||
@@ -1668,12 +1731,7 @@ void reader_run_command( const wchar_t *cmd )
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Test if the given shell command contains errors. Uses parser_test
|
||||
for testing.
|
||||
*/
|
||||
|
||||
static int shell_test( wchar_t *b )
|
||||
int reader_shell_test( wchar_t *b )
|
||||
{
|
||||
int res = parser_test( b, 0, 0, 0 );
|
||||
|
||||
@@ -1707,6 +1765,12 @@ static int default_test( wchar_t *b )
|
||||
void reader_push( wchar_t *name )
|
||||
{
|
||||
reader_data_t *n = calloc( 1, sizeof( reader_data_t ) );
|
||||
|
||||
if( !n )
|
||||
{
|
||||
DIE_MEM();
|
||||
}
|
||||
|
||||
n->name = wcsdup( name );
|
||||
n->next = data;
|
||||
sb_init( &n->kill_item );
|
||||
@@ -1774,8 +1838,9 @@ void reader_pop()
|
||||
}
|
||||
else
|
||||
{
|
||||
end_loop = 0;
|
||||
history_set_mode( data->name );
|
||||
exec_prompt();
|
||||
s_reset( &data->screen );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1853,7 +1918,7 @@ static int read_i()
|
||||
reader_push(L"fish");
|
||||
reader_set_complete_function( &complete );
|
||||
reader_set_highlight_function( &highlight_shell );
|
||||
reader_set_test_function( &shell_test );
|
||||
reader_set_test_function( &reader_shell_test );
|
||||
|
||||
data->prev_end_loop=0;
|
||||
|
||||
@@ -1861,8 +1926,8 @@ static int read_i()
|
||||
{
|
||||
wchar_t *tmp;
|
||||
|
||||
if( function_exists( L"fish_prompt" ) )
|
||||
reader_set_prompt( L"fish_prompt" );
|
||||
if( function_exists( PROMPT_FUNCTION_NAME ) )
|
||||
reader_set_prompt( PROMPT_FUNCTION_NAME );
|
||||
else
|
||||
reader_set_prompt( DEFAULT_PROMPT );
|
||||
|
||||
@@ -1899,34 +1964,24 @@ static int read_i()
|
||||
}
|
||||
else
|
||||
{
|
||||
pid_t my_pid = getpid();
|
||||
for( j = first_job; j; j=j->next )
|
||||
if( !isatty(0) )
|
||||
{
|
||||
if( ! job_is_completed( j ) )
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
for( j = first_job; j; j=j->next )
|
||||
{
|
||||
if( j->pgid != my_pid )
|
||||
if( ! job_is_completed( j ) )
|
||||
{
|
||||
killpg( j->pgid, SIGHUP );
|
||||
}
|
||||
else
|
||||
{
|
||||
process_t *p;
|
||||
for( p = j->first_process; p; p=p->next )
|
||||
{
|
||||
if( ! p->completed )
|
||||
{
|
||||
if( p->pid )
|
||||
{
|
||||
kill( p->pid, SIGHUP );
|
||||
}
|
||||
}
|
||||
}
|
||||
job_signal( j, SIGHUP );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else if( tmp )
|
||||
{
|
||||
tmp = wcsdup( tmp );
|
||||
|
||||
@@ -1966,6 +2021,27 @@ static int wchar_private( wchar_t c )
|
||||
return ( (c >= 0xe000) && (c <= 0xf8ff ) );
|
||||
}
|
||||
|
||||
/**
|
||||
Test if the specified character in the specified string is
|
||||
backslashed.
|
||||
*/
|
||||
static int is_backslashed( const wchar_t *str, int pos )
|
||||
{
|
||||
int count = 0;
|
||||
int i;
|
||||
|
||||
for( i=pos-1; i>=0; i-- )
|
||||
{
|
||||
if( str[i] != L'\\' )
|
||||
break;
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
return count %2;
|
||||
}
|
||||
|
||||
|
||||
wchar_t *reader_readline()
|
||||
{
|
||||
|
||||
@@ -1997,9 +2073,9 @@ wchar_t *reader_readline()
|
||||
*/
|
||||
tcgetattr(0,&old_modes);
|
||||
/* set the new modes */
|
||||
if( tcsetattr(0,TCSANOW,&shell_modes))
|
||||
if( tcsetattr(0,TCSANOW,&shell_modes))
|
||||
{
|
||||
wperror(L"tcsetattr");
|
||||
wperror(L"tcsetattr");
|
||||
}
|
||||
|
||||
while( !finished && !data->end_loop)
|
||||
@@ -2013,9 +2089,11 @@ wchar_t *reader_readline()
|
||||
*/
|
||||
while( 1 )
|
||||
{
|
||||
int was_interactive_read = is_interactive_read;
|
||||
is_interactive_read = 1;
|
||||
c=input_readch();
|
||||
|
||||
|
||||
is_interactive_read = was_interactive_read;
|
||||
|
||||
if( ( (!wchar_private(c))) && (c>31) && (c != 127) )
|
||||
{
|
||||
if( can_read(0) )
|
||||
@@ -2112,7 +2190,17 @@ wchar_t *reader_readline()
|
||||
|
||||
case R_NULL:
|
||||
{
|
||||
// exec_prompt();
|
||||
write( 1, "\r", 1 );
|
||||
s_reset( &data->screen );
|
||||
repaint();
|
||||
break;
|
||||
}
|
||||
|
||||
case R_REPAINT:
|
||||
{
|
||||
exec_prompt();
|
||||
write( 1, "\r", 1 );
|
||||
s_reset( &data->screen );
|
||||
repaint();
|
||||
break;
|
||||
@@ -2138,10 +2226,7 @@ wchar_t *reader_readline()
|
||||
if( !data->complete_func )
|
||||
break;
|
||||
|
||||
if( !comp_empty && last_char == R_COMPLETE )
|
||||
break;
|
||||
|
||||
if( comp_empty )
|
||||
if( comp_empty || last_char != R_COMPLETE)
|
||||
{
|
||||
wchar_t *begin, *end;
|
||||
wchar_t *token_begin, *token_end;
|
||||
@@ -2155,6 +2240,11 @@ wchar_t *reader_readline()
|
||||
|
||||
cursor_steps = token_end - data->buff- data->buff_pos;
|
||||
data->buff_pos += cursor_steps;
|
||||
if( is_backslashed( data->buff, data->buff_pos ) )
|
||||
{
|
||||
remove_backward();
|
||||
}
|
||||
|
||||
repaint();
|
||||
|
||||
len = data->buff_pos - (begin-data->buff);
|
||||
@@ -2296,6 +2386,7 @@ wchar_t *reader_readline()
|
||||
reader_replace_current_token( data->search_buff );
|
||||
}
|
||||
*data->search_buff=0;
|
||||
reader_super_highlight_me_plenty( data->buff_pos, 0 );
|
||||
repaint();
|
||||
|
||||
}
|
||||
@@ -2330,7 +2421,6 @@ wchar_t *reader_readline()
|
||||
{
|
||||
if( data->buff_len == 0 )
|
||||
{
|
||||
writestr( L"\n" );
|
||||
data->end_loop=1;
|
||||
}
|
||||
break;
|
||||
@@ -2346,7 +2436,7 @@ wchar_t *reader_readline()
|
||||
/*
|
||||
Allow backslash-escaped newlines
|
||||
*/
|
||||
if( data->buff_pos && data->buff[data->buff_pos-1]==L'\\' )
|
||||
if( is_backslashed( data->buff, data->buff_pos ) )
|
||||
{
|
||||
insert_char( '\n' );
|
||||
break;
|
||||
@@ -2368,7 +2458,6 @@ wchar_t *reader_readline()
|
||||
finished=1;
|
||||
data->buff_pos=data->buff_len;
|
||||
repaint();
|
||||
writestr( L"\n" );
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2571,6 +2660,7 @@ wchar_t *reader_readline()
|
||||
last_char = c;
|
||||
}
|
||||
|
||||
writestr( L"\n" );
|
||||
al_destroy( &comp );
|
||||
if( !reader_exit_forced() )
|
||||
{
|
||||
@@ -2582,7 +2672,7 @@ wchar_t *reader_readline()
|
||||
set_color( FISH_COLOR_RESET, FISH_COLOR_RESET );
|
||||
}
|
||||
|
||||
return data->buff;
|
||||
return finished ? data->buff : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
6
reader.h
6
reader.h
@@ -167,4 +167,10 @@ void reader_handle_int( int signal );
|
||||
*/
|
||||
int reader_exit_forced();
|
||||
|
||||
/**
|
||||
Test if the given shell command contains errors. Uses parser_test
|
||||
for testing. Suitable for reader_set_test_function().
|
||||
*/
|
||||
int reader_shell_test( wchar_t *b );
|
||||
|
||||
#endif
|
||||
|
||||
225
screen.c
225
screen.c
@@ -1,9 +1,9 @@
|
||||
/** \file screen.c High level library for handling the terminal screen
|
||||
|
||||
The screen library allows the interactive reader to write its
|
||||
output to screen efficiently by keeping an inetrnal representation
|
||||
of the current screen contents and trying to find the most
|
||||
efficient way for transforming that to the desired screen content.
|
||||
The screen library allows the interactive reader to write its
|
||||
output to screen efficiently by keeping an inetrnal representation
|
||||
of the current screen contents and trying to find the most
|
||||
efficient way for transforming that to the desired screen content.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "output.h"
|
||||
#include "highlight.h"
|
||||
#include "screen.h"
|
||||
#include "env.h"
|
||||
|
||||
/**
|
||||
Ugly kludge. The internal buffer used to store output of
|
||||
@@ -82,6 +83,9 @@ static int try_sequence( char *seq, wchar_t *str )
|
||||
|
||||
static int next_tab_stop( int in )
|
||||
{
|
||||
/*
|
||||
Assume tab stops every 8 characters if undefined
|
||||
*/
|
||||
if( init_tabs <= 0 )
|
||||
init_tabs = 8;
|
||||
|
||||
@@ -105,103 +109,132 @@ static int calc_prompt_width( wchar_t *prompt )
|
||||
/*
|
||||
This is the start of an escape code. Try to guess it's width.
|
||||
*/
|
||||
int l;
|
||||
int len=0;
|
||||
int found = 0;
|
||||
|
||||
/*
|
||||
Detect these terminfo color escapes with parameter
|
||||
value 0..7, all of which don't move the cursor
|
||||
*/
|
||||
char * esc[] =
|
||||
{
|
||||
set_a_foreground,
|
||||
set_a_background,
|
||||
set_foreground,
|
||||
set_background,
|
||||
}
|
||||
;
|
||||
|
||||
/*
|
||||
Detect these semi-common terminfo escapes without any
|
||||
parameter values, all of which don't move the cursor
|
||||
*/
|
||||
char *esc2[] =
|
||||
{
|
||||
enter_bold_mode,
|
||||
exit_attribute_mode,
|
||||
enter_underline_mode,
|
||||
exit_underline_mode,
|
||||
enter_standout_mode,
|
||||
exit_standout_mode,
|
||||
flash_screen,
|
||||
enter_subscript_mode,
|
||||
exit_subscript_mode,
|
||||
enter_superscript_mode,
|
||||
exit_superscript_mode,
|
||||
enter_blink_mode,
|
||||
enter_italics_mode,
|
||||
exit_italics_mode,
|
||||
enter_reverse_mode,
|
||||
enter_shadow_mode,
|
||||
exit_shadow_mode,
|
||||
enter_standout_mode,
|
||||
exit_standout_mode,
|
||||
enter_secure_mode
|
||||
}
|
||||
;
|
||||
|
||||
for( l=0; l < (sizeof(esc)/sizeof(char *)) && !found; l++ )
|
||||
int l;
|
||||
int len=0;
|
||||
int found = 0;
|
||||
|
||||
/*
|
||||
Detect these terminfo color escapes with parameter
|
||||
value 0..7, all of which don't move the cursor
|
||||
*/
|
||||
char * esc[] =
|
||||
{
|
||||
if( !esc[l] )
|
||||
continue;
|
||||
|
||||
for( k=0; k<8; k++ )
|
||||
{
|
||||
len = try_sequence( tparm(esc[l],k), &prompt[j] );
|
||||
if( len )
|
||||
{
|
||||
j += (len-1);
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
set_a_foreground,
|
||||
set_a_background,
|
||||
set_foreground,
|
||||
set_background,
|
||||
}
|
||||
;
|
||||
|
||||
for( l=0; l < (sizeof(esc2)/sizeof(char *)) && !found; l++ )
|
||||
/*
|
||||
Detect these semi-common terminfo escapes without any
|
||||
parameter values, all of which don't move the cursor
|
||||
*/
|
||||
char *esc2[] =
|
||||
{
|
||||
if( !esc2[l] )
|
||||
continue;
|
||||
/*
|
||||
Test both padded and unpadded version, just to
|
||||
be safe. Most versions of tparm don't actually
|
||||
seem to do anything these days.
|
||||
*/
|
||||
len = maxi( try_sequence( tparm(esc2[l]), &prompt[j] ),
|
||||
try_sequence( esc2[l], &prompt[j] ));
|
||||
|
||||
enter_bold_mode,
|
||||
exit_attribute_mode,
|
||||
enter_underline_mode,
|
||||
exit_underline_mode,
|
||||
enter_standout_mode,
|
||||
exit_standout_mode,
|
||||
flash_screen,
|
||||
enter_subscript_mode,
|
||||
exit_subscript_mode,
|
||||
enter_superscript_mode,
|
||||
exit_superscript_mode,
|
||||
enter_blink_mode,
|
||||
enter_italics_mode,
|
||||
exit_italics_mode,
|
||||
enter_reverse_mode,
|
||||
enter_shadow_mode,
|
||||
exit_shadow_mode,
|
||||
enter_standout_mode,
|
||||
exit_standout_mode,
|
||||
enter_secure_mode
|
||||
}
|
||||
;
|
||||
|
||||
for( l=0; l < (sizeof(esc)/sizeof(char *)) && !found; l++ )
|
||||
{
|
||||
if( !esc[l] )
|
||||
continue;
|
||||
|
||||
for( k=0; k<8; k++ )
|
||||
{
|
||||
len = try_sequence( tparm(esc[l],k), &prompt[j] );
|
||||
if( len )
|
||||
{
|
||||
j += (len-1);
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( prompt[j] == L'\t' )
|
||||
|
||||
for( l=0; l < (sizeof(esc2)/sizeof(char *)) && !found; l++ )
|
||||
{
|
||||
if( !esc2[l] )
|
||||
continue;
|
||||
/*
|
||||
Assume tab stops every 8 characters if undefined
|
||||
Test both padded and unpadded version, just to
|
||||
be safe. Most versions of tparm don't actually
|
||||
seem to do anything these days.
|
||||
*/
|
||||
res = next_tab_stop( res );
|
||||
len = maxi( try_sequence( tparm(esc2[l]), &prompt[j] ),
|
||||
try_sequence( esc2[l], &prompt[j] ));
|
||||
|
||||
if( len )
|
||||
{
|
||||
j += (len-1);
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if( !found )
|
||||
{
|
||||
/*
|
||||
Ordinary decent character. Just add width.
|
||||
*/
|
||||
res += wcwidth( prompt[j] );
|
||||
if( prompt[j+1] == L'k' )
|
||||
{
|
||||
wchar_t *term_name = env_get( L"TERM" );
|
||||
if( term_name && wcscmp( term_name, L"screen" ) == 0 )
|
||||
{
|
||||
wchar_t *end;
|
||||
j+=2;
|
||||
found = 1;
|
||||
end = wcsstr( &prompt[j], L"\e\\" );
|
||||
if( end )
|
||||
{
|
||||
/*
|
||||
You'd thing this should be
|
||||
'(end-prompt)+2', in order to move j
|
||||
past the end of the string, but there is
|
||||
a 'j++' at the end of each lap, so j
|
||||
should always point to the last menged
|
||||
character, e.g. +1.
|
||||
*/
|
||||
j = (end-prompt)+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if( prompt[j] == L'\t' )
|
||||
{
|
||||
res = next_tab_stop( res );
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Ordinary decent character. Just add width.
|
||||
*/
|
||||
res += wcwidth( prompt[j] );
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -304,7 +337,6 @@ static void s_check_status( screen_t *s)
|
||||
/**
|
||||
Free all memory used by one line_t struct.
|
||||
*/
|
||||
|
||||
static void free_line( void *l )
|
||||
{
|
||||
line_t *line = (line_t *)l;
|
||||
@@ -354,9 +386,9 @@ static line_t *s_create_line()
|
||||
}
|
||||
|
||||
/**
|
||||
Appends a character to the end of the line that the output cursor is
|
||||
on. This function automatically handles linebreaks and lines longer
|
||||
than the screen width.
|
||||
Appends a character to the end of the line that the output cursor is
|
||||
on. This function automatically handles linebreaks and lines longer
|
||||
than the screen width.
|
||||
*/
|
||||
static void s_desired_append_char( screen_t *s,
|
||||
wchar_t b,
|
||||
@@ -465,9 +497,9 @@ static void s_move( screen_t *s, buffer_t *b, int new_x, int new_y )
|
||||
|
||||
char *str;
|
||||
/*
|
||||
debug( 0, L"move from %d %d to %d %d",
|
||||
s->screen_cursor[0], s->screen_cursor[1],
|
||||
new_x, new_y );
|
||||
debug( 0, L"move from %d %d to %d %d",
|
||||
s->screen_cursor[0], s->screen_cursor[1],
|
||||
new_x, new_y );
|
||||
*/
|
||||
output_set_writer( &s_writeb );
|
||||
s_writeb_buffer = b;
|
||||
@@ -477,10 +509,11 @@ static void s_move( screen_t *s, buffer_t *b, int new_x, int new_y )
|
||||
if( y_steps > 0 && (strcmp( cursor_down, "\n")==0))
|
||||
{
|
||||
/*
|
||||
This is very strange - it seems all (most) consoles use a
|
||||
This is very strange - it seems some (all?) consoles use a
|
||||
simple newline as the cursor down escape. This will of
|
||||
course move the cursor to the beginning of the line as
|
||||
well. The cursor_up does not have this behaviour...
|
||||
course move the cursor to the beginning of the line as well
|
||||
as moving it down one step. The cursor_up does not have this
|
||||
behaviour...
|
||||
*/
|
||||
s->actual_cursor[0]=0;
|
||||
}
|
||||
@@ -565,6 +598,7 @@ static void s_write_char( screen_t *s, buffer_t *b, wchar_t c )
|
||||
|
||||
output_set_writer( writer_old );
|
||||
}
|
||||
|
||||
/**
|
||||
Send the specified string through tputs and append the output to
|
||||
the specified buffer.
|
||||
@@ -642,6 +676,11 @@ static void s_update( screen_t *scr, wchar_t *prompt )
|
||||
{
|
||||
s_move( scr, &output, start_pos, i );
|
||||
s_write_mbs( &output, clr_eol);
|
||||
if( s_line )
|
||||
{
|
||||
al_truncate( &s_line->text, 0 );
|
||||
al_truncate( &s_line->color, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
if( !s_line )
|
||||
|
||||
16
set_color.c
16
set_color.c
@@ -37,6 +37,7 @@
|
||||
#endif
|
||||
|
||||
#include "fallback.h"
|
||||
#include "print_help.h"
|
||||
|
||||
/*
|
||||
Small utility for setting the color.
|
||||
@@ -56,7 +57,11 @@
|
||||
*/
|
||||
#define GETOPT_STRING "b:hvocu"
|
||||
|
||||
#ifdef USE_GETTEXT
|
||||
#define _(string) gettext(string)
|
||||
#else
|
||||
#define _(string) (string)
|
||||
#endif
|
||||
|
||||
char *col[]=
|
||||
{
|
||||
@@ -90,8 +95,6 @@ int col_idx[]=
|
||||
}
|
||||
;
|
||||
|
||||
void print_help();
|
||||
|
||||
int translate_color( char *str )
|
||||
{
|
||||
char *endptr;
|
||||
@@ -99,10 +102,11 @@ int translate_color( char *str )
|
||||
|
||||
if( !str )
|
||||
return -1;
|
||||
|
||||
|
||||
errno = 0;
|
||||
color = strtol( str, &endptr, 10 );
|
||||
if(endptr<=str)
|
||||
|
||||
if( *endptr || color<0 || errno )
|
||||
{
|
||||
int i;
|
||||
color = -1;
|
||||
@@ -206,7 +210,7 @@ int main( int argc, char **argv )
|
||||
bgcolor = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
print_help();
|
||||
print_help( argv[0], 1 );
|
||||
exit(0);
|
||||
|
||||
case 'o':
|
||||
@@ -254,7 +258,7 @@ int main( int argc, char **argv )
|
||||
{
|
||||
check_locale_init();
|
||||
fprintf( stderr, _("%s: Expected an argument\n"), SET_COLOR );
|
||||
print_help();
|
||||
print_help( argv[0], 2 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
2
share/completions/and.fish
Normal file
2
share/completions/and.fish
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
complete -c and -s h -l help --description 'Display help and exit'
|
||||
3
share/completions/ant.fish
Normal file
3
share/completions/ant.fish
Normal file
@@ -0,0 +1,3 @@
|
||||
|
||||
complete -x -c ant -a "(__fish_complete_ant_targets)"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#apm
|
||||
complete -f -c apm -s V -l version -d (N_ "Display version and exit")
|
||||
complete -f -c apm -s v -l verbose -d (N_ "Print APM info")
|
||||
complete -f -c apm -s m -l minutes -d (N_ "Print time remaining")
|
||||
complete -f -c apm -s M -l monitor -d (N_ "Monitor status info")
|
||||
complete -f -c apm -s S -l standby -d (N_ "Request APM standby mode")
|
||||
complete -f -c apm -s s -l suspend -d (N_ "Request APM suspend mode")
|
||||
complete -f -c apm -s d -l debug -d (N_ "APM status debugging info")
|
||||
complete -f -c apm -s V -l version --description "Display version and exit"
|
||||
complete -f -c apm -s v -l verbose --description "Print APM info"
|
||||
complete -f -c apm -s m -l minutes --description "Print time remaining"
|
||||
complete -f -c apm -s M -l monitor --description "Monitor status info"
|
||||
complete -f -c apm -s S -l standby --description "Request APM standby mode"
|
||||
complete -f -c apm -s s -l suspend --description "Request APM suspend mode"
|
||||
complete -f -c apm -s d -l debug --description "APM status debugging info"
|
||||
|
||||
@@ -6,16 +6,16 @@ function __fish_complete_apropos
|
||||
end
|
||||
end
|
||||
|
||||
complete -xc apropos -a '(__fish_complete_apropos)' -d (N_ "whatis entry")
|
||||
complete -xc apropos -a '(__fish_complete_apropos)' --description "whatis entry"
|
||||
|
||||
complete -c apropos -s h -l help -d (N_ "Display help and exit")
|
||||
complete -f -c apropos -s d -l debug -d (N_ "Print debugging info")
|
||||
complete -f -c apropos -s v -l verbose -d (N_ "Verbose mode")
|
||||
complete -f -c apropos -s r -l regex -d (N_ "Keyword as regex")
|
||||
complete -f -c apropos -s w -l wildcard -d (N_ "Keyword as wildcards")
|
||||
complete -f -c apropos -s e -l exact -d (N_ "Keyword as exactly match")
|
||||
complete -x -c apropos -s m -l system -d (N_ "Search for other system")
|
||||
complete -x -c apropos -s M -l manpath -a '(echo $MANPATH)' -d (N_ "Specify man path")
|
||||
complete -x -c apropos -s C -l config-file -d (N_ "Specify a configuration file")
|
||||
complete -f -c apropos -s V -l version -d (N_ "Display version and exit")
|
||||
complete -c apropos -s h -l help --description "Display help and exit"
|
||||
complete -f -c apropos -s d -l debug --description "Print debugging info"
|
||||
complete -f -c apropos -s v -l verbose --description "Verbose mode"
|
||||
complete -f -c apropos -s r -l regex --description "Keyword as regex"
|
||||
complete -f -c apropos -s w -l wildcard --description "Keyword as wildcards"
|
||||
complete -f -c apropos -s e -l exact --description "Keyword as exactly match"
|
||||
complete -x -c apropos -s m -l system --description "Search for other system"
|
||||
complete -x -c apropos -s M -l manpath -a '(echo $MANPATH)' --description "Specify man path"
|
||||
complete -x -c apropos -s C -l config-file --description "Specify a configuration file"
|
||||
complete -f -c apropos -s V -l version --description "Display version and exit"
|
||||
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
|
||||
#apt-build
|
||||
complete -c apt-build -l help -d (N_ "Display help and exit")
|
||||
complete -f -c apt-build -a update -d (N_ "Update list of packages")
|
||||
complete -f -c apt-build -a upgrade -d (N_ "Upgrade packages")
|
||||
complete -f -c apt-bulid -a world -d (N_ "Rebuild your system")
|
||||
complete -x -c apt-build -a install -d (N_ "Build and install a new package")
|
||||
complete -x -c apt-build -a source -d (N_ "Download and extract a source")
|
||||
complete -x -c apt-build -a info -d (N_ "Info on a package")
|
||||
complete -x -c apt-build -a remove -d (N_ "Remove packages")
|
||||
complete -x -c apt-build -a clean-build -d (N_ "Erase built packages")
|
||||
complete -x -c apt-build -a build-source -d (N_ "Build source without install")
|
||||
complete -x -c apt-build -a clean-sources -d (N_ "Clean source directories")
|
||||
complete -x -c apt-build -a update-source -d (N_ "Update source and rebuild")
|
||||
complete -x -c apt-build -a update-repository -d (N_ "Update the repository")
|
||||
complete -f -c apt-build -l nowrapper -d (N_ "Do not use gcc wrapper")
|
||||
complete -f -c apt-build -l remove-builddep -d (N_ "Remove build-dep")
|
||||
complete -f -c apt-build -l no-source -d (N_ "Do not download source")
|
||||
complete -f -c apt-build -l build-dir -d (N_ "Specify build-dir")
|
||||
complete -f -c apt-build -l rebuild -d (N_ "Rebuild a package")
|
||||
complete -f -c apt-build -l reinstall -d (N_ "Rebuild and install an installed package")
|
||||
complete -r -f -c apt-build -l build-command -d (N_ "Use <command> to build")
|
||||
complete -r -c apt-build -l patch -d (N_ "Apply <file> patch")
|
||||
complete -c apt-build -s p -l patch-strip -d (N_ "Prefix to strip on patch")
|
||||
complete -c apt-build -s y -l yes -d (N_ "Assume yes to all questions")
|
||||
complete -c apt-build -l purge -d (N_ "Use purge instead of remove")
|
||||
complete -c apt-build -l noupdate -d (N_ "Do not run update")
|
||||
complete -r -c apt-build -l source-list -d (N_ "Specify sources.list file")
|
||||
complete -f -c apt-build -s v -l version -d (N_ "Display version and exit")
|
||||
complete -c apt-build -l help --description "Display help and exit"
|
||||
complete -f -c apt-build -a update --description "Update list of packages"
|
||||
complete -f -c apt-build -a upgrade --description "Upgrade packages"
|
||||
complete -f -c apt-bulid -a world --description "Rebuild your system"
|
||||
complete -x -c apt-build -a install --description "Build and install a new package"
|
||||
complete -x -c apt-build -a source --description "Download and extract a source"
|
||||
complete -x -c apt-build -a info --description "Info on a package"
|
||||
complete -x -c apt-build -a remove --description "Remove packages"
|
||||
complete -x -c apt-build -a clean-build --description "Erase built packages"
|
||||
complete -x -c apt-build -a build-source --description "Build source without install"
|
||||
complete -x -c apt-build -a clean-sources --description "Clean source directories"
|
||||
complete -x -c apt-build -a update-source --description "Update source and rebuild"
|
||||
complete -x -c apt-build -a update-repository --description "Update the repository"
|
||||
complete -f -c apt-build -l nowrapper --description "Do not use gcc wrapper"
|
||||
complete -f -c apt-build -l remove-builddep --description "Remove build-dep"
|
||||
complete -f -c apt-build -l no-source --description "Do not download source"
|
||||
complete -f -c apt-build -l build-dir --description "Specify build-dir"
|
||||
complete -f -c apt-build -l rebuild --description "Rebuild a package"
|
||||
complete -f -c apt-build -l reinstall --description "Rebuild and install an installed package"
|
||||
complete -r -f -c apt-build -l build-command --description "Use <command> to build"
|
||||
complete -r -c apt-build -l patch --description "Apply <file> patch"
|
||||
complete -c apt-build -s p -l patch-strip --description "Prefix to strip on patch"
|
||||
complete -c apt-build -s y -l yes --description "Assume yes to all questions"
|
||||
complete -c apt-build -l purge --description "Use purge instead of remove"
|
||||
complete -c apt-build -l noupdate --description "Do not run update"
|
||||
complete -r -c apt-build -l source-list --description "Specify sources.list file"
|
||||
complete -f -c apt-build -s v -l version --description "Display version and exit"
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
#apt-cache
|
||||
complete -c apt-cache -s h -l help -d (N_ "Display help and exit")
|
||||
complete -f -c apt-cache -a gencaches -d (N_ "Build apt cache")
|
||||
complete -x -c apt-cache -a showpkg -d (N_ "Show package info")
|
||||
complete -f -c apt-cache -a stats -d (N_ "Show cache statistics")
|
||||
complete -x -c apt-cache -a showsrc -d (N_ "Show source package")
|
||||
complete -f -c apt-cache -a dump -d (N_ "Show packages in cache")
|
||||
complete -f -c apt-cache -a dumpavail -d (N_ "Print available list")
|
||||
complete -f -c apt-cache -a unmet -d (N_ "List unmet dependencies in cache")
|
||||
complete -x -c apt-cache -a show -d (N_ "Display package record")
|
||||
complete -x -c apt-cache -a search -d (N_ "Search packagename by REGEX")
|
||||
complete -c apt-cache -l full -a search -d (N_ "Search full package name")
|
||||
complete -x -c apt-cache -l names-only -a search -d (N_ "Search packagename only")
|
||||
complete -x -c apt-cache -a depends -d (N_ "List dependencies for the package")
|
||||
complete -x -c apt-cache -a rdepends -d (N_ "List reverse dependencies for the package")
|
||||
complete -x -c apt-cache -a pkgnames -d (N_ "Print package name by prefix")
|
||||
complete -x -c apt-cache -a dotty -d (N_ "Generate dotty output for packages")
|
||||
complete -x -c apt-cache -a policy -d (N_ "Debug preferences file")
|
||||
complete -r -c apt-cache -s p -l pkg-cache -d (N_ "Select file to store package cache")
|
||||
complete -r -c apt-cache -s s -l src-cache -d (N_ "Select file to store source cache")
|
||||
complete -f -c apt-cache -s q -l quiet -d (N_ "Quiet mode")
|
||||
complete -f -c apt-cache -s i -l important -d (N_ "Print important dependencies")
|
||||
complete -f -c apt-cache -s a -l all-versions -d (N_ "Print full records")
|
||||
complete -f -c apt-cache -s g -l generate -d (N_ "Auto-gen package cache")
|
||||
complete -f -c apt-cache -l all-names -d (N_ "Print all names")
|
||||
complete -f -c apt-cache -l recurse -d (N_ "Dep and rdep recursive")
|
||||
complete -f -c apt-cache -l installed -d (N_ "Limit to installed")
|
||||
complete -f -c apt-cache -s v -l version -d (N_ "Display version and exit")
|
||||
complete -r -c apt-cache -s c -l config-file -d (N_ "Specify config file")
|
||||
complete -x -c apt-cache -s o -l option -d (N_ "Specify options")
|
||||
complete -c apt-cache -s h -l help --description "Display help and exit"
|
||||
complete -f -c apt-cache -a gencaches --description "Build apt cache"
|
||||
complete -x -c apt-cache -a showpkg --description "Show package info"
|
||||
complete -f -c apt-cache -a stats --description "Show cache statistics"
|
||||
complete -x -c apt-cache -a showsrc --description "Show source package"
|
||||
complete -f -c apt-cache -a dump --description "Show packages in cache"
|
||||
complete -f -c apt-cache -a dumpavail --description "Print available list"
|
||||
complete -f -c apt-cache -a unmet --description "List unmet dependencies in cache"
|
||||
complete -x -c apt-cache -a show --description "Display package record"
|
||||
complete -x -c apt-cache -a search --description "Search packagename by REGEX"
|
||||
complete -c apt-cache -l full -a search --description "Search full package name"
|
||||
complete -x -c apt-cache -l names-only -a search --description "Search packagename only"
|
||||
complete -x -c apt-cache -a depends --description "List dependencies for the package"
|
||||
complete -x -c apt-cache -a rdepends --description "List reverse dependencies for the package"
|
||||
complete -x -c apt-cache -a pkgnames --description "Print package name by prefix"
|
||||
complete -x -c apt-cache -a dotty --description "Generate dotty output for packages"
|
||||
complete -x -c apt-cache -a policy --description "Debug preferences file"
|
||||
complete -r -c apt-cache -s p -l pkg-cache --description "Select file to store package cache"
|
||||
complete -r -c apt-cache -s s -l src-cache --description "Select file to store source cache"
|
||||
complete -f -c apt-cache -s q -l quiet --description "Quiet mode"
|
||||
complete -f -c apt-cache -s i -l important --description "Print important dependencies"
|
||||
complete -f -c apt-cache -s a -l all-versions --description "Print full records"
|
||||
complete -f -c apt-cache -s g -l generate --description "Auto-gen package cache"
|
||||
complete -f -c apt-cache -l all-names --description "Print all names"
|
||||
complete -f -c apt-cache -l recurse --description "Dep and rdep recursive"
|
||||
complete -f -c apt-cache -l installed --description "Limit to installed"
|
||||
complete -f -c apt-cache -s v -l version --description "Display version and exit"
|
||||
complete -r -c apt-cache -s c -l config-file --description "Specify config file"
|
||||
complete -x -c apt-cache -s o -l option --description "Specify options"
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#apt-cdrom
|
||||
complete -c apt-cdrom -s h -l help -d (N_ "Display help and exit")
|
||||
complete -r -c apt-cdrom -a add -d (N_ "Add new disc to source list")
|
||||
complete -x -c apt-cdrom -a ident -d (N_ "Report identity of disc")
|
||||
complete -r -c apt-cdrom -s d -l cdrom -d (N_ "Mount point")
|
||||
complete -f -c apt-cdrom -s r -l rename -d (N_ "Rename a disc")
|
||||
complete -f -c apt-cdrom -s m -l no-mount -d (N_ "No mounting")
|
||||
complete -f -c apt-cdrom -s f -l fast -d (N_ "Fast copy")
|
||||
complete -f -c apt-cdrom -s a -l thorough -d (N_ "Thorough package scan")
|
||||
complete -f -c apt-cdrom -s n -l no-act -d (N_ "No changes")
|
||||
complete -f -c apt-cdrom -s v -l version -d (N_ "Display version and exit")
|
||||
complete -r -c apt-cdrom -s c -l config-file -d (N_ "Specify config file")
|
||||
complete -x -c apt-cdrom -s o -l option -d (N_ "Specify options")
|
||||
complete -c apt-cdrom -s h -l help --description "Display help and exit"
|
||||
complete -r -c apt-cdrom -a add --description "Add new disc to source list"
|
||||
complete -x -c apt-cdrom -a ident --description "Report identity of disc"
|
||||
complete -r -c apt-cdrom -s d -l cdrom --description "Mount point"
|
||||
complete -f -c apt-cdrom -s r -l rename --description "Rename a disc"
|
||||
complete -f -c apt-cdrom -s m -l no-mount --description "No mounting"
|
||||
complete -f -c apt-cdrom -s f -l fast --description "Fast copy"
|
||||
complete -f -c apt-cdrom -s a -l thorough --description "Thorough package scan"
|
||||
complete -f -c apt-cdrom -s n -l no-act --description "No changes"
|
||||
complete -f -c apt-cdrom -s v -l version --description "Display version and exit"
|
||||
complete -r -c apt-cdrom -s c -l config-file --description "Specify config file"
|
||||
complete -x -c apt-cdrom -s o -l option --description "Specify options"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#apt-config
|
||||
complete -c apt-config -s h -l help -d (N_ "Display help and exit")
|
||||
complete -c apt-config -a shell -d (N_ "Access config file from shell")
|
||||
complete -f -c apt-config -a dump -d (N_ "Dump contents of config file")
|
||||
complete -f -c apt-config -s v -l version -d (N_ "Display version and exit")
|
||||
complete -r -c apt-config -s c -l config-file -d (N_ "Specify config file")
|
||||
complete -x -c apt-config -s o -l option -d (N_ "Specify options")
|
||||
complete -c apt-config -s h -l help --description "Display help and exit"
|
||||
complete -c apt-config -a shell --description "Access config file from shell"
|
||||
complete -f -c apt-config -a dump --description "Dump contents of config file"
|
||||
complete -f -c apt-config -s v -l version --description "Display version and exit"
|
||||
complete -r -c apt-config -s c -l config-file --description "Specify config file"
|
||||
complete -x -c apt-config -s o -l option --description "Specify options"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
#apt-extracttemplates
|
||||
complete -c apt-extracttemplates -s h -l help -d (N_ "Display help and exit")
|
||||
complete -r -c apt-extracttemplates -s t -d (N_ "Set temp dir")
|
||||
complete -r -c apt-extracttemplates -s c -d (N_ "Specifiy config file")
|
||||
complete -r -c apt-extracttemplates -s o -d (N_ "Specify options")
|
||||
complete -c apt-extracttemplates -s h -l help --description "Display help and exit"
|
||||
complete -r -c apt-extracttemplates -s t --description "Set temp dir"
|
||||
complete -r -c apt-extracttemplates -s c --description "Specifiy config file"
|
||||
complete -r -c apt-extracttemplates -s o --description "Specify options"
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
#apt-file
|
||||
complete -c apt-file -s h -l help -d (N_ "Display help and exit")
|
||||
complete -x -c apt-file -a update -d (N_ "Resync package contents from source")
|
||||
complete -r -c apt-file -a search -d (N_ "Search package containing pattern")
|
||||
complete -r -c apt-file -a list -d (N_ "List contents of a package matching pattern")
|
||||
complete -x -c apt-file -a purge -d (N_ "Remove all gz files from cache")
|
||||
complete -r -c apt-file -s c -l cache -d (N_ "Set cache dir")
|
||||
complete -f -c apt-file -s v -l verbose -d (N_ "Verbose mode")
|
||||
complete -c apt-file -s d -l cdrom-mount -d (N_ "Use cdrom-mount-point")
|
||||
complete -f -c apt-file -s i -l ignore-case -d (N_ "Do not expand pattern")
|
||||
complete -f -c apt-file -s x -l regexp -d (N_ "Pattern is regexp")
|
||||
complete -f -c apt-file -s V -l version -d (N_ "Display version and exit")
|
||||
complete -f -c apt-file -s a -l architecture -d (N_ "Set arch")
|
||||
complete -r -c apt-file -s s -l sources-list -a "(ls /etc/apt)" -d (N_ "Set sources.list file")
|
||||
complete -f -c apt-file -s l -l package-only -d (N_ "Only display package name")
|
||||
complete -f -c apt-file -s F -l fixed-string -d (N_ "Do not expand pattern")
|
||||
complete -f -c apt-file -s y -l dummy -d (N_ "Run in dummy mode")
|
||||
complete -c apt-file -s h -l help --description "Display help and exit"
|
||||
complete -x -c apt-file -a update --description "Resync package contents from source"
|
||||
complete -r -c apt-file -a search --description "Search package containing pattern"
|
||||
complete -r -c apt-file -a list --description "List contents of a package matching pattern"
|
||||
complete -x -c apt-file -a purge --description "Remove all gz files from cache"
|
||||
complete -r -c apt-file -s c -l cache --description "Set cache dir"
|
||||
complete -f -c apt-file -s v -l verbose --description "Verbose mode"
|
||||
complete -c apt-file -s d -l cdrom-mount --description "Use cdrom-mount-point"
|
||||
complete -f -c apt-file -s i -l ignore-case --description "Do not expand pattern"
|
||||
complete -f -c apt-file -s x -l regexp --description "Pattern is regexp"
|
||||
complete -f -c apt-file -s V -l version --description "Display version and exit"
|
||||
complete -f -c apt-file -s a -l architecture --description "Set arch"
|
||||
complete -r -c apt-file -s s -l sources-list -a "(ls /etc/apt)" --description "Set sources.list file"
|
||||
complete -f -c apt-file -s l -l package-only --description "Only display package name"
|
||||
complete -f -c apt-file -s F -l fixed-string --description "Do not expand pattern"
|
||||
complete -f -c apt-file -s y -l dummy --description "Run in dummy mode"
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
#apt-ftparchive
|
||||
complete -c apt-ftparchive -s h -l help -d (N_ "Display help and exit")
|
||||
complete -f -c apt-ftparchive -a packages -d (N_ "Generate package from source")
|
||||
complete -f -c apt-ftparchive -a sources -d (N_ "Generate source index file")
|
||||
complete -f -c apt-ftparchive -a contents -d (N_ "Generate contents file")
|
||||
complete -f -c apt-ftparchive -a release -d (N_ "Generate release file")
|
||||
complete -f -c apt-ftparchive -a clean -d (N_ "Remove records")
|
||||
complete -f -c apt-ftparchive -l md5 -d (N_ "Generate MD5 sums")
|
||||
complete -f -c apt-ftparchive -s d -l db -d (N_ "Use a binary db")
|
||||
complete -f -c apt-ftparchive -s q -l quiet -d (N_ "Quiet mode")
|
||||
complete -f -c apt-ftparchive -l delink -d (N_ "Perform delinking")
|
||||
complete -f -c apt-ftparchive -l contents -d (N_ "Perform contents generation")
|
||||
complete -c apt-ftparchive -s s -l source-override -d (N_ "Use source override")
|
||||
complete -f -c apt-ftparchive -l readonly -d (N_ "Make caching db readonly")
|
||||
complete -f -c apt-ftparchive -s v -l version -d (N_ "Display version and exit")
|
||||
complete -r -c apt-ftparchive -s c -l config-file -d (N_ "Use config file")
|
||||
complete -r -c apt-ftparchive -s o -l option -d (N_ "Set config options")
|
||||
complete -c apt-ftparchive -s h -l help --description "Display help and exit"
|
||||
complete -f -c apt-ftparchive -a packages --description "Generate package from source"
|
||||
complete -f -c apt-ftparchive -a sources --description "Generate source index file"
|
||||
complete -f -c apt-ftparchive -a contents --description "Generate contents file"
|
||||
complete -f -c apt-ftparchive -a release --description "Generate release file"
|
||||
complete -f -c apt-ftparchive -a clean --description "Remove records"
|
||||
complete -f -c apt-ftparchive -l md5 --description "Generate MD5 sums"
|
||||
complete -f -c apt-ftparchive -s d -l db --description "Use a binary db"
|
||||
complete -f -c apt-ftparchive -s q -l quiet --description "Quiet mode"
|
||||
complete -f -c apt-ftparchive -l delink --description "Perform delinking"
|
||||
complete -f -c apt-ftparchive -l contents --description "Perform contents generation"
|
||||
complete -c apt-ftparchive -s s -l source-override --description "Use source override"
|
||||
complete -f -c apt-ftparchive -l readonly --description "Make caching db readonly"
|
||||
complete -f -c apt-ftparchive -s v -l version --description "Display version and exit"
|
||||
complete -r -c apt-ftparchive -s c -l config-file --description "Use config file"
|
||||
complete -r -c apt-ftparchive -s o -l option --description "Set config options"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#completion for apt-get
|
||||
|
||||
function __fish_apt_no_subcommand -d (N_ 'Test if apt has yet to be given the subcommand')
|
||||
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 dselect-upgrade dist-upgrade install remove source build-dep check clean autoclean
|
||||
return 1
|
||||
@@ -9,7 +9,7 @@ function __fish_apt_no_subcommand -d (N_ 'Test if apt has yet to be given the su
|
||||
return 0
|
||||
end
|
||||
|
||||
function __fish_apt_use_package -d (N_ 'Test if apt command should have packages as potential completion')
|
||||
function __fish_apt_use_package --description 'Test if apt command should have packages as potential completion'
|
||||
for i in (commandline -opc)
|
||||
if contains -- $i contains install remove build-dep
|
||||
return 0
|
||||
@@ -18,47 +18,47 @@ function __fish_apt_use_package -d (N_ 'Test if apt command should have packages
|
||||
return 1
|
||||
end
|
||||
|
||||
complete -c apt-get -n '__fish_apt_use_package' -a '(__fish_print_packages)' -d (N_ 'Package')
|
||||
complete -c apt-get -n '__fish_apt_use_package' -a '(__fish_print_packages)' --description 'Package'
|
||||
|
||||
complete -c apt-get -s h -l help -d (N_ 'Display help and exit')
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'update' -d (N_ 'Update sources')
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'upgrade' -d (N_ 'Upgrade or install newest packages')
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'dselect-upgrade' -d (N_ 'Use with dselect front-end')
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'dist-upgrade' -d (N_ 'Distro upgrade')
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'install' -d (N_ 'Install one or more packages')
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'remove' -d (N_ 'Remove one or more packages')
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'source' -d (N_ 'Fetch source packages')
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'build-dep' -d (N_ 'Install/remove packages for dependencies')
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'check' -d (N_ 'Update cache and check dependencies')
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'clean' -d (N_ 'Clean local caches and packages')
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'autoclean' -d (N_ 'Clean packages no longer be downloaded')
|
||||
complete -c apt-get -s d -l download-only -d (N_ 'Download Only')
|
||||
complete -c apt-get -s f -l fix-broken -d (N_ 'Correct broken dependencies')
|
||||
complete -c apt-get -s m -l fix-missing -d (N_ 'Ignore missing packages')
|
||||
complete -c apt-get -l no-download -d (N_ 'Disable downloading packages')
|
||||
complete -c apt-get -s q -l quiet -d (N_ 'Quiet mode')
|
||||
complete -c apt-get -s s -l simulate -d (N_ 'Perform a simulation')
|
||||
complete -c apt-get -s y -l assume-yes -d (N_ 'Automatic yes to prompts')
|
||||
complete -c apt-get -s u -l show-upgraded -d (N_ 'Show upgraded packages')
|
||||
complete -c apt-get -s V -l verbose-versions -d (N_ 'Show full versions for packages')
|
||||
complete -c apt-get -s b -l compile -d (N_ 'Compile source packages')
|
||||
complete -c apt-get -s b -l build -d (N_ 'Compile source packages')
|
||||
complete -c apt-get -l ignore-hold -d (N_ 'Ignore package Holds')
|
||||
complete -c apt-get -l no-upgrade -d (N_ "Do not upgrade packages")
|
||||
complete -c apt-get -l force-yes -d (N_ 'Force yes')
|
||||
complete -c apt-get -l print-uris -d (N_ 'Print the URIs')
|
||||
complete -c apt-get -l purge -d (N_ 'Use purge instead of remove')
|
||||
complete -c apt-get -l reinstall -d (N_ 'Reinstall packages')
|
||||
complete -c apt-get -l list-cleanup -d (N_ 'Erase obsolete files')
|
||||
complete -c apt-get -s t -l target-release -d (N_ 'Control default input to the policy engine')
|
||||
complete -c apt-get -l trivial-only -d (N_ 'Only perform operations that are trivial')
|
||||
complete -c apt-get -l no-remove -d (N_ 'Abort if any packages are to be removed')
|
||||
complete -c apt-get -l only-source -d (N_ 'Only accept source packages')
|
||||
complete -c apt-get -l diff-only -d (N_ 'Download only diff file')
|
||||
complete -c apt-get -l tar-only -d (N_ 'Download only tar file')
|
||||
complete -c apt-get -l arch-only -d (N_ 'Only process arch-dependant build-dependencies')
|
||||
complete -c apt-get -l allow-unauthenticated -d (N_ 'Ignore non-authenticated packages')
|
||||
complete -c apt-get -s v -l version -d (N_ 'Display version and exit')
|
||||
complete -r -c apt-get -s c -l config-file -d (N_ 'Specify a config file')
|
||||
complete -r -c apt-get -s o -l option -d (N_ 'Set a config option')
|
||||
complete -c apt-get -s h -l help --description 'Display help and exit'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'update' --description 'Update sources'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'upgrade' --description 'Upgrade or install newest packages'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'dselect-upgrade' --description 'Use with dselect front-end'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'dist-upgrade' --description 'Distro upgrade'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'install' --description 'Install one or more packages'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'remove' --description 'Remove one or more packages'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'source' --description 'Fetch source packages'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'build-dep' --description 'Install/remove packages for dependencies'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'check' --description 'Update cache and check dependencies'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'clean' --description 'Clean local caches and packages'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'autoclean' --description 'Clean packages no longer be downloaded'
|
||||
complete -c apt-get -s d -l download-only --description 'Download Only'
|
||||
complete -c apt-get -s f -l fix-broken --description 'Correct broken dependencies'
|
||||
complete -c apt-get -s m -l fix-missing --description 'Ignore missing packages'
|
||||
complete -c apt-get -l no-download --description 'Disable downloading packages'
|
||||
complete -c apt-get -s q -l quiet --description 'Quiet mode'
|
||||
complete -c apt-get -s s -l simulate --description 'Perform a simulation'
|
||||
complete -c apt-get -s y -l assume-yes --description 'Automatic yes to prompts'
|
||||
complete -c apt-get -s u -l show-upgraded --description 'Show upgraded packages'
|
||||
complete -c apt-get -s V -l verbose-versions --description 'Show full versions for packages'
|
||||
complete -c apt-get -s b -l compile --description 'Compile source packages'
|
||||
complete -c apt-get -s b -l build --description 'Compile source packages'
|
||||
complete -c apt-get -l ignore-hold --description 'Ignore package Holds'
|
||||
complete -c apt-get -l no-upgrade --description "Do not upgrade packages"
|
||||
complete -c apt-get -l force-yes --description 'Force yes'
|
||||
complete -c apt-get -l print-uris --description 'Print the URIs'
|
||||
complete -c apt-get -l purge --description 'Use purge instead of remove'
|
||||
complete -c apt-get -l reinstall --description 'Reinstall packages'
|
||||
complete -c apt-get -l list-cleanup --description 'Erase obsolete files'
|
||||
complete -c apt-get -s t -l target-release --description 'Control default input to the policy engine'
|
||||
complete -c apt-get -l trivial-only --description 'Only perform operations that are trivial'
|
||||
complete -c apt-get -l no-remove --description 'Abort if any packages are to be removed'
|
||||
complete -c apt-get -l only-source --description 'Only accept source packages'
|
||||
complete -c apt-get -l diff-only --description 'Download only diff file'
|
||||
complete -c apt-get -l tar-only --description 'Download only tar file'
|
||||
complete -c apt-get -l arch-only --description 'Only process arch-dependant build-dependencies'
|
||||
complete -c apt-get -l allow-unauthenticated --description 'Ignore non-authenticated packages'
|
||||
complete -c apt-get -s v -l version --description 'Display version and exit'
|
||||
complete -r -c apt-get -s c -l config-file --description 'Specify a config file'
|
||||
complete -r -c apt-get -s o -l option --description 'Set a config option'
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#apt-key
|
||||
complete -r -c apt-key -a add -d (N_ "Add a new key")
|
||||
complete -f -c apt-key -a del -d (N_ "Remove a key")
|
||||
complete -f -c apt-key -a list -d (N_ "List trusted keys")
|
||||
complete -r -c apt-key -a add --description "Add a new key"
|
||||
complete -f -c apt-key -a del --description "Remove a key"
|
||||
complete -f -c apt-key -a list --description "List trusted keys"
|
||||
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
#apt-listbugs
|
||||
complete -c apt-listbugs -s h -l help -d (N_ "Display help and exit")
|
||||
complete -f -c apt-listbugs -s s -l severity -a "critical grave" -d (N_ "Set severity")
|
||||
complete -f -c apt-listbugs -s T -l tag -d (N_ "Tags you want to see")
|
||||
complete -f -c apt-listbugs -s S -l stats -a "outstanding 'pending upload' resolved done open" -d (N_ "Bug-status you want to see")
|
||||
complete -f -c apt-listbugs -s l -l showless -d (N_ "Ignore bugs in your system")
|
||||
complete -f -c apt-listbugs -s g -l showgreater -d (N_ "Ignore newer bugs than upgrade packages")
|
||||
complete -f -c apt-listbugs -s D -l show-downgrade -d (N_ "Bugs for downgrade packages")
|
||||
complete -f -c apt-listbugs -s H -l hostname -a "osdn.debian.or.jp" -d (N_ "Bug Tracking system")
|
||||
complete -f -c apt-listbugs -s p -l port -d (N_ "Specify port for web interface")
|
||||
complete -f -c apt-listbugs -s R -l release-critical -d (N_ "Use daily bug report")
|
||||
complete -f -c apt-listbugs -s I -l index -d (N_ "Use the raw index.db")
|
||||
complete -f -c apt-listbugs -s X -l indexdir -d (N_ "Specify index dir")
|
||||
complete -f -c apt-listbugs -s P -l pin-priority -d (N_ "Specify Pin-Priority value")
|
||||
complete -f -c apt-listbugs -l title -d (N_ "Specify the title of rss")
|
||||
complete -f -c apt-listbugs -s f -l force-download -d (N_ "Retrieve fresh bugs")
|
||||
complete -f -c apt-listbugs -s q -l quiet -d (N_ "Do not display progress bar")
|
||||
complete -f -c apt-listbugs -s c -l cache-dir -a "/var/cache/apt-listbugs/" -d (N_ "Specify local cache dir")
|
||||
complete -f -c apt-listbugs -s t -l timer -d (N_ "Specify the expire cache timer")
|
||||
complete -c apt-listbugs -s C -l aptconf -d (N_ "Specify apt config file")
|
||||
complete -f -c apt-listbugs -s y -l force-yes -d (N_ "Assume yes to all questions")
|
||||
complete -f -c apt-listbugs -s n -l force-no -d (N_ "Assume no to all questions")
|
||||
complete -c apt-listbugs -a list -d (N_ "List bugs from packages")
|
||||
complete -c apt-listbugs -a rss -d (N_ "List bugs in rss format")
|
||||
complete -c apt-listbugs -s h -l help --description "Display help and exit"
|
||||
complete -f -c apt-listbugs -s s -l severity -a "critical grave" --description "Set severity"
|
||||
complete -f -c apt-listbugs -s T -l tag --description "Tags you want to see"
|
||||
complete -f -c apt-listbugs -s S -l stats -a "outstanding 'pending upload' resolved done open" --description "Bug-status you want to see"
|
||||
complete -f -c apt-listbugs -s l -l showless --description "Ignore bugs in your system"
|
||||
complete -f -c apt-listbugs -s g -l showgreater --description "Ignore newer bugs than upgrade packages"
|
||||
complete -f -c apt-listbugs -s D -l show-downgrade --description "Bugs for downgrade packages"
|
||||
complete -f -c apt-listbugs -s H -l hostname -a "osdn.debian.or.jp" --description "Bug Tracking system"
|
||||
complete -f -c apt-listbugs -s p -l port --description "Specify port for web interface"
|
||||
complete -f -c apt-listbugs -s R -l release-critical --description "Use daily bug report"
|
||||
complete -f -c apt-listbugs -s I -l index --description "Use the raw index.db"
|
||||
complete -f -c apt-listbugs -s X -l indexdir --description "Specify index dir"
|
||||
complete -f -c apt-listbugs -s P -l pin-priority --description "Specify Pin-Priority value"
|
||||
complete -f -c apt-listbugs -l title --description "Specify the title of rss"
|
||||
complete -f -c apt-listbugs -s f -l force-download --description "Retrieve fresh bugs"
|
||||
complete -f -c apt-listbugs -s q -l quiet --description "Do not display progress bar"
|
||||
complete -f -c apt-listbugs -s c -l cache-dir -a "/var/cache/apt-listbugs/" --description "Specify local cache dir"
|
||||
complete -f -c apt-listbugs -s t -l timer --description "Specify the expire cache timer"
|
||||
complete -c apt-listbugs -s C -l aptconf --description "Specify apt config file"
|
||||
complete -f -c apt-listbugs -s y -l force-yes --description "Assume yes to all questions"
|
||||
complete -f -c apt-listbugs -s n -l force-no --description "Assume no to all questions"
|
||||
complete -c apt-listbugs -a list --description "List bugs from packages"
|
||||
complete -c apt-listbugs -a rss --description "List bugs in rss format"
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#apt-listchanges
|
||||
complete -c apt-listchanges -l help -d (N_ "Display help and exit")
|
||||
complete -c apt-listchanges -l apt -d (N_ "Read filenames from pipe")
|
||||
complete -f -c apt-listchanges -s v -l verbose -d (N_ "Verbose mode")
|
||||
complete -f -c apt-listchanges -s f -l frontend -a "pager browser xterm-pager xterm-browser text mail none" -d (N_ "Select frontend interface")
|
||||
complete -r -f -c apt-listchanges -l email-address -d (N_ "Specify email address")
|
||||
complete -f -c apt-listchanges -s c -l confirm -d (N_ "Ask confirmation")
|
||||
complete -f -c apt-listchanges -s a -l all -d (N_ "Display all changelogs")
|
||||
complete -r -c apt-listchanges -l save_seen -d (N_ "Avoid changelogs from db in named file")
|
||||
complete -r -f -c apt-listchanges -l which -a "news changelogs both" -d (N_ "Select display")
|
||||
complete -f -c apt-listchanges -s h -l headers -d (N_ "Insert header")
|
||||
complete -f -c apt-listchanges -l debug -d (N_ "Display debug info")
|
||||
complete -r -c apt-listchanges -l profile -d (N_ "Select an option profile")
|
||||
complete -c apt-listchanges -l help --description "Display help and exit"
|
||||
complete -c apt-listchanges -l apt --description "Read filenames from pipe"
|
||||
complete -f -c apt-listchanges -s v -l verbose --description "Verbose mode"
|
||||
complete -f -c apt-listchanges -s f -l frontend -a "pager browser xterm-pager xterm-browser text mail none" --description "Select frontend interface"
|
||||
complete -r -f -c apt-listchanges -l email-address --description "Specify email address"
|
||||
complete -f -c apt-listchanges -s c -l confirm --description "Ask confirmation"
|
||||
complete -f -c apt-listchanges -s a -l all --description "Display all changelogs"
|
||||
complete -r -c apt-listchanges -l save_seen --description "Avoid changelogs from db in named file"
|
||||
complete -r -f -c apt-listchanges -l which -a "news changelogs both" --description "Select display"
|
||||
complete -f -c apt-listchanges -s h -l headers --description "Insert header"
|
||||
complete -f -c apt-listchanges -l debug --description "Display debug info"
|
||||
complete -r -c apt-listchanges -l profile --description "Select an option profile"
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
#apt-move
|
||||
complete -c apt-move -a get -d (N_ "Generate master file")
|
||||
complete -c apt-move -a getlocal -d (N_ "Alias for 'get'")
|
||||
complete -f -c apt-move -a move -d (N_ "Move packages to local tree")
|
||||
complete -f -c apt-move -a delete -d (N_ "Delete obsolete package files")
|
||||
complete -f -c apt-move -a packages -d (N_ "Build new local files")
|
||||
complete -f -c apt-move -a fsck -d (N_ "Rebuild index files")
|
||||
complete -f -c apt-move -a update -d (N_ "Move packages from cache to local mirror")
|
||||
complete -f -c apt-move -a local -d (N_ "Alias for 'move delete packages'")
|
||||
complete -f -c apt-move -a localupdate -d (N_ "Alias for 'update'")
|
||||
complete -f -c apt-move -a mirror -d (N_ "Download package missing from mirror")
|
||||
complete -f -c apt-move -a sync -d (N_ "Sync packages installed")
|
||||
complete -c apt-move -a get --description "Generate master file"
|
||||
complete -c apt-move -a getlocal --description "Alias for 'get'"
|
||||
complete -f -c apt-move -a move --description "Move packages to local tree"
|
||||
complete -f -c apt-move -a delete --description "Delete obsolete package files"
|
||||
complete -f -c apt-move -a packages --description "Build new local files"
|
||||
complete -f -c apt-move -a fsck --description "Rebuild index files"
|
||||
complete -f -c apt-move -a update --description "Move packages from cache to local mirror"
|
||||
complete -f -c apt-move -a local --description "Alias for 'move delete packages'"
|
||||
complete -f -c apt-move -a localupdate --description "Alias for 'update'"
|
||||
complete -f -c apt-move -a mirror --description "Download package missing from mirror"
|
||||
complete -f -c apt-move -a sync --description "Sync packages installed"
|
||||
complete -f -c apt-move -a exclude -d 'test $LOCALDIR/.exclude file'
|
||||
complete -c apt-move -a movefile -d (N_ "Move file specified on commandline")
|
||||
complete -f -c apt-move -a listbin -d (N_ "List packages that may serve as input to mirrorbin or mirrorsource" )
|
||||
complete -f -c apt-move -a mirrorbin -d (N_ "Fetch package from STDIN")
|
||||
complete -f -c apt-move -a mirrorsrc -d (N_ "Fetch source package from STDIN")
|
||||
complete -f -c apt-move -s a -d (N_ "Process all packages")
|
||||
complete -c apt-move -s c -d (N_ "Use specific conffile")
|
||||
complete -f -c apt-move -s f -d (N_ "Force deletion")
|
||||
complete -f -c apt-move -s q -d (N_ "Suppresses normal output")
|
||||
complete -f -c apt-move -s t -d (N_ "Test run")
|
||||
complete -c apt-move -a movefile --description "Move file specified on commandline"
|
||||
complete -f -c apt-move -a listbin --description 'List packages that may serve as input to mirrorbin or mirrorsource'
|
||||
complete -f -c apt-move -a mirrorbin --description "Fetch package from STDIN"
|
||||
complete -f -c apt-move -a mirrorsrc --description "Fetch source package from STDIN"
|
||||
complete -f -c apt-move -s a --description "Process all packages"
|
||||
complete -c apt-move -s c --description "Use specific conffile"
|
||||
complete -f -c apt-move -s f --description "Force deletion"
|
||||
complete -f -c apt-move -s q --description "Suppresses normal output"
|
||||
complete -f -c apt-move -s t --description "Test run"
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#apt-proxy-import
|
||||
complete -c apt-proxy-import -s h -l help -d (N_ 'Display help and exit')
|
||||
complete -f -c apt-proxy-import -s V -l version -d (N_ 'Display version and exit')
|
||||
complete -f -c apt-proxy-import -s v -l verbose -d (N_ 'Verbose mode')
|
||||
complete -f -c apt-proxy-import -s q -l quiet -d (N_ 'No message to STDOUT')
|
||||
complete -f -c apt-proxy-import -s r -l recursive -d (N_ 'Recurse into subdir')
|
||||
complete -r -c apt-proxy-import -s i -l import-dir -a '(ls -Fp|grep /\$)' -d (N_ 'Dir to import')
|
||||
complete -r -c apt-proxy-import -s u -l user -a '(__fish_complete_users)' -d (N_ 'Change to user')
|
||||
complete -r -c apt-proxy-import -s d -l debug -d (N_ 'Debug level[default 0]')
|
||||
complete -c apt-proxy-import -s h -l help --description 'Display help and exit'
|
||||
complete -f -c apt-proxy-import -s V -l version --description 'Display version and exit'
|
||||
complete -f -c apt-proxy-import -s v -l verbose --description 'Verbose mode'
|
||||
complete -f -c apt-proxy-import -s q -l quiet --description 'No message to STDOUT'
|
||||
complete -f -c apt-proxy-import -s r -l recursive --description 'Recurse into subdir'
|
||||
complete -r -c apt-proxy-import -s i -l import-dir -a '(ls -Fp|sgrep /\$)' --description 'Dir to import'
|
||||
complete -r -c apt-proxy-import -s u -l user -a '(__fish_complete_users)' --description 'Change to user'
|
||||
complete -r -c apt-proxy-import -s d -l debug --description 'Debug level[default 0]'
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#apt-rdepends
|
||||
complete -c apt-rdepends -l help -d (N_ "Display help and exit")
|
||||
complete -f -c apt-rdepends -s b -l build-depends -d (N_ "Show build dependencies")
|
||||
complete -f -c apt-rdepends -s d -l dotty -d (N_ "Generate a dotty graph")
|
||||
complete -f -c apt-rdepends -s p -l print-state -d (N_ "Show state of dependencies")
|
||||
complete -f -c apt-rdepends -s r -l reverse -d (N_ "List packages depending on")
|
||||
complete -r -f -c apt-rdepends -s f -l follow -d (N_ "Comma-separated list of dependancy types to follow recursively")
|
||||
complete -r -f -c apt-rdepends -s s -l show -d (N_ "Comma-separated list of dependancy types to show")
|
||||
complete -r -f -c apt-rdepends -l state-follow -d (N_ "Comma-separated list of package installation states to follow recursively")
|
||||
complete -r -f -c apt-rdepends -l state-show -d (N_ "Comma-separated list of package installation states to show")
|
||||
complete -f -c apt-rdepends -l man -d (N_ "Display man page")
|
||||
complete -f -c apt-rdepends -l version -d (N_ "Display version and exit")
|
||||
complete -c apt-rdepends -l help --description "Display help and exit"
|
||||
complete -f -c apt-rdepends -s b -l build-depends --description "Show build dependencies"
|
||||
complete -f -c apt-rdepends -s d -l dotty --description "Generate a dotty graph"
|
||||
complete -f -c apt-rdepends -s p -l print-state --description "Show state of dependencies"
|
||||
complete -f -c apt-rdepends -s r -l reverse --description "List packages depending on"
|
||||
complete -r -f -c apt-rdepends -s f -l follow --description "Comma-separated list of dependancy types to follow recursively"
|
||||
complete -r -f -c apt-rdepends -s s -l show --description "Comma-separated list of dependancy types to show"
|
||||
complete -r -f -c apt-rdepends -l state-follow --description "Comma-separated list of package installation states to follow recursively"
|
||||
complete -r -f -c apt-rdepends -l state-show --description "Comma-separated list of package installation states to show"
|
||||
complete -f -c apt-rdepends -l man --description "Display man page"
|
||||
complete -f -c apt-rdepends -l version --description "Display version and exit"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#apt-setup
|
||||
complete -c apt-setup -a probe -d (N_ "Probe a CD")
|
||||
complete -c apt-setup -s N -d (N_ "Run in noninteractive mode")
|
||||
complete -c apt-setup -a probe --description "Probe a CD"
|
||||
complete -c apt-setup -s N --description "Run in noninteractive mode"
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#apt-show-source
|
||||
complete -c apt-show-source -s h -l help -d (N_ 'Display help and exit')
|
||||
complete -r -c apt-show-source -l status-file -d (N_ 'Read package from file') -f
|
||||
complete -r -c apt-show-source -o stf -d (N_ 'Read package from file') -f
|
||||
complete -r -c apt-show-source -l list-dir -a '(ls -Fp .|grep /\$) /var/lib/apt/lists' -d (N_ 'Specify APT list dir')
|
||||
complete -r -c apt-show-source -o ld -a '(ls -Fp .|grep /\$) /var/lib/apt/lists' -d (N_ 'Specify APT list dir')
|
||||
complete -r -c apt-show-source -s p -l package -a '(apt-cache pkgnames)' -d (N_ 'List PKG info')
|
||||
complete -f -c apt-show-source -l version-only -d (N_ 'Display version and exit')
|
||||
complete -f -c apt-show-source -s a -l all -d (N_ 'Print all source packages with version')
|
||||
complete -f -c apt-show-source -s v -l verbose -d (N_ 'Verbose mode')
|
||||
complete -c apt-show-source -s h -l help --description 'Display help and exit'
|
||||
complete -r -c apt-show-source -l status-file --description 'Read package from file' -f
|
||||
complete -r -c apt-show-source -o stf --description 'Read package from file' -f
|
||||
complete -r -c apt-show-source -l list-dir -a '(ls -Fp .|sgrep /\$) /var/lib/apt/lists' --description 'Specify APT list dir'
|
||||
complete -r -c apt-show-source -o ld -a '(ls -Fp .|sgrep /\$) /var/lib/apt/lists' --description 'Specify APT list dir'
|
||||
complete -r -c apt-show-source -s p -l package -a '(apt-cache pkgnames)' --description 'List PKG info'
|
||||
complete -f -c apt-show-source -l version-only --description 'Display version and exit'
|
||||
complete -f -c apt-show-source -s a -l all --description 'Print all source packages with version'
|
||||
complete -f -c apt-show-source -s v -l verbose --description 'Verbose mode'
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#apt-show-versions
|
||||
complete -c apt-show-source -s h -l help -d (N_ 'Display help and exit')
|
||||
complete -r -c apt-show-versions -s p -l packages -a '(apt-cache pkgnames)' -d (N_ 'Print PKG versions')
|
||||
complete -f -c apt-show-versions -s r -l regex -d (N_ 'Using regex')
|
||||
complete -f -c apt-show-versions -s u -l upgradeable -d (N_ 'Print only upgradeable packages')
|
||||
complete -f -c apt-show-versions -s a -l allversions -d (N_ 'Print all versions')
|
||||
complete -f -c apt-show-versions -s b -l brief -d (N_ 'Print package name/distro')
|
||||
complete -f -c apt-show-versions -s v -l verbose -d (N_ 'Print verbose info')
|
||||
complete -f -c apt-show-versions -s i -l initialize -d (N_ 'Init or update cache only')
|
||||
complete -r -c apt-show-versions -l status-file -d (N_ 'Read package from file')
|
||||
complete -r -c apt-show-versions -o stf -d (N_ 'Read package from file')
|
||||
complete -r -c apt-show-versions -l list-dir -a '(ls -Fp .|grep /\$) /var/lib/apt/lists /var/state/apt/lists' -d (N_ 'Specify APT list dir')
|
||||
complete -r -c apt-show-versions -o ld -a '(ls -Fp .|grep /\$) /var/lib/apt/lists /var/state/apt/lists' -d (N_ 'Specify APT list dir')
|
||||
complete -c apt-show-source -s h -l help --description 'Display help and exit'
|
||||
complete -r -c apt-show-versions -s p -l packages -a '(apt-cache pkgnames)' --description 'Print PKG versions'
|
||||
complete -f -c apt-show-versions -s r -l regex --description 'Using regex'
|
||||
complete -f -c apt-show-versions -s u -l upgradeable --description 'Print only upgradeable packages'
|
||||
complete -f -c apt-show-versions -s a -l allversions --description 'Print all versions'
|
||||
complete -f -c apt-show-versions -s b -l brief --description 'Print package name/distro'
|
||||
complete -f -c apt-show-versions -s v -l verbose --description 'Print verbose info'
|
||||
complete -f -c apt-show-versions -s i -l initialize --description 'Init or update cache only'
|
||||
complete -r -c apt-show-versions -l status-file --description 'Read package from file'
|
||||
complete -r -c apt-show-versions -o stf --description 'Read package from file'
|
||||
complete -r -c apt-show-versions -l list-dir -a '(ls -Fp .|sgrep /\$) /var/lib/apt/lists /var/state/apt/lists' --description 'Specify APT list dir'
|
||||
complete -r -c apt-show-versions -o ld -a '(ls -Fp .|sgrep /\$) /var/lib/apt/lists /var/state/apt/lists' --description 'Specify APT list dir'
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#apt-sortpkgs
|
||||
complete -c apt-sortpkgs -s h -l help -d (N_ "Display help and exit")
|
||||
complete -f -c apt-sortpkgs -s s -l source -d (N_ "Use source index field")
|
||||
complete -f -c apt-sortpkgs -s v -l version -d (N_ "Display version and exit")
|
||||
complete -r -c apt-sortpkgs -s c -l conf-file -d (N_ "Specify conffile")
|
||||
complete -r -f -c apt-sortpkgs -s o -l option -d (N_ "Set config options")
|
||||
complete -c apt-sortpkgs -s h -l help --description "Display help and exit"
|
||||
complete -f -c apt-sortpkgs -s s -l source --description "Use source index field"
|
||||
complete -f -c apt-sortpkgs -s v -l version --description "Display version and exit"
|
||||
complete -r -c apt-sortpkgs -s c -l conf-file --description "Specify conffile"
|
||||
complete -r -f -c apt-sortpkgs -s o -l option --description "Set config options"
|
||||
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
#apt-spy
|
||||
complete -c apt-spy -s h -d (N_ "Display help and exit")
|
||||
complete -f -c apt-spy -s d -a "stable testing unstable" -d (N_ "Debian distribution")
|
||||
complete -f -c apt-spy -s a -a "Africa Asia Europe North-America Oceania South-America" -d (N_ "Servers in the areas")
|
||||
complete -c apt-spy -s c -d (N_ "Conf file")
|
||||
complete -f -c apt-spy -s e -d (N_ "Finish after number of servers")
|
||||
complete -c apt-spy -s f -d (N_ "File to grab servers")
|
||||
complete -c apt-spy -s i -d (N_ "File as input")
|
||||
complete -c apt-spy -s m -d (N_ "Mirror-list file")
|
||||
complete -c apt-spy -s o -d (N_ "Output sources.list file")
|
||||
complete -f -c apt-spy -s p -d (N_ "Use proxy server")
|
||||
complete -f -c apt-spy -s s -d (N_ "Comma separated country list")
|
||||
complete -f -c apt-spy -s t -d (N_ "How long in sec to download")
|
||||
complete -f -c apt-spy -s u -d (N_ "Custom URL to get mirror list")
|
||||
complete -c apt-spy -s w -d (N_ "Write top servers to file")
|
||||
complete -f -c apt-spy -s n -d (N_ "Number of top servers")
|
||||
complete -f -c apt-spy -a "update" -d (N_ "Update mirror list")
|
||||
complete -f -c apt-spy -s v -d (N_ "Version number")
|
||||
complete -c apt-spy -s h --description "Display help and exit"
|
||||
complete -f -c apt-spy -s d -a "stable testing unstable" --description "Debian distribution"
|
||||
complete -f -c apt-spy -s a -a "Africa Asia Europe North-America Oceania South-America" --description "Servers in the areas"
|
||||
complete -c apt-spy -s c --description "Conf file"
|
||||
complete -f -c apt-spy -s e --description "Finish after number of servers"
|
||||
complete -c apt-spy -s f --description "File to grab servers"
|
||||
complete -c apt-spy -s i --description "File as input"
|
||||
complete -c apt-spy -s m --description "Mirror-list file"
|
||||
complete -c apt-spy -s o --description "Output sources.list file"
|
||||
complete -f -c apt-spy -s p --description "Use proxy server"
|
||||
complete -f -c apt-spy -s s --description "Comma separated country list"
|
||||
complete -f -c apt-spy -s t --description "How long in sec to download"
|
||||
complete -f -c apt-spy -s u --description "Custom URL to get mirror list"
|
||||
complete -c apt-spy -s w --description "Write top servers to file"
|
||||
complete -f -c apt-spy -s n --description "Number of top servers"
|
||||
complete -f -c apt-spy -a "update" --description "Update mirror list"
|
||||
complete -f -c apt-spy -s v --description "Version number"
|
||||
|
||||
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
#apt-src
|
||||
complete -c apt-src -s h -l help -d (N_ "Display help and exit")
|
||||
complete -f -c apt-src -a "update" -d (N_ "Update list of source packages")
|
||||
complete -f -c apt-src -a "install" -d (N_ "Install source packages")
|
||||
complete -f -c apt-src -a "upgrade" -d (N_ "Upgrade source packages")
|
||||
complete -f -c apt-src -a "remove" -d (N_ "Remove source packages")
|
||||
complete -f -c apt-src -a "build" -d (N_ "Build source packages")
|
||||
complete -f -c apt-src -a "clean" -d (N_ "Clean source packages")
|
||||
complete -f -c apt-src -a "import" -d (N_ "Detect known source tree")
|
||||
complete -f -c apt-src -a "list" -d (N_ "List installed source package\(s\)")
|
||||
complete -f -c apt-src -a "location" -d (N_ "Root source tree")
|
||||
complete -f -c apt-src -a "version" -d (N_ "Version of source package")
|
||||
complete -f -c apt-src -a "name" -d (N_ "Name of the source package")
|
||||
complete -f -c apt-src -s b -l build -d (N_ "Build source packages")
|
||||
complete -f -c apt-src -s i -l installdebs -d (N_ "Install after build")
|
||||
complete -f -c apt-src -s p -l patch -d (N_ "Patch local changes")
|
||||
complete -r -c apt-src -s l -l location -d (N_ "Specify a dir")
|
||||
complete -c apt-src -s c -l here -d (N_ "Run on current dir")
|
||||
complete -f -c apt-src -l upstream-version -d (N_ "Omit debian version")
|
||||
complete -f -c apt-src -s k -l keep-built -d (N_ "Do not del built files")
|
||||
complete -f -c apt-src -s n -l no-delete-source -d (N_ "Do not del source files")
|
||||
complete -f -c apt-src -l version -d (N_ "Source tree version")
|
||||
complete -f -c apt-src -s q -l quiet -d (N_ "Output to /dev/null")
|
||||
complete -f -c apt-src -s t -l trace -d (N_ "Output trace")
|
||||
complete -c apt-src -s h -l help --description "Display help and exit"
|
||||
complete -f -c apt-src -a "update" --description "Update list of source packages"
|
||||
complete -f -c apt-src -a "install" --description "Install source packages"
|
||||
complete -f -c apt-src -a "upgrade" --description "Upgrade source packages"
|
||||
complete -f -c apt-src -a "remove" --description "Remove source packages"
|
||||
complete -f -c apt-src -a "build" --description "Build source packages"
|
||||
complete -f -c apt-src -a "clean" --description "Clean source packages"
|
||||
complete -f -c apt-src -a "import" --description "Detect known source tree"
|
||||
complete -f -c apt-src -a "list" --description "List installed source package\(s\)"
|
||||
complete -f -c apt-src -a "location" --description "Root source tree"
|
||||
complete -f -c apt-src -a "version" --description "Version of source package"
|
||||
complete -f -c apt-src -a "name" --description "Name of the source package"
|
||||
complete -f -c apt-src -s b -l build --description "Build source packages"
|
||||
complete -f -c apt-src -s i -l installdebs --description "Install after build"
|
||||
complete -f -c apt-src -s p -l patch --description "Patch local changes"
|
||||
complete -r -c apt-src -s l -l location --description "Specify a dir"
|
||||
complete -c apt-src -s c -l here --description "Run on current dir"
|
||||
complete -f -c apt-src -l upstream-version --description "Omit debian version"
|
||||
complete -f -c apt-src -s k -l keep-built --description "Do not del built files"
|
||||
complete -f -c apt-src -s n -l no-delete-source --description "Do not del source files"
|
||||
complete -f -c apt-src -l version --description "Source tree version"
|
||||
complete -f -c apt-src -s q -l quiet --description "Output to /dev/null"
|
||||
complete -f -c apt-src -s t -l trace --description "Output trace"
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#apt-zip-inst
|
||||
complete -c apt-zip-inst -s h -l help -d (N_ "Display help and exit")
|
||||
complete -f -c apt-zip-inst -s V -l version -d (N_ "Display version and exit")
|
||||
complete -c apt-zip-inst -s m -l medium -d (N_ "Removable medium")
|
||||
complete -f -c apt-zip-inst -s a -l aptgetaction -a "dselect-upgrade upgrade dist-upgrade" -d (N_ "Select an action")
|
||||
complete -c apt-zip-inst -s p -l packages -d (N_ "List of packages to install")
|
||||
complete -f -c apt-zip-inst -s f -l fix-broken -d (N_ "Fix broken option")
|
||||
complete -c apt-zip-inst -l skip-mount -d (N_ "Specify a non-mountpoint dir")
|
||||
complete -c apt-zip-inst -s h -l help --description "Display help and exit"
|
||||
complete -f -c apt-zip-inst -s V -l version --description "Display version and exit"
|
||||
complete -c apt-zip-inst -s m -l medium --description "Removable medium"
|
||||
complete -f -c apt-zip-inst -s a -l aptgetaction -a "dselect-upgrade upgrade dist-upgrade" --description "Select an action"
|
||||
complete -c apt-zip-inst -s p -l packages --description "List of packages to install"
|
||||
complete -f -c apt-zip-inst -s f -l fix-broken --description "Fix broken option"
|
||||
complete -c apt-zip-inst -l skip-mount --description "Specify a non-mountpoint dir"
|
||||
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#apt-zip-list
|
||||
complete -c apt-zip-list -s h -l help -d (N_ "Display help and exit")
|
||||
complete -f -c apt-zip-list -s V -l version -d (N_ "Display version and exit")
|
||||
complete -c apt-zip-list -s m -l medium -d (N_ "Removable medium")
|
||||
complete -f -c apt-zip-list -s a -l aptgetaction -a "dselect-upgrade upgrade dist-upgrade" -d (N_ "Select an action")
|
||||
complete -c apt-zip-list -s p -l packages -d (N_ "List of packages to install")
|
||||
complete -f -c apt-zip-list -s f -l fix-broken -d (N_ "Fix broken option")
|
||||
complete -c apt-zip-list -l skip-mount -d (N_ "Specify a non-mountpoint dir")
|
||||
complete -c apt-zip-list -s M -l method -d (N_ "Select a method")
|
||||
complete -c apt-zip-list -s o -l options -a "tar restart" -d (N_ "Specify options")
|
||||
complete -c apt-zip-list -s A -l accept -a "http ftp" -d (N_ "Accept protocols")
|
||||
complete -c apt-zip-list -s R -l reject -a "http ftp" -d (N_ "Reject protocols")
|
||||
complete -c apt-zip-list -s h -l help --description "Display help and exit"
|
||||
complete -f -c apt-zip-list -s V -l version --description "Display version and exit"
|
||||
complete -c apt-zip-list -s m -l medium --description "Removable medium"
|
||||
complete -f -c apt-zip-list -s a -l aptgetaction -a "dselect-upgrade upgrade dist-upgrade" --description "Select an action"
|
||||
complete -c apt-zip-list -s p -l packages --description "List of packages to install"
|
||||
complete -f -c apt-zip-list -s f -l fix-broken --description "Fix broken option"
|
||||
complete -c apt-zip-list -l skip-mount --description "Specify a non-mountpoint dir"
|
||||
complete -c apt-zip-list -s M -l method --description "Select a method"
|
||||
complete -c apt-zip-list -s o -l options -a "tar restart" --description "Specify options"
|
||||
complete -c apt-zip-list -s A -l accept -a "http ftp" --description "Accept protocols"
|
||||
complete -c apt-zip-list -s R -l reject -a "http ftp" --description "Reject protocols"
|
||||
|
||||
|
||||
68
share/completions/aptitude.fish
Normal file
68
share/completions/aptitude.fish
Normal file
@@ -0,0 +1,68 @@
|
||||
#completion for aptitude
|
||||
|
||||
function __fish_apt_no_subcommand --description 'Test if aptitude has yet to be given the subcommand'
|
||||
for i in (commandline -opc)
|
||||
if contains -- $i autoclean clean forget-new keep-all update upgrade changelog dist-upgrade download forbid-version hold install keep markauto purge reinstall remove show unhold unmarkauto search help
|
||||
return 1
|
||||
end
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
function __fish_apt_use_package --description 'Test if aptitude command should have packages as potential completion'
|
||||
for i in (commandline -opc)
|
||||
if contains -- $i changelog dist-upgrade download forbid-version hold install keep-all markauto purge reinstall remove show unhold unmarkauto
|
||||
return 0
|
||||
end
|
||||
end
|
||||
return 1
|
||||
end
|
||||
|
||||
complete -c aptitude -n '__fish_apt_use_package' -a '(__fish_print_packages)' --description 'Package'
|
||||
|
||||
complete -c aptitude -s h -l help --description 'Display a brief help message. Identical to the help action'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c aptitude -a 'autoclean' --description 'Remove any cached packages which can no longer be downloaded'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c aptitude -a 'clean' --description 'Remove all downloaded .deb files from the package cache directory'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c aptitude -a 'forget-new' --description 'Forget all internal information about what packages are “new”'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c aptitude -a 'keep-all' --description 'Cancel all scheduled actions on all packages'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c aptitude -a 'update' --description 'Update the list of available packages from the apt sources'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c aptitude -a 'upgrade' --description 'Upgrade installed packages to their most recent version'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c aptitude -a 'changelog' --description 'Download and displays the Debian changelog for the packages'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c aptitude -a 'dist-upgrade' --description 'Upgrade, removing or installing packages as necessary'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c aptitude -a 'download' --description 'Download the packages to the current directory'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c aptitude -a 'forbid-version' --description 'Forbid the upgrade to a particular version'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c aptitude -a 'hold' --description 'Ignore the packages by future upgrade commands'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c aptitude -a 'install' --description 'Install the packages'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c aptitude -a 'keep' --description 'Cancel any scheduled actions on the packages'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c aptitude -a 'markauto' --description 'Mark packages as automatically installed'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c aptitude -a 'purge' --description 'Remove and delete all associated configuration and data files'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c aptitude -a 'reinstall' --description 'Reinstall the packages'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c aptitude -a 'remove' --description 'Remove the packages'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c aptitude -a 'show' --description 'Display detailed information about the packages'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c aptitude -a 'unhold' --description 'Consider the packages by future upgrade commands'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c aptitude -a 'unmarkauto' --description 'Mark packages as manually installed'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c aptitude -a 'search' --description 'Search for packages matching one of the patterns'
|
||||
complete -f -n '__fish_apt_no_subcommand' -c aptitude -a 'help' --description 'Display brief summary of the available commands and options'
|
||||
|
||||
complete -c aptitude -s D -l show-deps --description 'Show explanations of automatic installations and removals'
|
||||
complete -c aptitude -s d -l download-only --description 'Download Only'
|
||||
complete -c aptitude -s f -l fix-broken --description 'Correct broken dependencies'
|
||||
complete -c aptitude -l purge-unused --description 'Purge packages that are not required by any installed package'
|
||||
complete -c aptitude -s P -l prompt --description 'Always display a prompt'
|
||||
complete -c aptitude -s R -l without-recommends --description 'Do not treat recommendations as dependencies'
|
||||
complete -c aptitude -s r -l with-recommends --description 'Treat recommendations as dependencies'
|
||||
complete -c aptitude -s s -l simulate --description 'Don\'t perform the actions. Just show them'
|
||||
complete -c aptitude -l schedule-only --description 'Schedule operations to be performed in the future'
|
||||
complete -c aptitude -s q -l quiet --description 'Suppress incremental progress indicators'
|
||||
complete -c aptitude -s V -l show-versions --description 'Show which versions of packages will be installed'
|
||||
complete -c aptitude -s v -l verbose --description 'Display extra information'
|
||||
complete -c aptitude -l version --description 'Display the version of aptitude and compile information'
|
||||
complete -c aptitude -l visual-preview --description 'Start up the visual interface and display its preview screen'
|
||||
complete -c aptitude -s y -l assume-yes --description 'Assume the answer yes for all question prompts'
|
||||
complete -c aptitude -s Z --description 'Show how much disk space will be used or freed'
|
||||
complete -r -c aptitude -s F -l display-format --description 'Specify the format to be used by the search command'
|
||||
complete -r -c aptitude -s t -l target-release --description 'Set the release from which packages should be installed'
|
||||
complete -r -c aptitude -s O -l sort --description 'Specify the order for the output from the search command'
|
||||
complete -r -c aptitude -s o --description 'Set a configuration file option directly'
|
||||
complete -r -c aptitude -s w -l width --description 'Specify the display width for the output from the search command'
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#completion for arp
|
||||
complete -c arp -s v -l verbose -d (N_ "Verbose mode")
|
||||
complete -c arp -s n -l numeric -d (N_ "Numerical address")
|
||||
complete -x -c arp -s H -l tw-type -a "ether arcnet pronet ax25 netrom" -d (N_ "Class of hw type")
|
||||
complete -c arp -s a -l display -x -a "(__fish_print_hostnames)" -d (N_ "Show arp entries")
|
||||
complete -x -c arp -s d -l delete -a "(__fish_print_hostnames)" -d (N_ "Remove an entry for hostname")
|
||||
complete -c arp -s D -l use-device -d (N_ "Use hardware address")
|
||||
complete -x -c arp -s i -l device -a "(__fish_print_interfaces)" -d (N_ "Select interface")
|
||||
complete -x -c arp -s s -l set -d (N_ "Manually create ARP address") -a "(__fish_print_hostnames)"
|
||||
complete -f -c arp -s f -l file -d (N_ "Take addr from filename, default /etc/ethers")
|
||||
complete -c arp -s v -l verbose --description "Verbose mode"
|
||||
complete -c arp -s n -l numeric --description "Numerical address"
|
||||
complete -x -c arp -s H -l tw-type -a "ether arcnet pronet ax25 netrom" --description "Class of hw type"
|
||||
complete -c arp -s a -l display -x -a "(__fish_print_hostnames)" --description "Show arp entries"
|
||||
complete -x -c arp -s d -l delete -a "(__fish_print_hostnames)" --description "Remove an entry for hostname"
|
||||
complete -c arp -s D -l use-device --description "Use hardware address"
|
||||
complete -x -c arp -s i -l device -a "(__fish_print_interfaces)" --description "Select interface"
|
||||
complete -x -c arp -s s -l set --description "Manually create ARP address" -a "(__fish_print_hostnames)"
|
||||
complete -f -c arp -s f -l file --description "Take addr from filename, default /etc/ethers"
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#at
|
||||
complete -f -c at -s V -d (N_ "Display version and exit")
|
||||
complete -f -c at -s q -d (N_ "Use specified queue")
|
||||
complete -f -c at -s m -d (N_ "Send mail to user")
|
||||
complete -c at -s f -x -a "(__fish_complete_suffix (commandline -ct) '' 'At job')" -d (N_ "Read job from file")
|
||||
complete -f -c at -s l -d (N_ "Alias for atq")
|
||||
complete -f -c at -s d -d (N_ "Alias for atrm")
|
||||
complete -f -c at -s v -d (N_ "Show the time")
|
||||
complete -f -c at -s c -d (N_ "Print the jobs listed")
|
||||
complete -f -c at -s V --description "Display version and exit"
|
||||
complete -f -c at -s q --description "Use specified queue"
|
||||
complete -f -c at -s m --description "Send mail to user"
|
||||
complete -c at -s f -x -a "(__fish_complete_suffix (commandline -ct) '' 'At job')" --description "Read job from file"
|
||||
complete -f -c at -s l --description "Alias for atq"
|
||||
complete -f -c at -s d --description "Alias for atrm"
|
||||
complete -f -c at -s v --description "Show the time"
|
||||
complete -f -c at -s c --description "Print the jobs listed"
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user