mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-13 12:51:15 -03:00
Compare commits
145 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ec58ffa641 | ||
|
|
2c44ecb4a3 | ||
|
|
2eebb6e7ed | ||
|
|
1a3ab8a189 | ||
|
|
4722ddc373 | ||
|
|
25365dbc54 | ||
|
|
6a5f11879b | ||
|
|
b028e41f7f | ||
|
|
86593cd6a2 | ||
|
|
6cae5c8b0a | ||
|
|
29cd62ab6e | ||
|
|
4c7e06e752 | ||
|
|
433169dca4 | ||
|
|
d46dade284 | ||
|
|
79b466441b | ||
|
|
9f14d50974 | ||
|
|
990803009e | ||
|
|
6dfd629fc5 | ||
|
|
d97f8f3fde | ||
|
|
95ca3d1c69 | ||
|
|
c8b04f70cf | ||
|
|
bffff77d17 | ||
|
|
6bdb0cde8b | ||
|
|
42a260f1e6 | ||
|
|
148cb68700 | ||
|
|
18c185c256 | ||
|
|
b5b49e7a4d | ||
|
|
28ea5ce732 | ||
|
|
eccba7626d | ||
|
|
79d3207d51 | ||
|
|
d6bf879675 | ||
|
|
051f557e8f | ||
|
|
17171c3277 | ||
|
|
18a59291ed | ||
|
|
29e86254d0 | ||
|
|
b746a803a9 | ||
|
|
07e14ed7a8 | ||
|
|
df5cc6f858 | ||
|
|
409a407ca0 | ||
|
|
1c2cbb00bc | ||
|
|
bbf2a3836f | ||
|
|
1aa1ab540e | ||
|
|
27c9eb8758 | ||
|
|
e6b1035ddc | ||
|
|
9f6aba38d6 | ||
|
|
b52fe0feb6 | ||
|
|
db459f869a | ||
|
|
763a6b8351 | ||
|
|
4a06821d99 | ||
|
|
22f3dcfd35 | ||
|
|
dbb66e1895 | ||
|
|
5a7a264b96 | ||
|
|
3d601bd751 | ||
|
|
c9deea2237 | ||
|
|
32e54fd719 | ||
|
|
9ebdc16be6 | ||
|
|
92ecc01baa | ||
|
|
ff1c5e058f | ||
|
|
3d192a8e93 | ||
|
|
f5c6306bde | ||
|
|
524e0aa174 | ||
|
|
94abb30f94 | ||
|
|
af8e053896 | ||
|
|
633e2f498f | ||
|
|
4932538c74 | ||
|
|
786144ba86 | ||
|
|
e3dd94f272 | ||
|
|
b110a0ae21 | ||
|
|
48d9c38d1e | ||
|
|
51f8272ebd | ||
|
|
77f35c1b41 | ||
|
|
06668bfacb | ||
|
|
df59b8498f | ||
|
|
92fde30c0c | ||
|
|
d690a15b29 | ||
|
|
445f6539cf | ||
|
|
13a7269378 | ||
|
|
fd2644ce49 | ||
|
|
508de57459 | ||
|
|
de2405b35a | ||
|
|
a7f977836a | ||
|
|
f59e4a88c6 | ||
|
|
c755bd0358 | ||
|
|
536523ffd7 | ||
|
|
ca82fc2f03 | ||
|
|
d1411c42d6 | ||
|
|
9d770af5f4 | ||
|
|
d1ff6a323a | ||
|
|
112ea1759a | ||
|
|
76bafbef2a | ||
|
|
1947ec88f1 | ||
|
|
d0956f1e43 | ||
|
|
6996c7718e | ||
|
|
45d56d8e05 | ||
|
|
53295d38b7 | ||
|
|
bd9c843fd1 | ||
|
|
f812b9b26c | ||
|
|
52851a3ba4 | ||
|
|
b1bf115fa2 | ||
|
|
0f25ef365d | ||
|
|
55ea4b6fc0 | ||
|
|
5ef8cccf21 | ||
|
|
5613d96001 | ||
|
|
5d9ba8c1a2 | ||
|
|
0de232bf54 | ||
|
|
db5b887824 | ||
|
|
634bdb8b3b | ||
|
|
9c579a37bb | ||
|
|
1502acd83e | ||
|
|
ef3430f669 | ||
|
|
01af64cf1f | ||
|
|
349f52a1a5 | ||
|
|
850aa1963f | ||
|
|
185d0c3c1c | ||
|
|
3656443b1f | ||
|
|
6748b9699f | ||
|
|
dc91d7aec4 | ||
|
|
13a51ba4c2 | ||
|
|
749dad1309 | ||
|
|
7a07d7c188 | ||
|
|
53c95abfb2 | ||
|
|
7fd2ae4ffd | ||
|
|
717ac3f7fe | ||
|
|
50fa7234ea | ||
|
|
80b4055eab | ||
|
|
94b7c8d5e6 | ||
|
|
580ec26885 | ||
|
|
6ba5d80a20 | ||
|
|
d58b9de63b | ||
|
|
99a93b5add | ||
|
|
de50539c02 | ||
|
|
04cf08b93b | ||
|
|
2c5b52eb6c | ||
|
|
dd8150d98d | ||
|
|
99662d7711 | ||
|
|
5f3ad87a98 | ||
|
|
83d05f9170 | ||
|
|
0d56818664 | ||
|
|
5b0cd5a911 | ||
|
|
102b99a17b | ||
|
|
6222d00ffc | ||
|
|
73370f5f39 | ||
|
|
883ce6e440 | ||
|
|
f320f5f710 | ||
|
|
32b531667a |
11
INSTALL
11
INSTALL
@@ -2,11 +2,12 @@
|
||||
Known issues
|
||||
============
|
||||
|
||||
Fish currently requires a semi-modern GCC version to
|
||||
compile. Specifically, GCC 2.95.* won't compile fish, but GCC 3.2.3 is
|
||||
known to work. Fish has not been coded with an C99- or GNU-specific
|
||||
features in mind, so it is hoped that it should be possible to make
|
||||
fish work with other compilers. Patches are welcome.
|
||||
Fish is developed using GCC, with the goal of using only C89 language
|
||||
features. Fish does, however use the *wprintf family of functions,
|
||||
which are new to the C99 standrard. It is not unlikely that any given
|
||||
release contains a few GCC:isms, but ICC 9.0.030 has been found to
|
||||
produce working binaries. GCC 2.95.* won't compile fish, but GCC 3.2.3
|
||||
is known to work. Patches to fix any remaining GNU:isms are welcome.
|
||||
|
||||
Older versions of Doxygen has bugs in the man-page generation which
|
||||
cause the builtin help to render incorrectly. Doxygen 1.2.14 is known
|
||||
|
||||
243
Makefile.in
243
Makefile.in
@@ -36,22 +36,7 @@
|
||||
CC := @CC@
|
||||
INSTALL:=@INSTALL@
|
||||
|
||||
#
|
||||
# Compiler flags:
|
||||
#
|
||||
#
|
||||
# -fno-optimize-sibling-calls seems to work around a bug where sending
|
||||
# a SIGWINCH to fish on NetBSD causes fish to exit when compiled with
|
||||
# GCC 3.3.3. This is probably either a compiler bug or a libc bug, but
|
||||
# adding this flag seems to fix things for now. Long term, the real
|
||||
# problem should be tracked down and truly fixed, at which point we
|
||||
# can remove this silly flag. This bug has been verified to not exist
|
||||
# on Linux using GCC 3.3.3.
|
||||
#
|
||||
# -Wall is there to keep me on my toes
|
||||
#
|
||||
|
||||
CFLAGS:=@CFLAGS@ -Wall -fno-optimize-sibling-calls
|
||||
CFLAGS:=@CFLAGS@
|
||||
CPPFLAGS=@CPPFLAGS@
|
||||
LDFLAGS:= @LIBS@ @LDFLAGS@
|
||||
|
||||
@@ -87,7 +72,7 @@ COMMON_OBJS_WITH_HEADER := builtin_help.o
|
||||
|
||||
# main.c exists, but main.h does not, etc.
|
||||
COMMON_OBJS_WITH_CODE := builtin_set.o builtin_commandline.o \
|
||||
builtin_ulimit.c builtin_complete.o
|
||||
builtin_ulimit.o builtin_complete.o builtin_jobs.o
|
||||
|
||||
# All objects that the system needs to build fish
|
||||
FISH_OBJS := $(COMMON_OBJS) $(COMMON_OBJS_WITH_CODE) \
|
||||
@@ -179,14 +164,16 @@ ETC_DIR_FILES :=etc/fish.in etc/fish_inputrc \
|
||||
etc/fish_interactive.fish.in
|
||||
|
||||
# Files in ./share/
|
||||
SHARE_DIR_FILES :=share/fish
|
||||
SHARE_DIR_FILES :=share/fish.in
|
||||
|
||||
# Files in ./tests/
|
||||
TESTS_DIR_FILES := $(TEST_IN) $(TEST_IN:.in=.out) $(TEST_IN:.in=.err) \
|
||||
$(TEST_IN:.in=.status) tests/test.fish tests/gen_output.fish
|
||||
|
||||
# Files in ./share/completions/
|
||||
COMPLETIONS_DIR_FILES := $(wildcard share/completions/*.fish)
|
||||
|
||||
# Files in ./share/functions/
|
||||
FUNCTIONS_DIR_FILES := $(wildcard share/functions/*.fish)
|
||||
|
||||
# Programs to build
|
||||
@@ -210,8 +197,14 @@ all: $(PROGRAMS) user_doc
|
||||
@echo Use \'make install\' to install fish.
|
||||
.PHONY: all
|
||||
|
||||
configure: configure.ac
|
||||
./config.status --recheck
|
||||
|
||||
Makefile: Makefile.in configure
|
||||
./config.status
|
||||
|
||||
debug:
|
||||
make fish CFLAGS="-O0 -Wno-unused -Werror -g -Wall -fno-optimize-sibling-calls"
|
||||
make fish CFLAGS="@CFLAGS@ -O0 -Wno-unused -Werror -g"
|
||||
.PHONY: debug
|
||||
|
||||
# User documentation, describing the features of the fish shell.
|
||||
@@ -351,7 +344,6 @@ builtin_help.c: $(BUILTIN_DOC_HDR) doc_src/count.doxygen gen_hdr2 gen_hdr.sh bui
|
||||
./gen_hdr.sh $*.doxygen >>$@
|
||||
echo ");" >>$@
|
||||
echo "}" >>$@
|
||||
#man -- doc_src/builtin_doc/man/man1/`basename $@ .c`.1 | cat -s | ./gen_hdr2 >>$@
|
||||
|
||||
#
|
||||
# The build rules for installing/uninstalling fish
|
||||
@@ -420,7 +412,7 @@ install-force: all install-translations
|
||||
@echo \* use the command \'chsh -s $(DESTDIR)$(bindir)/fish\'.
|
||||
@echo
|
||||
@echo Have fun!
|
||||
.PHONY: force-install
|
||||
.PHONY: install-force
|
||||
|
||||
|
||||
# Uninstall this fish version
|
||||
@@ -462,6 +454,7 @@ uninstall-legacy: uninstall
|
||||
rmdir $(DESTDIR)$(sysconfdir)/fish.d/completions; true
|
||||
rmdir $(DESTDIR)$(sysconfdir)/fish.d; true
|
||||
@echo The previous fish installation has been removed.
|
||||
.PHONY: uninstall-legacy
|
||||
|
||||
install-translations: $(TRANSLATIONS)
|
||||
if test $(HAVE_GETTEXT) = 1; then \
|
||||
@@ -498,25 +491,26 @@ fish_tests: $(FISH_TESTS_OBJS)
|
||||
$(CC) $(FISH_TESTS_OBJS) $(LDFLAGS) -o $@
|
||||
|
||||
|
||||
mimedb: $(MIME_OBJS) doc_src/mimedb.c
|
||||
$(CC) ${MIME_OBJS} doc_src/mimedb.c $(LDFLAGS) -o $@
|
||||
mimedb: $(MIME_OBJS) doc_src/mimedb.o
|
||||
$(CC) ${MIME_OBJS} doc_src/mimedb.o $(LDFLAGS) -o $@
|
||||
|
||||
set_color: set_color.o doc_src/set_color.c
|
||||
$(CC) set_color.o doc_src/set_color.c $(LDFLAGS) -o $@
|
||||
set_color: set_color.o doc_src/set_color.o
|
||||
$(CC) set_color.o doc_src/set_color.o $(LDFLAGS) -o $@
|
||||
|
||||
# Test program for the tokenizer library
|
||||
tokenizer_test: tokenizer.c tokenizer.h util.o wutil.o common.o
|
||||
$(CC) ${CFLAGS} tokenizer.c util.o wutil.o common.o -D TOKENIZER_TEST $(LDFLAGS) -o $@
|
||||
|
||||
# Neat little program to show output from terminal
|
||||
key_reader: key_reader.o input_common.o common.o env_universal.o env_universal_common.o util.o wutil.o
|
||||
$(CC) key_reader.o input_common.o common.o env_universal.o env_universal_common.o util.o wutil.o $(LDFLAGS) -o $@
|
||||
key_reader: key_reader.o input_common.o $(CORE_OBJS) env_universal.o env_universal_common.o wutil.o
|
||||
$(CC) key_reader.o input_common.o $(CORE_OBJS) env_universal.o env_universal_common.o wutil.o $(LDFLAGS) -o $@
|
||||
|
||||
#
|
||||
# Update dependencies
|
||||
#
|
||||
depend:
|
||||
makedepend -fMakefile.in -Y *.c
|
||||
./config.status
|
||||
.PHONY: depend
|
||||
|
||||
# Copy all the source files into a new directory and use tar to create
|
||||
@@ -546,15 +540,27 @@ fish-@PACKAGE_VERSION@.tar: $(DOC_SRC_DIR_FILES) $(MAIN_DIR_FILES) $(ETC_DIR_FIL
|
||||
tar -c fish-@PACKAGE_VERSION@ >fish-@PACKAGE_VERSION@.tar
|
||||
rm -rf fish-@PACKAGE_VERSION@
|
||||
|
||||
tar: fish-@PACKAGE_VERSION@.tar
|
||||
.PHONY: tar
|
||||
|
||||
fish-@PACKAGE_VERSION@.tar.gz: fish-@PACKAGE_VERSION@.tar
|
||||
gzip -f --best -c fish-@PACKAGE_VERSION@.tar >fish-@PACKAGE_VERSION@.tar.gz
|
||||
|
||||
fish-@PACKAGE_VERSION@.tar.bz2: fish-@PACKAGE_VERSION@.tar
|
||||
bzip2 -f --best -k fish-@PACKAGE_VERSION@.tar
|
||||
|
||||
dist: fish-@PACKAGE_VERSION@.tar.bz2
|
||||
.PHONY: dist
|
||||
|
||||
# Create .rpm file for the current systems architecture and an
|
||||
# .src.rpm file.
|
||||
rpm: fish-@PACKAGE_VERSION@.tar.bz2
|
||||
@if ! which rpmbuild; then \
|
||||
echo Could not find the rpmbuild command, needed to build an rpm; \
|
||||
echo You may be able to install it using the following command:; \
|
||||
echo \'yum install rpm-build\'; \
|
||||
false; \
|
||||
fi
|
||||
cp fish.spec /usr/src/redhat/SPECS/
|
||||
cp fish-@PACKAGE_VERSION@.tar.bz2 /usr/src/redhat/SOURCES/
|
||||
rpmbuild -ba --clean /usr/src/redhat/SPECS/fish.spec
|
||||
@@ -573,7 +579,7 @@ distclean: clean
|
||||
.PHONY: distclean
|
||||
|
||||
clean:
|
||||
rm -f *.o doc.h doc_src/*.doxygen doc_src/*.c builtin_help.c
|
||||
rm -f *.o doc.h doc_src/*.doxygen doc_src/*.c builtin_help.c doc_src/*.o
|
||||
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 fishd fish_pager count fish_tests
|
||||
@@ -590,105 +596,112 @@ clean:
|
||||
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
||||
builtin.o: config.h util.h wutil.h builtin.h function.h complete.h proc.h
|
||||
builtin.o: io.h parser.h event.h reader.h env.h common.h wgetopt.h sanity.h
|
||||
builtin.o: tokenizer.h builtin_help.h wildcard.h input_common.h input.h
|
||||
builtin.o: intern.h signal.h translate.h halloc.h halloc_util.h parse_util.h
|
||||
builtin.o: expand.h
|
||||
builtin_commandline.o: signal.h config.h util.h wutil.h builtin.h common.h
|
||||
builtin_commandline.o: wgetopt.h reader.h proc.h io.h parser.h event.h
|
||||
builtin_commandline.o: tokenizer.h input_common.h input.h translate.h
|
||||
builtin.o: config.h fallback.h common.h util.h wutil.h builtin.h function.h
|
||||
builtin.o: complete.h proc.h io.h parser.h event.h reader.h env.h wgetopt.h
|
||||
builtin.o: sanity.h tokenizer.h builtin_help.h wildcard.h input_common.h
|
||||
builtin.o: input.h intern.h signal.h translate.h halloc.h halloc_util.h
|
||||
builtin.o: parse_util.h expand.h
|
||||
builtin_commandline.o: signal.h config.h fallback.h common.h util.h wutil.h
|
||||
builtin_commandline.o: builtin.h wgetopt.h reader.h proc.h io.h parser.h
|
||||
builtin_commandline.o: event.h tokenizer.h input_common.h input.h translate.h
|
||||
builtin_commandline.o: parse_util.h
|
||||
builtin_complete.o: signal.h config.h util.h wutil.h builtin.h common.h
|
||||
builtin_complete.o: complete.h wgetopt.h parser.h proc.h io.h event.h
|
||||
builtin_complete.o: reader.h translate.h
|
||||
builtin_complete.o: signal.h config.h fallback.h common.h util.h wutil.h
|
||||
builtin_complete.o: builtin.h complete.h wgetopt.h parser.h proc.h io.h
|
||||
builtin_complete.o: event.h reader.h translate.h
|
||||
builtin_help.o: config.h util.h common.h builtin_help.h
|
||||
builtin_set.o: signal.h config.h util.h wutil.h builtin.h env.h expand.h
|
||||
builtin_set.o: common.h wgetopt.h proc.h io.h parser.h event.h translate.h
|
||||
builtin_ulimit.o: config.h util.h builtin.h common.h wgetopt.h translate.h
|
||||
common.o: config.h util.h wutil.h common.h expand.h proc.h io.h wildcard.h
|
||||
common.o: parser.h event.h
|
||||
complete.o: signal.h config.h util.h tokenizer.h wildcard.h proc.h io.h
|
||||
complete.o: parser.h event.h function.h complete.h builtin.h env.h exec.h
|
||||
complete.o: expand.h common.h reader.h history.h intern.h translate.h
|
||||
complete.o: parse_util.h halloc_util.h wutil.h
|
||||
env.o: config.h signal.h util.h wutil.h proc.h io.h common.h env.h sanity.h
|
||||
env.o: expand.h history.h reader.h parser.h event.h env_universal.h
|
||||
builtin_set.o: signal.h config.h fallback.h common.h util.h wutil.h builtin.h
|
||||
builtin_set.o: env.h expand.h wgetopt.h proc.h io.h parser.h event.h
|
||||
builtin_set.o: translate.h
|
||||
builtin_ulimit.o: config.h fallback.h common.h util.h builtin.h wgetopt.h
|
||||
builtin_ulimit.o: translate.h
|
||||
common.o: config.h fallback.h common.h util.h wutil.h expand.h proc.h io.h
|
||||
common.o: wildcard.h parser.h event.h
|
||||
complete.o: signal.h config.h fallback.h common.h util.h tokenizer.h
|
||||
complete.o: wildcard.h proc.h io.h parser.h event.h function.h complete.h
|
||||
complete.o: builtin.h env.h exec.h expand.h reader.h history.h intern.h
|
||||
complete.o: translate.h parse_util.h halloc_util.h wutil.h
|
||||
env.o: config.h signal.h fallback.h common.h util.h wutil.h proc.h io.h env.h
|
||||
env.o: sanity.h expand.h history.h reader.h parser.h event.h env_universal.h
|
||||
env.o: env_universal_common.h input_common.h translate.h complete.h
|
||||
env_universal.o: config.h signal.h util.h common.h wutil.h
|
||||
env_universal.o: config.h signal.h fallback.h common.h util.h wutil.h
|
||||
env_universal.o: env_universal_common.h env_universal.h
|
||||
env_universal_common.o: config.h signal.h util.h common.h wutil.h
|
||||
env_universal_common.o: config.h signal.h fallback.h common.h util.h wutil.h
|
||||
env_universal_common.o: env_universal_common.h
|
||||
event.o: signal.h config.h util.h wutil.h function.h proc.h io.h parser.h
|
||||
event.o: event.h common.h translate.h halloc_util.h
|
||||
exec.o: signal.h config.h util.h common.h wutil.h proc.h io.h exec.h parser.h
|
||||
exec.o: event.h builtin.h function.h env.h wildcard.h sanity.h expand.h
|
||||
exec.o: env_universal.h env_universal_common.h translate.h halloc.h
|
||||
exec.o: halloc_util.h parse_util.h
|
||||
expand.o: signal.h config.h util.h common.h wutil.h env.h proc.h io.h
|
||||
expand.o: parser.h event.h expand.h wildcard.h exec.h tokenizer.h complete.h
|
||||
expand.o: translate.h parse_util.h halloc_util.h
|
||||
fishd.o: config.h signal.h util.h common.h wutil.h env_universal_common.h
|
||||
fish_pager.o: config.h signal.h util.h wutil.h common.h complete.h output.h
|
||||
fish_pager.o: input_common.h env_universal.h env_universal_common.h halloc.h
|
||||
fish_pager.o: halloc_util.h
|
||||
fish_tests.o: config.h signal.h util.h common.h proc.h io.h reader.h
|
||||
fish_tests.o: builtin.h function.h complete.h wutil.h env.h expand.h parser.h
|
||||
fish_tests.o: event.h tokenizer.h output.h exec.h halloc_util.h
|
||||
function.o: signal.h config.h wutil.h util.h function.h proc.h io.h parser.h
|
||||
function.o: event.h common.h intern.h reader.h parse_util.h env.h expand.h
|
||||
halloc.o: config.h util.h common.h halloc.h
|
||||
halloc_util.o: config.h util.h common.h halloc.h
|
||||
highlight.o: signal.h config.h util.h wutil.h highlight.h tokenizer.h proc.h
|
||||
highlight.o: io.h parser.h event.h parse_util.h builtin.h function.h env.h
|
||||
highlight.o: expand.h sanity.h common.h complete.h output.h
|
||||
history.o: config.h util.h wutil.h history.h common.h reader.h env.h sanity.h
|
||||
history.o: signal.h
|
||||
input.o: config.h signal.h util.h wutil.h reader.h proc.h io.h common.h
|
||||
input.o: sanity.h input_common.h input.h parser.h event.h env.h expand.h
|
||||
event.o: signal.h config.h fallback.h common.h util.h wutil.h function.h
|
||||
event.o: proc.h io.h parser.h event.h translate.h halloc_util.h
|
||||
exec.o: signal.h config.h fallback.h common.h util.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 translate.h
|
||||
exec.o: halloc.h halloc_util.h parse_util.h
|
||||
expand.o: signal.h config.h fallback.h common.h util.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 translate.h parse_util.h halloc_util.h
|
||||
fallback.o: config.h fallback.h common.h util.h
|
||||
fishd.o: config.h signal.h fallback.h common.h util.h wutil.h
|
||||
fishd.o: env_universal_common.h
|
||||
fish_pager.o: config.h signal.h fallback.h common.h util.h wutil.h complete.h
|
||||
fish_pager.o: output.h input_common.h env_universal.h env_universal_common.h
|
||||
fish_pager.o: halloc.h halloc_util.h
|
||||
fish_tests.o: config.h signal.h fallback.h common.h util.h proc.h io.h
|
||||
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: signal.h config.h wutil.h fallback.h common.h util.h function.h
|
||||
function.o: proc.h io.h translate.h parser.h event.h intern.h reader.h
|
||||
function.o: parse_util.h env.h expand.h
|
||||
halloc.o: config.h fallback.h common.h util.h halloc.h
|
||||
halloc_util.o: config.h fallback.h common.h util.h halloc.h
|
||||
highlight.o: signal.h config.h fallback.h common.h util.h wutil.h highlight.h
|
||||
highlight.o: tokenizer.h proc.h io.h parser.h event.h parse_util.h builtin.h
|
||||
highlight.o: function.h env.h expand.h sanity.h complete.h output.h
|
||||
history.o: config.h fallback.h common.h util.h wutil.h history.h reader.h
|
||||
history.o: env.h sanity.h signal.h
|
||||
input.o: config.h signal.h fallback.h common.h util.h wutil.h reader.h proc.h
|
||||
input.o: io.h sanity.h input_common.h input.h parser.h event.h env.h expand.h
|
||||
input.o: translate.h output.h
|
||||
input_common.o: config.h util.h common.h wutil.h input_common.h
|
||||
input_common.o: config.h fallback.h common.h util.h wutil.h input_common.h
|
||||
input_common.o: env_universal.h env_universal_common.h
|
||||
intern.o: config.h util.h wutil.h common.h intern.h
|
||||
io.o: config.h util.h wutil.h exec.h proc.h io.h common.h translate.h
|
||||
io.o: halloc.h
|
||||
key_reader.o: input_common.h
|
||||
kill.o: signal.h config.h util.h wutil.h kill.h proc.h io.h sanity.h common.h
|
||||
kill.o: env.h exec.h parser.h event.h
|
||||
main.o: config.h signal.h util.h common.h reader.h builtin.h function.h
|
||||
main.o: complete.h wutil.h env.h sanity.h proc.h io.h parser.h event.h
|
||||
main.o: expand.h intern.h exec.h output.h translate.h halloc_util.h
|
||||
mimedb.o: config.h xdgmime.h util.h
|
||||
output.o: config.h signal.h util.h wutil.h expand.h common.h output.h
|
||||
output.o: halloc_util.h highlight.h
|
||||
parser.o: signal.h config.h util.h common.h wutil.h proc.h io.h parser.h
|
||||
parser.o: event.h tokenizer.h exec.h wildcard.h function.h builtin.h
|
||||
intern.o: config.h fallback.h common.h util.h wutil.h intern.h
|
||||
io.o: config.h fallback.h common.h util.h wutil.h exec.h proc.h io.h
|
||||
io.o: translate.h halloc.h
|
||||
key_reader.o: fallback.h common.h util.h input_common.h
|
||||
kill.o: signal.h config.h fallback.h common.h util.h wutil.h kill.h proc.h
|
||||
kill.o: io.h sanity.h env.h exec.h parser.h event.h
|
||||
main.o: config.h signal.h fallback.h common.h util.h reader.h builtin.h
|
||||
main.o: function.h complete.h wutil.h env.h sanity.h proc.h io.h parser.h
|
||||
main.o: event.h expand.h intern.h exec.h output.h translate.h halloc_util.h
|
||||
main.o: history.h
|
||||
mimedb.o: config.h xdgmime.h fallback.h common.h util.h
|
||||
output.o: config.h signal.h fallback.h common.h util.h wutil.h expand.h
|
||||
output.o: output.h halloc_util.h highlight.h
|
||||
parser.o: signal.h config.h fallback.h common.h util.h wutil.h proc.h io.h
|
||||
parser.o: parser.h event.h tokenizer.h exec.h wildcard.h function.h builtin.h
|
||||
parser.o: builtin_help.h env.h expand.h reader.h sanity.h env_universal.h
|
||||
parser.o: env_universal_common.h translate.h intern.h parse_util.h halloc.h
|
||||
parser.o: halloc_util.h
|
||||
parse_util.o: config.h util.h wutil.h common.h tokenizer.h parse_util.h
|
||||
parse_util.o: expand.h intern.h exec.h proc.h io.h env.h halloc_util.h
|
||||
proc.o: config.h signal.h util.h wutil.h proc.h io.h common.h reader.h
|
||||
proc.o: sanity.h env.h parser.h event.h translate.h halloc.h halloc_util.h
|
||||
proc.o: output.h
|
||||
reader.o: config.h signal.h util.h wutil.h highlight.h reader.h proc.h io.h
|
||||
reader.o: parser.h event.h complete.h history.h common.h sanity.h env.h
|
||||
reader.o: exec.h expand.h tokenizer.h kill.h input_common.h input.h
|
||||
parse_util.o: config.h fallback.h common.h util.h wutil.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
|
||||
proc.o: config.h signal.h fallback.h common.h util.h wutil.h proc.h io.h
|
||||
proc.o: reader.h sanity.h env.h parser.h event.h translate.h halloc.h
|
||||
proc.o: halloc_util.h output.h
|
||||
reader.o: config.h signal.h fallback.h common.h util.h wutil.h highlight.h
|
||||
reader.o: reader.h proc.h io.h parser.h event.h complete.h history.h sanity.h
|
||||
reader.o: env.h exec.h expand.h tokenizer.h kill.h input_common.h input.h
|
||||
reader.o: function.h output.h translate.h parse_util.h
|
||||
refcount.o: config.h util.h wutil.h common.h refcount.h
|
||||
sanity.o: signal.h config.h util.h common.h sanity.h proc.h io.h history.h
|
||||
sanity.o: reader.h kill.h wutil.h translate.h
|
||||
refcount.o: config.h fallback.h common.h util.h wutil.h refcount.h
|
||||
sanity.o: signal.h config.h fallback.h common.h util.h sanity.h proc.h io.h
|
||||
sanity.o: history.h reader.h kill.h wutil.h translate.h
|
||||
set_color.o: config.h
|
||||
signal.o: config.h signal.h common.h util.h wutil.h event.h reader.h proc.h
|
||||
signal.o: io.h translate.h
|
||||
tokenizer.o: config.h util.h wutil.h tokenizer.h common.h wildcard.h
|
||||
tokenizer.o: translate.h
|
||||
translate.o: config.h common.h util.h halloc_util.h
|
||||
util.o: config.h util.h common.h wutil.h
|
||||
wgetopt.o: config.h wgetopt.h wutil.h translate.h
|
||||
wildcard.o: config.h util.h wutil.h complete.h common.h wildcard.h reader.h
|
||||
wildcard.o: expand.h translate.h
|
||||
wutil.o: config.h util.h common.h wutil.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 translate.h
|
||||
tokenizer.o: config.h fallback.h common.h util.h wutil.h tokenizer.h
|
||||
tokenizer.o: wildcard.h translate.h
|
||||
translate.o: config.h common.h util.h fallback.h halloc_util.h
|
||||
util.o: config.h fallback.h common.h util.h wutil.h
|
||||
wgetopt.o: config.h wgetopt.h wutil.h fallback.h common.h util.h translate.h
|
||||
wildcard.o: config.h fallback.h common.h util.h wutil.h complete.h wildcard.h
|
||||
wildcard.o: reader.h expand.h translate.h
|
||||
wutil.o: config.h fallback.h common.h util.h wutil.h
|
||||
xdgmimealias.o: xdgmimealias.h xdgmime.h xdgmimeint.h
|
||||
xdgmime.o: xdgmime.h xdgmimeint.h xdgmimeglob.h xdgmimemagic.h xdgmimealias.h
|
||||
xdgmime.o: xdgmimeparent.h
|
||||
|
||||
611
builtin.c
611
builtin.c
@@ -92,18 +92,6 @@ typedef struct builtin_data
|
||||
builtin_data_t;
|
||||
|
||||
|
||||
/**
|
||||
Print modes for the jobs builtin
|
||||
*/
|
||||
enum
|
||||
{
|
||||
JOBS_DEFAULT, /**< Print lots of general info */
|
||||
JOBS_PRINT_PID, /**< Print pid of each process in job */
|
||||
JOBS_PRINT_COMMAND, /**< Print command name of each process in job */
|
||||
JOBS_PRINT_GROUP, /**< Print group id of job */
|
||||
}
|
||||
;
|
||||
|
||||
/**
|
||||
Table of all builtins
|
||||
*/
|
||||
@@ -159,6 +147,15 @@ void builtin_wperror( const wchar_t *s)
|
||||
}
|
||||
}
|
||||
|
||||
static int count_char( const wchar_t *str, wchar_t c )
|
||||
{
|
||||
int res = 0;
|
||||
for( ; *str; str++ )
|
||||
{
|
||||
res += (*str==c);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
Here follows the definition of all builtin commands. The function
|
||||
@@ -170,10 +167,12 @@ void builtin_wperror( const wchar_t *s)
|
||||
are part of the parser. (They are not parsed as commands, instead
|
||||
they only slightly alter the parser state)
|
||||
|
||||
If \c b is the buffer representing standard error, and the help
|
||||
message is about to be printed to an interactive screen, it may be
|
||||
shortened to fit the screen.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
void builtin_print_help( wchar_t *cmd, string_buffer_t *b )
|
||||
{
|
||||
const char *h;
|
||||
@@ -189,11 +188,50 @@ void builtin_print_help( wchar_t *cmd, string_buffer_t *b )
|
||||
if( !h )
|
||||
return;
|
||||
|
||||
|
||||
|
||||
wchar_t *str = str2wcs(builtin_help_get( cmd ));
|
||||
wchar_t *str = str2wcs( h );
|
||||
if( str )
|
||||
{
|
||||
|
||||
if( is_interactive && !builtin_out_redirect && b==sb_err)
|
||||
{
|
||||
/* 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 )
|
||||
{
|
||||
wchar_t *pos;
|
||||
|
||||
/* Find first empty line */
|
||||
for( pos=str; *pos; pos++ )
|
||||
{
|
||||
if( *pos == L'\n' )
|
||||
{
|
||||
wchar_t *pos2;
|
||||
int is_empty = 1;
|
||||
|
||||
for( pos2 = pos+1; *pos2; pos2++ )
|
||||
{
|
||||
if( *pos2 == L'\n' )
|
||||
break;
|
||||
|
||||
if( *pos2 != L'\t' && *pos2 !=L' ' )
|
||||
{
|
||||
is_empty = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( is_empty )
|
||||
{
|
||||
*(pos+1)=L'\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sb_append( b, str );
|
||||
free( str );
|
||||
}
|
||||
@@ -215,6 +253,10 @@ static int builtin_bind( wchar_t **argv )
|
||||
L"set-mode", required_argument, 0, 'M'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
@@ -227,7 +269,7 @@ static int builtin_bind( wchar_t **argv )
|
||||
|
||||
int opt = wgetopt_long( argc,
|
||||
argv,
|
||||
L"M:",
|
||||
L"M:h",
|
||||
long_options,
|
||||
&opt_index );
|
||||
if( opt == -1 )
|
||||
@@ -250,6 +292,10 @@ static int builtin_bind( wchar_t **argv )
|
||||
input_set_mode( woptarg );
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
|
||||
case '?':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
@@ -337,7 +383,7 @@ static int builtin_block( wchar_t **argv )
|
||||
|
||||
return 1;
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
|
||||
case 'g':
|
||||
@@ -478,7 +524,7 @@ static int builtin_builtin( wchar_t **argv )
|
||||
|
||||
return 1;
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
|
||||
case 'n':
|
||||
@@ -497,27 +543,24 @@ static int builtin_builtin( wchar_t **argv )
|
||||
if( list )
|
||||
{
|
||||
array_list_t names;
|
||||
wchar_t **names_arr;
|
||||
int i;
|
||||
|
||||
al_init( &names );
|
||||
builtin_get_names( &names );
|
||||
names_arr = list_to_char_arr( &names );
|
||||
qsort( names_arr,
|
||||
al_get_count( &names ),
|
||||
sizeof(wchar_t *),
|
||||
(int (*)(const void *, const void *))&wcsfilecmp );
|
||||
sort_list( &names );
|
||||
|
||||
for( i=0; i<al_get_count( &names ); i++ )
|
||||
{
|
||||
if( wcscmp( names_arr[i], L"count" ) == 0 )
|
||||
wchar_t *el = (wchar_t *)al_get( &names, i );
|
||||
|
||||
if( wcscmp( el, L"count" ) == 0 )
|
||||
continue;
|
||||
|
||||
sb_append2( sb_out,
|
||||
names_arr[i],
|
||||
el,
|
||||
L"\n",
|
||||
(void *)0 );
|
||||
}
|
||||
free( names_arr );
|
||||
al_destroy( &names );
|
||||
}
|
||||
return 0;
|
||||
@@ -586,6 +629,7 @@ static int builtin_generic( wchar_t **argv )
|
||||
}
|
||||
|
||||
/**
|
||||
Output a definition of the specified function to the sb_out
|
||||
stringbuffer. Used by the functions builtin.
|
||||
*/
|
||||
static void functions_def( wchar_t *name )
|
||||
@@ -676,7 +720,6 @@ static int builtin_functions( wchar_t **argv )
|
||||
wchar_t *desc=0;
|
||||
|
||||
array_list_t names;
|
||||
wchar_t **names_arr;
|
||||
|
||||
int argc=builtin_count_args( argv );
|
||||
int list=0;
|
||||
@@ -704,6 +747,10 @@ static int builtin_functions( wchar_t **argv )
|
||||
L"all", no_argument, 0, 'a'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
@@ -716,7 +763,7 @@ static int builtin_functions( wchar_t **argv )
|
||||
|
||||
int opt = wgetopt_long( argc,
|
||||
argv,
|
||||
L"ed:na",
|
||||
L"ed:nah",
|
||||
long_options,
|
||||
&opt_index );
|
||||
if( opt == -1 )
|
||||
@@ -752,6 +799,10 @@ static int builtin_functions( wchar_t **argv )
|
||||
show_hidden=1;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
|
||||
case '?':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
@@ -819,11 +870,7 @@ static int builtin_functions( wchar_t **argv )
|
||||
|
||||
al_init( &names );
|
||||
function_get_names( &names, show_hidden );
|
||||
names_arr = list_to_char_arr( &names );
|
||||
qsort( names_arr,
|
||||
al_get_count( &names ),
|
||||
sizeof(wchar_t *),
|
||||
(int (*)(const void *, const void *))&wcsfilecmp );
|
||||
sort_list( &names );
|
||||
if( is_screen )
|
||||
{
|
||||
string_buffer_t buff;
|
||||
@@ -832,12 +879,12 @@ static int builtin_functions( wchar_t **argv )
|
||||
for( i=0; i<al_get_count( &names ); i++ )
|
||||
{
|
||||
sb_append2( &buff,
|
||||
names_arr[i],
|
||||
al_get(&names, i),
|
||||
L", ",
|
||||
(void *)0 );
|
||||
}
|
||||
|
||||
write_screen( (wchar_t *)buff.buff );
|
||||
write_screen( (wchar_t *)buff.buff, sb_out );
|
||||
sb_destroy( &buff );
|
||||
}
|
||||
else
|
||||
@@ -845,13 +892,12 @@ static int builtin_functions( wchar_t **argv )
|
||||
for( i=0; i<al_get_count( &names ); i++ )
|
||||
{
|
||||
sb_append2( sb_out,
|
||||
names_arr[i],
|
||||
al_get(&names, i),
|
||||
L"\n",
|
||||
(void *)0 );
|
||||
}
|
||||
}
|
||||
|
||||
free( names_arr );
|
||||
al_destroy( &names );
|
||||
return 0;
|
||||
}
|
||||
@@ -864,16 +910,13 @@ static int builtin_functions( wchar_t **argv )
|
||||
sb_append( sb_out, _( L"Current function definitions are:\n\n" ) );
|
||||
al_init( &names );
|
||||
function_get_names( &names, show_hidden );
|
||||
names_arr = list_to_char_arr( &names );
|
||||
qsort( names_arr,
|
||||
al_get_count( &names ),
|
||||
sizeof(wchar_t *),
|
||||
(int (*)(const void *, const void *))&wcsfilecmp );
|
||||
sort_list( &names );
|
||||
|
||||
for( i=0; i<al_get_count( &names ); i++ )
|
||||
{
|
||||
functions_def( names_arr[i] );
|
||||
functions_def( (wchar_t *)al_get( &names, i ) );
|
||||
}
|
||||
free( names_arr );
|
||||
|
||||
al_destroy( &names );
|
||||
break;
|
||||
}
|
||||
@@ -959,6 +1002,10 @@ static int builtin_function( wchar_t **argv )
|
||||
L"on-variable", required_argument, 0, 'v'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
@@ -971,7 +1018,7 @@ static int builtin_function( wchar_t **argv )
|
||||
|
||||
int opt = wgetopt_long( argc,
|
||||
argv,
|
||||
L"bd:s:j:p:v:",
|
||||
L"bd:s:j:p:v:h",
|
||||
long_options,
|
||||
&opt_index );
|
||||
if( opt == -1 )
|
||||
@@ -1028,7 +1075,7 @@ static int builtin_function( wchar_t **argv )
|
||||
{
|
||||
event_t *e;
|
||||
|
||||
if( !wcsvarname( woptarg ) )
|
||||
if( wcsvarname( woptarg ) )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: Invalid variable name '%ls'\n" ),
|
||||
@@ -1125,6 +1172,10 @@ static int builtin_function( wchar_t **argv )
|
||||
break;
|
||||
}
|
||||
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
|
||||
case '?':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
res = 1;
|
||||
@@ -1144,7 +1195,7 @@ static int builtin_function( wchar_t **argv )
|
||||
argc-woptind );
|
||||
res=1;
|
||||
}
|
||||
else if( !(is_binding?wcsbindingname( argv[woptind] ) : wcsvarname( argv[woptind] ) ))
|
||||
else if( !(is_binding?wcsbindingname( argv[woptind] ) : !wcsvarname( argv[woptind] ) ))
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: Illegal function name '%ls'\n" ),
|
||||
@@ -1169,24 +1220,20 @@ static int builtin_function( wchar_t **argv )
|
||||
{
|
||||
int i;
|
||||
array_list_t names;
|
||||
wchar_t **names_arr;
|
||||
int chars=0;
|
||||
|
||||
// builtin_print_help( argv[0], sb_err );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
const wchar_t *cfa = _( L"Current functions are: " );
|
||||
sb_append( sb_err, cfa );
|
||||
chars += wcslen( cfa );
|
||||
|
||||
al_init( &names );
|
||||
function_get_names( &names, 0 );
|
||||
names_arr = list_to_char_arr( &names );
|
||||
qsort( names_arr,
|
||||
al_get_count( &names ),
|
||||
sizeof(wchar_t *),
|
||||
(int (*)(const void *, const void *))&wcsfilecmp );
|
||||
sort_list( &names );
|
||||
|
||||
for( i=0; i<al_get_count( &names ); i++ )
|
||||
{
|
||||
wchar_t *nxt = names_arr[i];
|
||||
wchar_t *nxt = (wchar_t *)al_get( &names, i );
|
||||
int l = wcslen( nxt + 2 );
|
||||
if( chars+l > common_get_width() )
|
||||
{
|
||||
@@ -1197,7 +1244,6 @@ static int builtin_function( wchar_t **argv )
|
||||
sb_append2( sb_err,
|
||||
nxt, L" ", (void *)0 );
|
||||
}
|
||||
free( names_arr );
|
||||
al_destroy( &names );
|
||||
sb_append( sb_err, L"\n" );
|
||||
|
||||
@@ -1274,7 +1320,7 @@ static int builtin_random( wchar_t **argv )
|
||||
return 1;
|
||||
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
break;
|
||||
|
||||
case '?':
|
||||
@@ -1347,9 +1393,10 @@ static int builtin_read( wchar_t **argv )
|
||||
wchar_t *nxt;
|
||||
wchar_t *prompt = DEFAULT_READ_PROMPT;
|
||||
wchar_t *commandline = L"";
|
||||
|
||||
int exit_res=0;
|
||||
|
||||
woptind=0;
|
||||
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
const static struct woption
|
||||
@@ -1383,6 +1430,10 @@ static int builtin_read( wchar_t **argv )
|
||||
L"command", required_argument, 0, 'c'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
@@ -1393,7 +1444,7 @@ static int builtin_read( wchar_t **argv )
|
||||
|
||||
int opt = wgetopt_long( argc,
|
||||
argv,
|
||||
L"xglUup:c:",
|
||||
L"xglUup:c:h",
|
||||
long_options,
|
||||
&opt_index );
|
||||
if( opt == -1 )
|
||||
@@ -1434,10 +1485,13 @@ static int builtin_read( wchar_t **argv )
|
||||
commandline = woptarg;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
|
||||
case L'?':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1466,20 +1520,6 @@ static int builtin_read( wchar_t **argv )
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( woptind == argc )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
BUILTIN_ERR_MISSING,
|
||||
argv[0] );
|
||||
|
||||
sb_append2( sb_err,
|
||||
parser_current_line(),
|
||||
L"\n",
|
||||
(void *)0 );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Verify all variable names
|
||||
*/
|
||||
@@ -1510,10 +1550,6 @@ static int builtin_read( wchar_t **argv )
|
||||
*/
|
||||
i=woptind;
|
||||
|
||||
ifs = env_get( L"IFS" );
|
||||
if( ifs == 0 )
|
||||
ifs = L"";
|
||||
|
||||
/*
|
||||
Check if we should read interactively using \c reader_readline()
|
||||
*/
|
||||
@@ -1529,10 +1565,12 @@ static int builtin_read( wchar_t **argv )
|
||||
else
|
||||
{
|
||||
string_buffer_t sb;
|
||||
int eof=0;
|
||||
|
||||
sb_init( &sb );
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
int eof=0;
|
||||
int finished=0;
|
||||
|
||||
wchar_t res=0;
|
||||
@@ -1573,30 +1611,46 @@ static int builtin_read( wchar_t **argv )
|
||||
|
||||
if( eof )
|
||||
break;
|
||||
|
||||
if( res == L'\n' )
|
||||
break;
|
||||
|
||||
sb_append_char( &sb, res );
|
||||
}
|
||||
|
||||
if( sb.used < 2 && eof )
|
||||
{
|
||||
exit_res = 1;
|
||||
}
|
||||
|
||||
buff = wcsdup( (wchar_t *)sb.buff );
|
||||
sb_destroy( &sb );
|
||||
}
|
||||
|
||||
wchar_t *state;
|
||||
|
||||
nxt = wcstok( buff, (i<argc-1)?ifs:L"", &state );
|
||||
|
||||
while( i<argc )
|
||||
if( i != argc )
|
||||
{
|
||||
env_set( argv[i], nxt != 0 ? nxt: L"", place );
|
||||
|
||||
wchar_t *state;
|
||||
|
||||
i++;
|
||||
if( nxt != 0 )
|
||||
nxt = wcstok( 0, (i<argc-1)?ifs:L"", &state);
|
||||
ifs = env_get( L"IFS" );
|
||||
if( ifs == 0 )
|
||||
ifs = L"";
|
||||
|
||||
nxt = wcstok( buff, (i<argc-1)?ifs:L"", &state );
|
||||
|
||||
while( i<argc )
|
||||
{
|
||||
env_set( argv[i], nxt != 0 ? nxt: L"", place );
|
||||
|
||||
i++;
|
||||
if( nxt != 0 )
|
||||
nxt = wcstok( 0, (i<argc-1)?ifs:L"", &state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
free( buff );
|
||||
return 0;
|
||||
|
||||
return exit_res;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1711,7 +1765,7 @@ static int builtin_status( wchar_t **argv )
|
||||
return 1;
|
||||
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
|
||||
case 'j':
|
||||
@@ -1865,14 +1919,14 @@ static int builtin_exit( wchar_t **argv )
|
||||
|
||||
default:
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: Too many arguments\n" ),
|
||||
BUILTIN_ERR_TOO_MANY_ARGUMENTS,
|
||||
argv[0] );
|
||||
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
|
||||
}
|
||||
reader_exit( 1 );
|
||||
reader_exit( 1, 0 );
|
||||
return ec;
|
||||
}
|
||||
|
||||
@@ -2017,10 +2071,10 @@ static int builtin_source( wchar_t ** argv )
|
||||
parser_push_block( SOURCE );
|
||||
reader_push_current_filename( fn_intern );
|
||||
|
||||
|
||||
current_block->param1.source_dest = fn_intern;
|
||||
|
||||
parse_util_set_argv( argv+2);
|
||||
|
||||
res = reader_read( fd );
|
||||
|
||||
parser_pop_block();
|
||||
@@ -2029,8 +2083,7 @@ static int builtin_source( wchar_t ** argv )
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: Error while reading file '%ls'\n" ),
|
||||
argv[0],
|
||||
argv[1]
|
||||
);
|
||||
argv[1] );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2076,7 +2129,7 @@ static void make_first( job_t *j )
|
||||
*/
|
||||
static int builtin_fg( wchar_t **argv )
|
||||
{
|
||||
job_t *j;
|
||||
job_t *j=0;
|
||||
|
||||
if( argv[1] == 0 )
|
||||
{
|
||||
@@ -2126,27 +2179,40 @@ static int builtin_fg( wchar_t **argv )
|
||||
}
|
||||
else
|
||||
{
|
||||
int pid = abs(wcstol( argv[1], 0, 10 ));
|
||||
j = job_get_from_pid( pid );
|
||||
if( !j )
|
||||
wchar_t *end;
|
||||
int pid = abs(wcstol( argv[1], &end, 10 ));
|
||||
|
||||
if( *end )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: No suitable job: %d\n" ),
|
||||
argv[0],
|
||||
pid );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: Argument must be a number: %ls\n" ),
|
||||
argv[0],
|
||||
argv[1] );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
}
|
||||
if( !j->job_control )
|
||||
else
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: Can't put job %d, '%ls' to foreground because it is not under job control\n" ),
|
||||
argv[0],
|
||||
pid,
|
||||
j->command );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
j=0;
|
||||
j = job_get_from_pid( pid );
|
||||
if( !j || !j->constructed || job_is_completed( j ))
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: No suitable job: %d\n" ),
|
||||
argv[0],
|
||||
pid );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
j=0;
|
||||
}
|
||||
else if( !j->job_control )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: Can't put job %d, '%ls' to foreground because it is not under job control\n" ),
|
||||
argv[0],
|
||||
pid,
|
||||
j->command );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
j=0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( j )
|
||||
@@ -2263,309 +2329,6 @@ static int builtin_bg( wchar_t **argv )
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE__PROC_SELF_STAT
|
||||
/**
|
||||
Calculates the cpu usage (in percent) of the specified job.
|
||||
*/
|
||||
static int cpu_use( job_t *j )
|
||||
{
|
||||
double u=0;
|
||||
process_t *p;
|
||||
|
||||
for( p=j->first_process; p; p=p->next )
|
||||
{
|
||||
struct timeval t;
|
||||
int jiffies;
|
||||
gettimeofday( &t, 0 );
|
||||
jiffies = proc_get_jiffies( p );
|
||||
|
||||
double t1 = 1000000.0*p->last_time.tv_sec+p->last_time.tv_usec;
|
||||
double t2 = 1000000.0*t.tv_sec+t.tv_usec;
|
||||
|
||||
/* fwprintf( stderr, L"t1 %f t2 %f p1 %d p2 %d\n",
|
||||
t1, t2, jiffies, p->last_jiffies );
|
||||
*/
|
||||
|
||||
u += ((double)(jiffies-p->last_jiffies))/(t2-t1);
|
||||
}
|
||||
return u*1000000;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
Print information about the specified job
|
||||
*/
|
||||
static void builtin_jobs_print( job_t *j, int mode, int header )
|
||||
{
|
||||
process_t *p;
|
||||
switch( mode )
|
||||
{
|
||||
case JOBS_DEFAULT:
|
||||
{
|
||||
|
||||
if( header )
|
||||
{
|
||||
/*
|
||||
Print table header before first job
|
||||
*/
|
||||
sb_append( sb_out, _( L"Job\tGroup\t" ));
|
||||
#ifdef HAVE__PROC_SELF_STAT
|
||||
sb_append( sb_out, _( L"CPU\t" ) );
|
||||
#endif
|
||||
sb_append( sb_out, _( L"State\tCommand\n" ) );
|
||||
}
|
||||
|
||||
sb_printf( sb_out, L"%d\t%d\t", j->job_id, j->pgid );
|
||||
|
||||
#ifdef HAVE__PROC_SELF_STAT
|
||||
sb_printf( sb_out, L"%d%%\t", cpu_use(j) );
|
||||
#endif
|
||||
sb_append2( sb_out,
|
||||
job_is_stopped(j)?_(L"stopped"):_(L"running"),
|
||||
L"\t",
|
||||
j->command,
|
||||
L"\n",
|
||||
(void *)0 );
|
||||
break;
|
||||
}
|
||||
|
||||
case JOBS_PRINT_GROUP:
|
||||
{
|
||||
if( header )
|
||||
{
|
||||
/*
|
||||
Print table header before first job
|
||||
*/
|
||||
sb_append( sb_out, _( L"Group\n" ));
|
||||
}
|
||||
sb_printf( sb_out, L"%d\n", j->pgid );
|
||||
break;
|
||||
}
|
||||
|
||||
case JOBS_PRINT_PID:
|
||||
{
|
||||
if( header )
|
||||
{
|
||||
/*
|
||||
Print table header before first job
|
||||
*/
|
||||
sb_append( sb_out, _( L"Procces\n" ));
|
||||
}
|
||||
|
||||
for( p=j->first_process; p; p=p->next )
|
||||
{
|
||||
sb_printf( sb_out, L"%d\n", p->pid );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case JOBS_PRINT_COMMAND:
|
||||
{
|
||||
if( header )
|
||||
{
|
||||
/*
|
||||
Print table header before first job
|
||||
*/
|
||||
sb_append( sb_out, _( L"Command\n" ));
|
||||
}
|
||||
|
||||
for( p=j->first_process; p; p=p->next )
|
||||
{
|
||||
sb_printf( sb_out, L"%ls\n", p->argv[0] );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Builtin for printing running jobs
|
||||
*/
|
||||
static int builtin_jobs( wchar_t **argv )
|
||||
{
|
||||
int argc=0;
|
||||
int found=0;
|
||||
int mode=JOBS_DEFAULT;
|
||||
int print_last = 0;
|
||||
job_t *j;
|
||||
|
||||
argc = builtin_count_args( argv );
|
||||
woptind=0;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
const static struct woption
|
||||
long_options[] =
|
||||
{
|
||||
{
|
||||
L"pid", no_argument, 0, 'p'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"command", no_argument, 0, 'c'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"group", no_argument, 0, 'g'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"last", no_argument, 0, 'l'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
int opt_index = 0;
|
||||
|
||||
int opt = wgetopt_long( argc,
|
||||
argv,
|
||||
L"pclg",
|
||||
long_options,
|
||||
&opt_index );
|
||||
if( opt == -1 )
|
||||
break;
|
||||
|
||||
switch( opt )
|
||||
{
|
||||
case 0:
|
||||
if(long_options[opt_index].flag != 0)
|
||||
break;
|
||||
sb_printf( sb_err,
|
||||
BUILTIN_ERR_UNKNOWN,
|
||||
argv[0],
|
||||
long_options[opt_index].name );
|
||||
|
||||
sb_append( sb_err,
|
||||
parser_current_line() );
|
||||
// builtin_print_help( argv[0], sb_err );
|
||||
|
||||
|
||||
return 1;
|
||||
|
||||
|
||||
case 'p':
|
||||
mode=JOBS_PRINT_PID;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
mode=JOBS_PRINT_COMMAND;
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
mode=JOBS_PRINT_GROUP;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
{
|
||||
print_last = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case '?':
|
||||
// builtin_print_help( argv[0], sb_err );
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Do not babble if not interactive
|
||||
*/
|
||||
if( builtin_out_redirect )
|
||||
{
|
||||
found=1;
|
||||
}
|
||||
|
||||
if( print_last )
|
||||
{
|
||||
/*
|
||||
Ignore unconstructed jobs, i.e. ourself.
|
||||
*/
|
||||
for( j=first_job; j; j=j->next )
|
||||
{
|
||||
if( j->constructed )
|
||||
{
|
||||
builtin_jobs_print( j, mode, !found );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if( woptind < argc )
|
||||
{
|
||||
int i;
|
||||
|
||||
found = 1;
|
||||
|
||||
for( i=woptind; i<argc; i++ )
|
||||
{
|
||||
long pid;
|
||||
wchar_t *end;
|
||||
errno=0;
|
||||
pid=wcstol( argv[i], &end, 10 );
|
||||
if( errno || *end )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: '%ls' is not a job\n" ),
|
||||
argv[0],
|
||||
argv[i] );
|
||||
return 1;
|
||||
}
|
||||
|
||||
j = job_get_from_pid( pid );
|
||||
|
||||
if( j )
|
||||
{
|
||||
builtin_jobs_print( j, mode, !found );
|
||||
}
|
||||
else
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: No suitable job: %d\n" ),
|
||||
argv[0],
|
||||
pid );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( j= first_job; j; j=j->next )
|
||||
{
|
||||
/*
|
||||
Ignore unconstructed jobs, i.e. ourself.
|
||||
*/
|
||||
if( j->constructed /*&& j->skip_notification*/ )
|
||||
{
|
||||
builtin_jobs_print( j, mode, !found );
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !found )
|
||||
{
|
||||
sb_printf( sb_out,
|
||||
_( L"%ls: There are no jobs\n" ),
|
||||
argv[0] );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Builtin for looping over a list
|
||||
*/
|
||||
@@ -2583,7 +2346,7 @@ static int builtin_for( wchar_t **argv )
|
||||
argv[0] );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
}
|
||||
else if ( !wcsvarname(argv[1]) )
|
||||
else if ( wcsvarname(argv[1]) )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: '%ls' is not a valid variable name\n" ),
|
||||
@@ -2594,7 +2357,7 @@ static int builtin_for( wchar_t **argv )
|
||||
else if (wcscmp( argv[2], L"in") != 0 )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: Second argument must be 'in'\n" ),
|
||||
BUILTIN_FOR_ERR_IN,
|
||||
argv[0] );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
}
|
||||
@@ -3221,7 +2984,7 @@ static int internal_help( wchar_t *cmd )
|
||||
int builtin_run( wchar_t **argv )
|
||||
{
|
||||
int (*cmd)(wchar_t **argv)=0;
|
||||
cmd = hash_get( &builtin, argv[0] );
|
||||
cmd = (int (*)(wchar_t **))hash_get( &builtin, argv[0] );
|
||||
|
||||
if( argv[1] != 0 && !internal_help(argv[0]) )
|
||||
{
|
||||
|
||||
26
builtin.h
26
builtin.h
@@ -57,6 +57,13 @@ enum
|
||||
*/
|
||||
#define BUILTIN_ERR_VARNAME_ZERO _( L"%ls: Variable name can not be the empty string\n" )
|
||||
|
||||
/**
|
||||
Error message when second argument to for isn't 'in'
|
||||
*/
|
||||
#define BUILTIN_FOR_ERR_IN _( L"%ls: Second argument must be 'in'\n" )
|
||||
|
||||
#define BUILTIN_ERR_TOO_MANY_ARGUMENTS _( L"%ls: Too many arguments\n" )
|
||||
|
||||
/**
|
||||
Stringbuffer used to represent standard output
|
||||
*/
|
||||
@@ -132,33 +139,42 @@ const wchar_t *builtin_get_desc( const wchar_t *b );
|
||||
int builtin_count_args( wchar_t **argv );
|
||||
|
||||
/**
|
||||
Print help for the specified builtin. If \c b is sb_err, also print the line information
|
||||
Print help for the specified builtin. If \c b is sb_err, also print
|
||||
the line information
|
||||
*/
|
||||
void builtin_print_help( wchar_t *cmd, string_buffer_t *b );
|
||||
|
||||
|
||||
/**
|
||||
The set builtin, used for setting variables. Defined in builtin_set.c.
|
||||
The set builtin, used for setting variables. Defined in
|
||||
builtin_set.c.
|
||||
*/
|
||||
int builtin_set(wchar_t **argv);
|
||||
|
||||
/**
|
||||
The commandline builtin, used for setting and getting the contents of the commandline. Defined in builtin_commandline.c.
|
||||
The commandline builtin, used for setting and getting the contents
|
||||
of the commandline. Defined in builtin_commandline.c.
|
||||
*/
|
||||
int builtin_commandline(wchar_t **argv);
|
||||
|
||||
/**
|
||||
The ulimit builtin, used for setting resource limits. Defined in builtin_ulimit.c.
|
||||
The ulimit builtin, used for setting resource limits. Defined in
|
||||
builtin_ulimit.c.
|
||||
*/
|
||||
int builtin_ulimit(wchar_t **argv);
|
||||
|
||||
/**
|
||||
The complete builtin. Used for specifying programmable
|
||||
tab-completions. Calls the functions in complete.c for any heavy
|
||||
lifting.
|
||||
lifting. Defined in builtin_complete.c
|
||||
*/
|
||||
int builtin_complete(wchar_t **argv);
|
||||
|
||||
/**
|
||||
The jobs builtin. Used fopr printing running jobs. Defined in builtin_jobs.c.
|
||||
*/
|
||||
int builtin_jobs(wchar_t **argv);
|
||||
|
||||
const wchar_t *builtin_complete_get_temporary_buffer();
|
||||
|
||||
/**
|
||||
|
||||
@@ -265,6 +265,10 @@ int builtin_commandline( wchar_t **argv )
|
||||
L"tokenize", no_argument, 0, 'o'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
@@ -275,7 +279,7 @@ int builtin_commandline( wchar_t **argv )
|
||||
|
||||
int opt = wgetopt_long( argc,
|
||||
argv,
|
||||
L"aijpctwfor",
|
||||
L"aijpctwforh",
|
||||
long_options,
|
||||
&opt_index );
|
||||
if( opt == -1 )
|
||||
@@ -330,6 +334,10 @@ int builtin_commandline( wchar_t **argv )
|
||||
tokenize=1;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
|
||||
case L'?':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
|
||||
@@ -341,6 +341,10 @@ int builtin_complete( wchar_t **argv )
|
||||
L"do-complete", required_argument, 0, 'C'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
@@ -351,7 +355,7 @@ int builtin_complete( wchar_t **argv )
|
||||
|
||||
int opt = wgetopt_long( argc,
|
||||
argv,
|
||||
L"a:c:p:s:l:o:d:frxeun:C:",
|
||||
L"a:c:p:s:l:o:d:frxeun:C:h",
|
||||
long_options,
|
||||
&opt_index );
|
||||
if( opt == -1 )
|
||||
@@ -369,7 +373,7 @@ int builtin_complete( wchar_t **argv )
|
||||
sb_append( sb_err,
|
||||
parser_current_line() );
|
||||
|
||||
// builtin_print_help( argv[0], sb_err );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
|
||||
res = 1;
|
||||
@@ -431,10 +435,14 @@ int builtin_complete( wchar_t **argv )
|
||||
do_complete = woptarg?woptarg:reader_get_buffer();
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
|
||||
case '?':
|
||||
sb_append( sb_err,
|
||||
parser_current_line() );
|
||||
// builtin_print_help( argv[0], sb_err );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
res = 1;
|
||||
break;
|
||||
@@ -443,6 +451,42 @@ int builtin_complete( wchar_t **argv )
|
||||
|
||||
}
|
||||
|
||||
if( !res )
|
||||
{
|
||||
if( condition && wcslen( condition ) )
|
||||
{
|
||||
if( parser_test( condition, 0 ) )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
L"%ls: Condition '%ls' contained a syntax error\n",
|
||||
argv[0],
|
||||
condition );
|
||||
|
||||
parser_test( condition, 1 );
|
||||
|
||||
res = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !res )
|
||||
{
|
||||
if( comp && wcslen( comp ) )
|
||||
{
|
||||
if( parser_test_args( comp, 0 ) )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
L"%ls: Completion '%ls' contained a syntax error\n",
|
||||
argv[0],
|
||||
comp );
|
||||
|
||||
parser_test_args( comp, 1 );
|
||||
|
||||
res = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !res )
|
||||
{
|
||||
if( do_complete )
|
||||
@@ -485,7 +529,7 @@ int builtin_complete( wchar_t **argv )
|
||||
argv[0] );
|
||||
sb_append( sb_err,
|
||||
parser_current_line() );
|
||||
// builtin_print_help( argv[0], sb_err );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
res = 1;
|
||||
}
|
||||
|
||||
349
builtin_jobs.c
Normal file
349
builtin_jobs.c
Normal file
@@ -0,0 +1,349 @@
|
||||
/** \file builtin_jobs.c
|
||||
Functions for executing the jobs builtin.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <wctype.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "fallback.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "wutil.h"
|
||||
#include "builtin.h"
|
||||
#include "proc.h"
|
||||
#include "parser.h"
|
||||
#include "common.h"
|
||||
#include "wgetopt.h"
|
||||
#include "translate.h"
|
||||
|
||||
/**
|
||||
Print modes for the jobs builtin
|
||||
*/
|
||||
enum
|
||||
{
|
||||
JOBS_DEFAULT, /**< Print lots of general info */
|
||||
JOBS_PRINT_PID, /**< Print pid of each process in job */
|
||||
JOBS_PRINT_COMMAND, /**< Print command name of each process in job */
|
||||
JOBS_PRINT_GROUP, /**< Print group id of job */
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
|
||||
#ifdef HAVE__PROC_SELF_STAT
|
||||
/**
|
||||
Calculates the cpu usage (in percent) of the specified job.
|
||||
*/
|
||||
static int cpu_use( job_t *j )
|
||||
{
|
||||
double u=0;
|
||||
process_t *p;
|
||||
|
||||
for( p=j->first_process; p; p=p->next )
|
||||
{
|
||||
struct timeval t;
|
||||
int jiffies;
|
||||
gettimeofday( &t, 0 );
|
||||
jiffies = proc_get_jiffies( p );
|
||||
|
||||
double t1 = 1000000.0*p->last_time.tv_sec+p->last_time.tv_usec;
|
||||
double t2 = 1000000.0*t.tv_sec+t.tv_usec;
|
||||
|
||||
/* fwprintf( stderr, L"t1 %f t2 %f p1 %d p2 %d\n",
|
||||
t1, t2, jiffies, p->last_jiffies );
|
||||
*/
|
||||
|
||||
u += ((double)(jiffies-p->last_jiffies))/(t2-t1);
|
||||
}
|
||||
return u*1000000;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
Print information about the specified job
|
||||
*/
|
||||
static void builtin_jobs_print( job_t *j, int mode, int header )
|
||||
{
|
||||
process_t *p;
|
||||
switch( mode )
|
||||
{
|
||||
case JOBS_DEFAULT:
|
||||
{
|
||||
|
||||
if( header )
|
||||
{
|
||||
/*
|
||||
Print table header before first job
|
||||
*/
|
||||
sb_append( sb_out, _( L"Job\tGroup\t" ));
|
||||
#ifdef HAVE__PROC_SELF_STAT
|
||||
sb_append( sb_out, _( L"CPU\t" ) );
|
||||
#endif
|
||||
sb_append( sb_out, _( L"State\tCommand\n" ) );
|
||||
}
|
||||
|
||||
sb_printf( sb_out, L"%d\t%d\t", j->job_id, j->pgid );
|
||||
|
||||
#ifdef HAVE__PROC_SELF_STAT
|
||||
sb_printf( sb_out, L"%d%%\t", cpu_use(j) );
|
||||
#endif
|
||||
sb_append2( sb_out,
|
||||
job_is_stopped(j)?_(L"stopped"):_(L"running"),
|
||||
L"\t",
|
||||
j->command,
|
||||
L"\n",
|
||||
(void *)0 );
|
||||
break;
|
||||
}
|
||||
|
||||
case JOBS_PRINT_GROUP:
|
||||
{
|
||||
if( header )
|
||||
{
|
||||
/*
|
||||
Print table header before first job
|
||||
*/
|
||||
sb_append( sb_out, _( L"Group\n" ));
|
||||
}
|
||||
sb_printf( sb_out, L"%d\n", j->pgid );
|
||||
break;
|
||||
}
|
||||
|
||||
case JOBS_PRINT_PID:
|
||||
{
|
||||
if( header )
|
||||
{
|
||||
/*
|
||||
Print table header before first job
|
||||
*/
|
||||
sb_append( sb_out, _( L"Procces\n" ));
|
||||
}
|
||||
|
||||
for( p=j->first_process; p; p=p->next )
|
||||
{
|
||||
sb_printf( sb_out, L"%d\n", p->pid );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case JOBS_PRINT_COMMAND:
|
||||
{
|
||||
if( header )
|
||||
{
|
||||
/*
|
||||
Print table header before first job
|
||||
*/
|
||||
sb_append( sb_out, _( L"Command\n" ));
|
||||
}
|
||||
|
||||
for( p=j->first_process; p; p=p->next )
|
||||
{
|
||||
sb_printf( sb_out, L"%ls\n", p->argv[0] );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
int builtin_jobs( wchar_t **argv )
|
||||
{
|
||||
int argc=0;
|
||||
int found=0;
|
||||
int mode=JOBS_DEFAULT;
|
||||
int print_last = 0;
|
||||
job_t *j;
|
||||
|
||||
argc = builtin_count_args( argv );
|
||||
woptind=0;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
const static struct woption
|
||||
long_options[] =
|
||||
{
|
||||
{
|
||||
L"pid", no_argument, 0, 'p'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"command", no_argument, 0, 'c'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"group", no_argument, 0, 'g'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"last", no_argument, 0, 'l'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
int opt_index = 0;
|
||||
|
||||
int opt = wgetopt_long( argc,
|
||||
argv,
|
||||
L"pclgh",
|
||||
long_options,
|
||||
&opt_index );
|
||||
if( opt == -1 )
|
||||
break;
|
||||
|
||||
switch( opt )
|
||||
{
|
||||
case 0:
|
||||
if(long_options[opt_index].flag != 0)
|
||||
break;
|
||||
sb_printf( sb_err,
|
||||
BUILTIN_ERR_UNKNOWN,
|
||||
argv[0],
|
||||
long_options[opt_index].name );
|
||||
|
||||
sb_append( sb_err,
|
||||
parser_current_line() );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
|
||||
return 1;
|
||||
|
||||
|
||||
case 'p':
|
||||
mode=JOBS_PRINT_PID;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
mode=JOBS_PRINT_COMMAND;
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
mode=JOBS_PRINT_GROUP;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
{
|
||||
print_last = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
|
||||
case '?':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Do not babble if not interactive
|
||||
*/
|
||||
if( builtin_out_redirect )
|
||||
{
|
||||
found=1;
|
||||
}
|
||||
|
||||
if( print_last )
|
||||
{
|
||||
/*
|
||||
Ignore unconstructed jobs, i.e. ourself.
|
||||
*/
|
||||
for( j=first_job; j; j=j->next )
|
||||
{
|
||||
if( j->constructed && !job_is_completed(j) )
|
||||
{
|
||||
builtin_jobs_print( j, mode, !found );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if( woptind < argc )
|
||||
{
|
||||
int i;
|
||||
|
||||
found = 1;
|
||||
|
||||
for( i=woptind; i<argc; i++ )
|
||||
{
|
||||
long pid;
|
||||
wchar_t *end;
|
||||
errno=0;
|
||||
pid=wcstol( argv[i], &end, 10 );
|
||||
if( errno || *end )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: '%ls' is not a job\n" ),
|
||||
argv[0],
|
||||
argv[i] );
|
||||
return 1;
|
||||
}
|
||||
|
||||
j = job_get_from_pid( pid );
|
||||
|
||||
if( j && !job_is_completed( j ) )
|
||||
{
|
||||
builtin_jobs_print( j, mode, !found );
|
||||
}
|
||||
else
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: No suitable job: %d\n" ),
|
||||
argv[0],
|
||||
pid );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( j= first_job; j; j=j->next )
|
||||
{
|
||||
/*
|
||||
Ignore unconstructed jobs, i.e. ourself.
|
||||
*/
|
||||
if( j->constructed && !job_is_completed(j) )
|
||||
{
|
||||
builtin_jobs_print( j, mode, !found );
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !found )
|
||||
{
|
||||
sb_printf( sb_out,
|
||||
_( L"%ls: There are no jobs\n" ),
|
||||
argv[0] );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
676
builtin_set.c
676
builtin_set.c
@@ -26,46 +26,164 @@ Functions used for implementing the set builtin.
|
||||
#include "parser.h"
|
||||
#include "translate.h"
|
||||
|
||||
/**
|
||||
Extract the name from a destination argument of the form name[index1 index2...]
|
||||
/**
|
||||
Error message for invalid path operations
|
||||
*/
|
||||
static int parse_fill_name( string_buffer_t *name,
|
||||
const wchar_t *src)
|
||||
#define BUILTIN_SET_PATH_ERROR L"%ls: Could not add component %ls to %ls.\n"
|
||||
|
||||
/**
|
||||
Hint for invalid path operation with a colon
|
||||
*/
|
||||
#define BUILTIN_SET_PATH_HINT L"%ls: Did you mean 'set %ls $%ls %ls'?\n"
|
||||
|
||||
/**
|
||||
Error for mismatch between index count and elements
|
||||
*/
|
||||
#define BUILTIN_SET_ARG_COUNT L"%ls: The number of variable indexes does not match the number of values\n"
|
||||
|
||||
/**
|
||||
Test if the specified variable should be subject to path validation
|
||||
*/
|
||||
static int is_path_variable( const wchar_t *env )
|
||||
{
|
||||
|
||||
if (src == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (iswalnum(*src) || *src == L'_')
|
||||
{
|
||||
sb_append_char(name, *src++);
|
||||
}
|
||||
|
||||
if (*src != L'[' && *src != L'\0')
|
||||
{
|
||||
sb_printf( sb_err, BUILTIN_ERR_VARCHAR, L"set", *src );
|
||||
sb_append2(sb_err, parser_current_line(), L"\n", (void *)0 );
|
||||
// builtin_print_help( L"set", sb_err );
|
||||
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return contains_str( env,
|
||||
L"PATH",
|
||||
L"CDPATH",
|
||||
(void *)0 );
|
||||
}
|
||||
|
||||
/**
|
||||
Call env_set. If this is a path variable, e.g. PATH, validate the
|
||||
elements. On error, print a description of the problem to stderr.
|
||||
*/
|
||||
static int my_env_set( const wchar_t *key, array_list_t *val, int scope )
|
||||
{
|
||||
string_buffer_t sb;
|
||||
int i;
|
||||
int retcode = 0;
|
||||
wchar_t *val_str=0;
|
||||
|
||||
if( is_path_variable( key ) )
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
for( i=0; i<al_get_count( val ); i++ )
|
||||
{
|
||||
int show_perror = 0;
|
||||
int show_hint = 0;
|
||||
|
||||
struct stat buff;
|
||||
wchar_t *dir = (wchar_t *)al_get( val, i );
|
||||
|
||||
if( wstat( dir, &buff ) )
|
||||
{
|
||||
error = 1;
|
||||
show_perror = 1;
|
||||
}
|
||||
|
||||
if( !( S_IFDIR & buff.st_mode ) )
|
||||
{
|
||||
error = 1;
|
||||
|
||||
}
|
||||
|
||||
if( error )
|
||||
{
|
||||
wchar_t *colon;
|
||||
|
||||
sb_printf( sb_err,
|
||||
_(BUILTIN_SET_PATH_ERROR),
|
||||
L"set",
|
||||
dir,
|
||||
key );
|
||||
|
||||
colon = wcschr( dir, L':' );
|
||||
|
||||
if( colon && *(colon+1) )
|
||||
{
|
||||
show_hint = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( show_perror )
|
||||
{
|
||||
builtin_wperror( L"set" );
|
||||
}
|
||||
|
||||
if( show_hint )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_(BUILTIN_SET_PATH_HINT),
|
||||
L"set",
|
||||
key,
|
||||
key,
|
||||
wcschr( dir, L':' )+1);
|
||||
}
|
||||
|
||||
if( error )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( error )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sb_init( &sb );
|
||||
|
||||
if( al_get_count( val ) )
|
||||
{
|
||||
for( i=0; i<al_get_count( val ); i++ )
|
||||
{
|
||||
sb_append( &sb, (wchar_t *)al_get( val, i ) );
|
||||
if( i<al_get_count( val )-1 )
|
||||
{
|
||||
sb_append( &sb, ARRAY_SEP_STR );
|
||||
}
|
||||
}
|
||||
val_str = (wchar_t *)sb.buff;
|
||||
|
||||
}
|
||||
|
||||
switch( env_set( key, val_str, scope | ENV_USER ) )
|
||||
{
|
||||
case ENV_PERM:
|
||||
{
|
||||
sb_printf( sb_err, _(L"%ls: Tried to change the read-only variable '%ls'\n"), L"set", key );
|
||||
retcode=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sb_destroy( &sb );
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
/**
|
||||
Extract indexes from a destination argument of the form name[index1 index2...]
|
||||
*/
|
||||
static int parse_fill_indexes( array_list_t *indexes,
|
||||
const wchar_t *src)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
\param indexes the list to insert the new indexes into
|
||||
\param src the source string to parse
|
||||
\param name the name of the element. Return null if the name in \c src does not match this name
|
||||
|
||||
\return the number of indexes parsed, or -1 on error
|
||||
*/
|
||||
static int parse_index( array_list_t *indexes,
|
||||
const wchar_t *src,
|
||||
const wchar_t *name )
|
||||
{
|
||||
int len;
|
||||
|
||||
int count = 0;
|
||||
const wchar_t *src_orig = src;
|
||||
|
||||
if (src == 0)
|
||||
{
|
||||
return 0;
|
||||
@@ -76,16 +194,27 @@ static int parse_fill_indexes( array_list_t *indexes,
|
||||
src++;
|
||||
}
|
||||
|
||||
if (*src == L'\0')
|
||||
if (*src != L'[')
|
||||
{
|
||||
sb_printf( sb_err, _(BUILTIN_SET_ARG_COUNT), L"set" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (*src++ != L'[')
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
len = src-src_orig;
|
||||
|
||||
if( (wcsncmp( src_orig, name, len )!=0) || (wcslen(name) != (len)) )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_(L"%ls: Multiple variable names specified in single call (%ls and %.*ls)\n"),
|
||||
L"set",
|
||||
name,
|
||||
len,
|
||||
src_orig);
|
||||
return 0;
|
||||
}
|
||||
|
||||
src++;
|
||||
|
||||
while (iswspace(*src))
|
||||
{
|
||||
src++;
|
||||
@@ -98,9 +227,9 @@ static int parse_fill_indexes( array_list_t *indexes,
|
||||
if (end == src)
|
||||
{
|
||||
sb_printf(sb_err, _(L"%ls: Invalid index starting at '%ls'\n"), L"set", src);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int *ind = (int *) calloc(1, sizeof(int));
|
||||
*ind = (int) l_ind;
|
||||
al_push(indexes, ind);
|
||||
@@ -114,7 +243,13 @@ static int parse_fill_indexes( array_list_t *indexes,
|
||||
|
||||
|
||||
/**
|
||||
Update a list by writing the specified values at the specified indexes
|
||||
Update a list \c list by writing copies (using wcsdup) of the
|
||||
values specified by \c values to the indexes specified by \c
|
||||
indexes. The previous entries at the specidied position will be
|
||||
free'd.
|
||||
|
||||
\return The number of elements in the list after the modifications
|
||||
have been made
|
||||
*/
|
||||
static int update_values( array_list_t *list,
|
||||
array_list_t *indexes,
|
||||
@@ -122,16 +257,12 @@ static int update_values( array_list_t *list,
|
||||
{
|
||||
int i;
|
||||
|
||||
//fwprintf(stderr, L"Scan complete\n");
|
||||
/* Replace values where needed */
|
||||
for( i = 0; i < al_get_count(indexes); i++ )
|
||||
{
|
||||
int ind = *(int *) al_get(indexes, i) - 1;
|
||||
void *new = (void *) al_get(values, i);
|
||||
if (al_get(list, ind) != 0)
|
||||
{
|
||||
free((void *) al_get(list, ind));
|
||||
}
|
||||
free((void *) al_get(list, ind));
|
||||
al_set(list, ind, new != 0 ? wcsdup(new) : wcsdup(L""));
|
||||
}
|
||||
|
||||
@@ -151,7 +282,7 @@ static int al_contains_int( array_list_t *list,
|
||||
for (i = 0; i < al_get_count(list); i++)
|
||||
{
|
||||
int *current = (int *) al_get(list, i);
|
||||
if (current != 0 && *current == val)
|
||||
if( current != 0 && *current == val )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@@ -164,13 +295,11 @@ static int al_contains_int( array_list_t *list,
|
||||
/**
|
||||
Erase from a list values at specified indexes
|
||||
*/
|
||||
static int erase_values(array_list_t *list, array_list_t *indexes)
|
||||
static void erase_values(array_list_t *list, array_list_t *indexes)
|
||||
{
|
||||
int i;
|
||||
array_list_t result;
|
||||
|
||||
//fwprintf(stderr, L"Starting with %d\n", al_get_count(list));
|
||||
|
||||
al_init(&result);
|
||||
|
||||
for (i = 0; i < al_get_count(list); i++)
|
||||
@@ -188,33 +317,6 @@ static int erase_values(array_list_t *list, array_list_t *indexes)
|
||||
al_truncate(list,0);
|
||||
al_push_all( list, &result );
|
||||
al_destroy(&result);
|
||||
|
||||
//fwprintf(stderr, L"Remaining: %d\n", al_get_count(&result));
|
||||
|
||||
return al_get_count(list);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Fill a string buffer with values from a list, using ARRAY_SEP_STR to separate them
|
||||
*/
|
||||
static int fill_buffer_from_list(string_buffer_t *sb, array_list_t *list)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < al_get_count(list); i++)
|
||||
{
|
||||
wchar_t *v = (wchar_t *) al_get(list, i);
|
||||
if (v != 0)
|
||||
{
|
||||
// fwprintf(stderr, L".\n");
|
||||
// fwprintf(stderr, L"Collecting %ls from %d\n", v, i);
|
||||
sb_append(sb, v);
|
||||
}
|
||||
if (i < al_get_count(list) - 1)
|
||||
sb_append(sb, ARRAY_SEP_STR);
|
||||
}
|
||||
return al_get_count(list);
|
||||
}
|
||||
|
||||
|
||||
@@ -254,46 +356,64 @@ static void print_variables(int include_values, int esc, int scope)
|
||||
al_destroy(&names);
|
||||
}
|
||||
|
||||
/**
|
||||
The set builtin. Creates, updates and erases environment variables and environemnt variable arrays.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
The set builtin. Creates, updates and erases environment variables
|
||||
and environemnt variable arrays.
|
||||
*/
|
||||
int builtin_set( wchar_t **argv )
|
||||
{
|
||||
|
||||
/**
|
||||
Variables used for parsing the argument list
|
||||
*/
|
||||
const static struct woption
|
||||
long_options[] =
|
||||
{
|
||||
{
|
||||
L"export", no_argument, 0, 'x'
|
||||
},
|
||||
}
|
||||
,
|
||||
{
|
||||
L"global", no_argument, 0, 'g'
|
||||
},
|
||||
}
|
||||
,
|
||||
{
|
||||
L"local", no_argument, 0, 'l'
|
||||
},
|
||||
}
|
||||
,
|
||||
{
|
||||
L"erase", no_argument, 0, 'e'
|
||||
},
|
||||
}
|
||||
,
|
||||
{
|
||||
L"names", no_argument, 0, 'n'
|
||||
} ,
|
||||
}
|
||||
,
|
||||
{
|
||||
L"unexport", no_argument, 0, 'u'
|
||||
} ,
|
||||
}
|
||||
,
|
||||
{
|
||||
L"universal", no_argument, 0, 'U'
|
||||
} ,
|
||||
}
|
||||
,
|
||||
{
|
||||
L"query", no_argument, 0, 'q'
|
||||
} ,
|
||||
}
|
||||
,
|
||||
{
|
||||
L"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
wchar_t short_options[] = L"+xglenuUq";
|
||||
const wchar_t *short_options = L"+xglenuUqh";
|
||||
|
||||
int argc = builtin_count_args(argv);
|
||||
|
||||
@@ -309,14 +429,12 @@ int builtin_set( wchar_t **argv )
|
||||
Variables used for performing the actual work
|
||||
*/
|
||||
wchar_t *dest = 0;
|
||||
array_list_t values;
|
||||
string_buffer_t name_sb;
|
||||
int retcode=0;
|
||||
wchar_t *name;
|
||||
array_list_t indexes;
|
||||
int retval;
|
||||
|
||||
|
||||
int scope;
|
||||
int slice=0;
|
||||
int i;
|
||||
|
||||
|
||||
/* Parse options to obtain the requested operation and the modifiers */
|
||||
woptind = 0;
|
||||
while (1)
|
||||
@@ -332,37 +450,61 @@ int builtin_set( wchar_t **argv )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
erase = 1;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
list = 1;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
export = 1;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
local = 1;
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
global = 1;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
unexport = 1;
|
||||
break;
|
||||
|
||||
case 'U':
|
||||
universal = 1;
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
query = 1;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
|
||||
case '?':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Ok, all arguments have been parsed, let's validate them
|
||||
*/
|
||||
|
||||
/*
|
||||
If we are checking the existance of a variable (-q) we can not
|
||||
also specify scope
|
||||
*/
|
||||
|
||||
if( query && (erase || list || global || local || universal || export || unexport ) )
|
||||
{
|
||||
sb_printf(sb_err,
|
||||
@@ -375,7 +517,7 @@ int builtin_set( wchar_t **argv )
|
||||
}
|
||||
|
||||
|
||||
/* Check operation and modifiers sanity */
|
||||
/* We can't both list and erase varaibles */
|
||||
if( erase && list )
|
||||
{
|
||||
sb_printf(sb_err,
|
||||
@@ -387,6 +529,9 @@ int builtin_set( wchar_t **argv )
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Variables can only have one scope
|
||||
*/
|
||||
if( local + global + universal > 1 )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
@@ -397,6 +542,9 @@ int builtin_set( wchar_t **argv )
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Variables can only have one export status
|
||||
*/
|
||||
if( export && unexport )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
@@ -407,205 +555,211 @@ int builtin_set( wchar_t **argv )
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Calculate the scope value for variable assignement
|
||||
*/
|
||||
scope = (local ? ENV_LOCAL : 0) | (global ? ENV_GLOBAL : 0) | (export ? ENV_EXPORT : 0) | (unexport ? ENV_UNEXPORT : 0) | (universal ? ENV_UNIVERSAL:0) | ENV_USER;
|
||||
|
||||
if( query )
|
||||
{
|
||||
/*
|
||||
Query mode. Return number of specified variables that do not exist.
|
||||
Query mode. Return the number variables that do not exist
|
||||
out of the specified variables.
|
||||
*/
|
||||
int i;
|
||||
for( i=woptind; i<argc; i++ )
|
||||
{
|
||||
if( !env_exist( argv[i] ) )
|
||||
{
|
||||
retcode++;
|
||||
}
|
||||
|
||||
}
|
||||
return retcode;
|
||||
}
|
||||
|
||||
|
||||
/* Parse destination */
|
||||
if( woptind < argc )
|
||||
if( woptind == argc )
|
||||
{
|
||||
dest = wcsdup(argv[woptind++]);
|
||||
//fwprintf(stderr, L"Dest: %ls\n", dest);
|
||||
/*
|
||||
Print values of variables
|
||||
*/
|
||||
|
||||
if( !wcslen( dest ) )
|
||||
if( erase )
|
||||
{
|
||||
free( dest );
|
||||
sb_printf( sb_err, BUILTIN_ERR_VARNAME_ZERO, argv[0] );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse values */
|
||||
// wchar_t **values = woptind < argc ? (wchar_t **) calloc(argc - woptind, sizeof(wchar_t *)) : 0;
|
||||
|
||||
al_init(&values);
|
||||
while( woptind < argc )
|
||||
{
|
||||
al_push(&values, argv[woptind++]);
|
||||
// fwprintf(stderr, L"Val: %ls\n", argv[woptind - 1]);
|
||||
}
|
||||
|
||||
/* Extract variable name and indexes */
|
||||
|
||||
sb_init(&name_sb);
|
||||
retval = parse_fill_name(&name_sb, dest);
|
||||
|
||||
|
||||
if( retval < 0 )
|
||||
retcode=1;
|
||||
|
||||
if( !retcode )
|
||||
{
|
||||
name = (wchar_t *) name_sb.buff;
|
||||
//fwprintf(stderr, L"Name is %ls\n", name);
|
||||
|
||||
al_init(&indexes);
|
||||
retval = parse_fill_indexes(&indexes, dest);
|
||||
if (retval < 0)
|
||||
sb_printf( sb_err,
|
||||
_(L"%ls: Erase needs a variable name\n%ls\n"),
|
||||
argv[0],
|
||||
parser_current_line() );
|
||||
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
retcode = 1;
|
||||
}
|
||||
|
||||
if( !retcode )
|
||||
{
|
||||
|
||||
int i;
|
||||
int finished=0;
|
||||
|
||||
/* Do the actual work */
|
||||
int scope = (local ? ENV_LOCAL : 0) | (global ? ENV_GLOBAL : 0) | (export ? ENV_EXPORT : 0) | (unexport ? ENV_UNEXPORT : 0) | (universal ? ENV_UNIVERSAL:0) | ENV_USER;
|
||||
if( list )
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Maybe we should issue an error if there are any other arguments */
|
||||
print_variables(0, 0, scope);
|
||||
finished=1;
|
||||
}
|
||||
|
||||
if( (!finished ) &&
|
||||
(name == 0 || wcslen(name) == 0))
|
||||
{
|
||||
/* No arguments -- display name & value for all variables in scope */
|
||||
if( erase )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_(L"%ls: Erase needs a variable name\n%ls\n"),
|
||||
argv[0],
|
||||
parser_current_line() );
|
||||
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
retcode = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
print_variables( 1, 1, scope );
|
||||
}
|
||||
|
||||
finished=1;
|
||||
}
|
||||
|
||||
|
||||
if( !finished )
|
||||
{
|
||||
if( al_get_count( &values ) == 0 &&
|
||||
al_get_count( &indexes ) == 0 &&
|
||||
!erase &&
|
||||
!list )
|
||||
{
|
||||
env_set( name, 0, scope );
|
||||
finished = 1;
|
||||
}
|
||||
print_variables( 1, 1, scope );
|
||||
}
|
||||
|
||||
if( !finished )
|
||||
return retcode;
|
||||
}
|
||||
|
||||
if( list )
|
||||
{
|
||||
/* Maybe we should issue an error if there are any other arguments? */
|
||||
print_variables(0, 0, scope);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( !(dest = wcsdup(argv[woptind])))
|
||||
{
|
||||
die_mem();
|
||||
}
|
||||
|
||||
if( wcschr( dest, L'[' ) )
|
||||
{
|
||||
slice = 1;
|
||||
*wcschr( dest, L'[' )=0;
|
||||
}
|
||||
|
||||
if( !wcslen( dest ) )
|
||||
{
|
||||
free( dest );
|
||||
sb_printf( sb_err, BUILTIN_ERR_VARNAME_ZERO, argv[0] );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
set assignment can work in two modes, either using slices or
|
||||
using the whole array. We detect which mode is used here.
|
||||
*/
|
||||
|
||||
if( slice )
|
||||
{
|
||||
|
||||
/*
|
||||
Slice mode
|
||||
*/
|
||||
int idx_count, val_count;
|
||||
array_list_t values;
|
||||
array_list_t indexes;
|
||||
|
||||
al_init(&values);
|
||||
al_init(&indexes);
|
||||
|
||||
for( ; woptind<argc; woptind++ )
|
||||
{
|
||||
if( !parse_index( &indexes, argv[woptind], dest ) )
|
||||
{
|
||||
retcode = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
val_count = argc-woptind-1;
|
||||
idx_count = al_get_count( &indexes );
|
||||
|
||||
if( !erase )
|
||||
{
|
||||
if( val_count < idx_count )
|
||||
{
|
||||
sb_printf( sb_err, _(BUILTIN_SET_ARG_COUNT), argv[0] );
|
||||
retcode=1;
|
||||
break;
|
||||
}
|
||||
if( val_count == idx_count )
|
||||
{
|
||||
woptind++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !retcode )
|
||||
{
|
||||
/* There are some arguments, we have at least a variable name */
|
||||
if( erase && al_get_count(&values) != 0 )
|
||||
/*
|
||||
Slice indexes have been calculated, do the actual work
|
||||
*/
|
||||
|
||||
array_list_t result;
|
||||
al_init(&result);
|
||||
|
||||
tokenize_variable_array( env_get(dest), &result );
|
||||
if( erase )
|
||||
{
|
||||
erase_values(&result, &indexes);
|
||||
my_env_set( dest, &result, scope);
|
||||
}
|
||||
else
|
||||
{
|
||||
array_list_t value;
|
||||
al_init(&value);
|
||||
|
||||
while( woptind < argc )
|
||||
{
|
||||
al_push(&value, argv[woptind++]);
|
||||
}
|
||||
|
||||
update_values( &result,
|
||||
&indexes,
|
||||
&value );
|
||||
|
||||
my_env_set(dest,
|
||||
&result,
|
||||
scope);
|
||||
|
||||
al_destroy( &value );
|
||||
|
||||
}
|
||||
al_foreach( &result, (void (*)(const void *))&free );
|
||||
al_destroy( &result );
|
||||
}
|
||||
|
||||
al_foreach( &indexes, (void (*)(const void *))&free );
|
||||
al_destroy(&indexes);
|
||||
al_destroy(&values);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
woptind++;
|
||||
|
||||
/*
|
||||
No slicing
|
||||
*/
|
||||
if( erase )
|
||||
{
|
||||
if( woptind != argc )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_(L"%ls: Values cannot be specfied with erase\n%ls\n"),
|
||||
argv[0],
|
||||
parser_current_line() );
|
||||
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
retcode = 1;
|
||||
}
|
||||
retcode=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* All ok, we can alter the specified variable */
|
||||
array_list_t val_l;
|
||||
al_init(&val_l);
|
||||
|
||||
void *old=0;
|
||||
|
||||
if (al_get_count(&indexes) == 0)
|
||||
{
|
||||
/* We will act upon the entire variable */
|
||||
|
||||
al_push( &val_l, wcsdup(L"") );
|
||||
old = val_l.arr;
|
||||
|
||||
/* Build indexes for all variable or all new values */
|
||||
int end_index = erase ? al_get_count(&val_l) : al_get_count(&values);
|
||||
for (i = 0; i < end_index; i++)
|
||||
{
|
||||
int *ind = (int *) calloc(1, sizeof(int));
|
||||
*ind = i + 1;
|
||||
al_push(&indexes, ind);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We will act upon some specific indexes */
|
||||
expand_variable_array( env_get(name), &val_l );
|
||||
}
|
||||
|
||||
string_buffer_t result_sb;
|
||||
sb_init(&result_sb);
|
||||
if (erase)
|
||||
{
|
||||
int rem = erase_values(&val_l, &indexes);
|
||||
if (rem == 0)
|
||||
{
|
||||
env_remove(name, ENV_USER);
|
||||
}
|
||||
else
|
||||
{
|
||||
fill_buffer_from_list(&result_sb, &val_l);
|
||||
env_set(name, (wchar_t *) result_sb.buff, scope);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
update_values( &val_l,
|
||||
&indexes,
|
||||
&values );
|
||||
|
||||
fill_buffer_from_list( &result_sb,
|
||||
&val_l );
|
||||
|
||||
env_set(name,
|
||||
(wchar_t *) result_sb.buff,
|
||||
scope);
|
||||
}
|
||||
|
||||
al_foreach( &val_l, (void (*)(const void *))&free );
|
||||
al_destroy(&val_l);
|
||||
sb_destroy(&result_sb);
|
||||
{
|
||||
env_remove( dest, ENV_USER );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
array_list_t val;
|
||||
al_init( &val );
|
||||
|
||||
for( i=woptind; i<argc; i++ )
|
||||
{
|
||||
al_push( &val, argv[i] );
|
||||
}
|
||||
|
||||
al_foreach( &indexes, (void (*)(const void *))&free );
|
||||
al_destroy(&indexes);
|
||||
retcode = my_env_set( dest, &val, scope );
|
||||
|
||||
al_destroy( &val );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Common cleanup */
|
||||
//fwprintf(stderr, L"Cleanup\n");
|
||||
free(dest);
|
||||
sb_destroy(&name_sb);
|
||||
al_destroy( &values );
|
||||
free( dest );
|
||||
|
||||
return retcode;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
Functions used for implementing the ulimit builtin.
|
||||
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
@@ -12,8 +14,6 @@ Functions used for implementing the ulimit builtin.
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "fallback.h"
|
||||
#include "util.h"
|
||||
|
||||
@@ -63,13 +63,13 @@ const static struct resource_t resource_arr[] =
|
||||
RLIMIT_FSIZE, L"Maximum size of files created by the shell", L'f', 1024
|
||||
}
|
||||
,
|
||||
#if HAVE_RLIMIT_MEMLOCK
|
||||
#ifdef RLIMIT_MEMLOCK
|
||||
{
|
||||
RLIMIT_MEMLOCK, L"Maximum size that may be locked into memory", L'l', 1024
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#if HAVE_RLIMIT_RSS
|
||||
#ifdef RLIMIT_RSS
|
||||
{
|
||||
RLIMIT_RSS, L"Maximum resident set size", L'm', 1024
|
||||
}
|
||||
@@ -87,13 +87,13 @@ const static struct resource_t resource_arr[] =
|
||||
RLIMIT_CPU, L"Maximum amount of cpu time in seconds", L't', 1
|
||||
}
|
||||
,
|
||||
#if HAVE_RLIMIT_NPROC
|
||||
#ifdef RLIMIT_NPROC
|
||||
{
|
||||
RLIMIT_NPROC, L"Maximum number of processes available to a single user", L'u', 1
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#if HAVE_RLIMIT_AS
|
||||
#ifdef RLIMIT_AS
|
||||
{
|
||||
RLIMIT_AS, L"Maximum amount of virtual memory available to the shell", L'v', 1024
|
||||
}
|
||||
@@ -326,6 +326,10 @@ int builtin_ulimit( wchar_t ** argv )
|
||||
L"virtual-memory-size", no_argument, 0, 'v'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
@@ -337,7 +341,7 @@ int builtin_ulimit( wchar_t ** argv )
|
||||
|
||||
int opt = wgetopt_long( argc,
|
||||
argv,
|
||||
L"aHScdflmnptuv",
|
||||
L"aHScdflmnptuvh",
|
||||
long_options,
|
||||
&opt_index );
|
||||
if( opt == -1 )
|
||||
@@ -379,13 +383,13 @@ int builtin_ulimit( wchar_t ** argv )
|
||||
case L'f':
|
||||
what=RLIMIT_FSIZE;
|
||||
break;
|
||||
#if HAVE_RLIMIT_MEMLOCK
|
||||
#ifdef RLIMIT_MEMLOCK
|
||||
case L'l':
|
||||
what=RLIMIT_MEMLOCK;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if HAVE_RLIMIT_RSS
|
||||
#ifdef RLIMIT_RSS
|
||||
case L'm':
|
||||
what=RLIMIT_RSS;
|
||||
break;
|
||||
@@ -403,18 +407,22 @@ int builtin_ulimit( wchar_t ** argv )
|
||||
what=RLIMIT_CPU;
|
||||
break;
|
||||
|
||||
#if HAVE_RLIMIT_NPROC
|
||||
#ifdef RLIMIT_NPROC
|
||||
case L'u':
|
||||
what=RLIMIT_NPROC;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if HAVE_RLIMIT_AS
|
||||
#ifdef RLIMIT_AS
|
||||
case L'v':
|
||||
what=RLIMIT_AS;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case L'h':
|
||||
builtin_print_help( argv[0], sb_out );
|
||||
return 0;
|
||||
|
||||
case L'?':
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
|
||||
183
common.c
183
common.c
@@ -61,11 +61,6 @@ parts of fish.
|
||||
#include "wildcard.h"
|
||||
#include "parser.h"
|
||||
|
||||
/**
|
||||
The maximum number of minor errors to report. Further errors will be omitted.
|
||||
*/
|
||||
#define ERROR_MAX_COUNT 1
|
||||
|
||||
/**
|
||||
The number of milliseconds to wait between polls when attempting to acquire
|
||||
a lockfile
|
||||
@@ -400,119 +395,17 @@ wchar_t **strv2wcsv( const char **in )
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*$OpenBSD: strlcat.c,v 1.11 2003/06/17 21:56:24 millert Exp $*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
size_t
|
||||
wcslcat(wchar_t *dst, const wchar_t *src, size_t siz)
|
||||
{
|
||||
|
||||
register wchar_t *d = dst;
|
||||
register const wchar_t *s = src;
|
||||
register size_t n = siz;
|
||||
size_t dlen;
|
||||
|
||||
/* Find the end of dst and adjust bytes left but don't go past end */
|
||||
while (n-- != 0 && *d != '\0')
|
||||
d++;
|
||||
|
||||
dlen = d - dst;
|
||||
n = siz - dlen;
|
||||
|
||||
if (n == 0)
|
||||
return(dlen + wcslen(s));
|
||||
|
||||
while (*s != '\0')
|
||||
{
|
||||
if (n != 1)
|
||||
{
|
||||
*d++ = *s;
|
||||
n--;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
*d = '\0';
|
||||
|
||||
return(dlen + (s - src));
|
||||
/* count does not include NUL */
|
||||
}
|
||||
|
||||
/*$OpenBSD: strlcpy.c,v 1.8 2003/06/17 21:56:24 millert Exp $*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
size_t
|
||||
wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz)
|
||||
{
|
||||
register wchar_t *d = dst;
|
||||
register const wchar_t *s = src;
|
||||
register size_t n = siz;
|
||||
|
||||
/* Copy as many bytes as will fit */
|
||||
if (n != 0 && --n != 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
if ((*d++ = *s++) == 0)
|
||||
break;
|
||||
}
|
||||
while (--n != 0);
|
||||
}
|
||||
|
||||
/* Not enough room in dst, add NUL and traverse rest of src */
|
||||
if (n == 0)
|
||||
{
|
||||
if (siz != 0)
|
||||
*d = '\0';
|
||||
/* NUL-terminate dst */
|
||||
while (*s++)
|
||||
;
|
||||
}
|
||||
return(s - src - 1);
|
||||
/* count does not include NUL */
|
||||
}
|
||||
|
||||
int wcsvarname( wchar_t *str )
|
||||
wchar_t *wcsvarname( wchar_t *str )
|
||||
{
|
||||
while( *str )
|
||||
{
|
||||
if( (!iswalnum(*str)) && (*str != L'_' ) )
|
||||
{
|
||||
return 0;
|
||||
return str;
|
||||
}
|
||||
str++;
|
||||
}
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -597,6 +490,12 @@ int contains_str( const wchar_t *a, ... )
|
||||
wchar_t *arg;
|
||||
va_list va;
|
||||
int res = 0;
|
||||
|
||||
if( !a )
|
||||
{
|
||||
debug( 1, L"Warning: Called contains_str with null argument. This is a bug." );
|
||||
return 0;
|
||||
}
|
||||
|
||||
va_start( va, a );
|
||||
while( (arg=va_arg(va, wchar_t *) )!= 0 )
|
||||
@@ -641,23 +540,28 @@ void debug( int level, const wchar_t *msg, ... )
|
||||
{
|
||||
va_list va;
|
||||
string_buffer_t sb;
|
||||
string_buffer_t sb2;
|
||||
|
||||
if( level > debug_level )
|
||||
return;
|
||||
|
||||
sb_init( &sb );
|
||||
va_start( va, msg );
|
||||
|
||||
sb_init( &sb2 );
|
||||
|
||||
sb_printf( &sb, L"%ls: ", program_name );
|
||||
|
||||
va_start( va, msg );
|
||||
sb_vprintf( &sb, msg, va );
|
||||
va_end( va );
|
||||
|
||||
write_screen( (wchar_t *)sb.buff );
|
||||
write_screen( (wchar_t *)sb.buff, &sb2 );
|
||||
fwprintf( stderr, L"%ls", sb2.buff );
|
||||
|
||||
sb_destroy( &sb );
|
||||
sb_destroy( &sb2 );
|
||||
}
|
||||
|
||||
void write_screen( const wchar_t *msg )
|
||||
void write_screen( const wchar_t *msg, string_buffer_t *buff )
|
||||
{
|
||||
const wchar_t *start, *pos;
|
||||
int line_width = 0;
|
||||
@@ -678,7 +582,7 @@ void write_screen( const wchar_t *msg )
|
||||
*/
|
||||
while( *pos && ( !wcschr( L" \n\r\t", *pos ) ) )
|
||||
{
|
||||
|
||||
|
||||
/*
|
||||
Check is token is wider than one line.
|
||||
If so we mark it as an overflow and break the token.
|
||||
@@ -703,12 +607,12 @@ void write_screen( const wchar_t *msg )
|
||||
else if( overflow )
|
||||
{
|
||||
/*
|
||||
In case of overflow, we print a newline, except if we alreade are at position 0
|
||||
In case of overflow, we print a newline, except if we already are at position 0
|
||||
*/
|
||||
wchar_t *token = wcsndup( start, pos-start );
|
||||
if( line_width != 0 )
|
||||
putwc( L'\n', stderr );
|
||||
fwprintf( stderr, L"%ls-\n", token );
|
||||
sb_append_char( buff, L'\n' );
|
||||
sb_printf( buff, L"%ls-\n", token );
|
||||
free( token );
|
||||
line_width=0;
|
||||
}
|
||||
@@ -720,13 +624,14 @@ void write_screen( const wchar_t *msg )
|
||||
wchar_t *token = wcsndup( start, pos-start );
|
||||
if( (line_width + (line_width!=0?1:0) + tok_width) > screen_width )
|
||||
{
|
||||
putwc( L'\n', stderr );
|
||||
sb_append_char( buff, L'\n' );
|
||||
line_width=0;
|
||||
}
|
||||
fwprintf( stderr, L"%ls%ls", line_width?L" ":L"", token );
|
||||
sb_printf( buff, L"%ls%ls", line_width?L" ":L"", token );
|
||||
free( token );
|
||||
line_width += (line_width!=0?1:0) + tok_width;
|
||||
}
|
||||
|
||||
/*
|
||||
Break on end of string
|
||||
*/
|
||||
@@ -738,9 +643,9 @@ void write_screen( const wchar_t *msg )
|
||||
}
|
||||
else
|
||||
{
|
||||
fwprintf( stderr, L"%ls", msg );
|
||||
sb_printf( buff, L"%ls", msg );
|
||||
}
|
||||
putwc( L'\n', stderr );
|
||||
sb_append_char( buff, L'\n' );
|
||||
}
|
||||
|
||||
wchar_t *escape( const wchar_t *in,
|
||||
@@ -934,14 +839,14 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special )
|
||||
int base=16;
|
||||
|
||||
int byte = 0;
|
||||
int max_val = 127;
|
||||
wchar_t max_val = ASCII_MAX;
|
||||
|
||||
switch( in[in_pos] )
|
||||
{
|
||||
case L'u':
|
||||
{
|
||||
chars=4;
|
||||
max_val = 35535;
|
||||
max_val = UCS2_MAX;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -960,7 +865,7 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special )
|
||||
case L'X':
|
||||
{
|
||||
byte=1;
|
||||
max_val = 255;
|
||||
max_val = BYTE_MAX;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -986,7 +891,7 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special )
|
||||
res=(res*base)|d;
|
||||
}
|
||||
|
||||
if( (res > 0) && (res <= max_val) )
|
||||
if( (res <= max_val) )
|
||||
{
|
||||
in[out_pos] = (byte?ENCODE_DIRECT_BASE:0)+res;
|
||||
}
|
||||
@@ -1500,3 +1405,29 @@ int common_get_height()
|
||||
return termsize.ws_row;
|
||||
}
|
||||
|
||||
void tokenize_variable_array( const wchar_t *val, array_list_t *out )
|
||||
{
|
||||
if( val )
|
||||
{
|
||||
wchar_t *cpy = wcsdup( val );
|
||||
wchar_t *pos, *start;
|
||||
|
||||
if( !cpy )
|
||||
{
|
||||
die_mem();
|
||||
}
|
||||
|
||||
for( start=pos=cpy; *pos; pos++ )
|
||||
{
|
||||
if( *pos == ARRAY_SEP )
|
||||
{
|
||||
*pos=0;
|
||||
al_push( out, start==cpy?cpy:wcsdup(start) );
|
||||
start=pos+1;
|
||||
}
|
||||
}
|
||||
al_push( out, start==cpy?cpy:wcsdup(start) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
92
common.h
92
common.h
@@ -15,40 +15,31 @@
|
||||
|
||||
#include "util.h"
|
||||
|
||||
/**
|
||||
Under curses, tputs expects an int (*func)(char) as its last
|
||||
parameter, but in ncurses, tputs expects a int (*func)(int) as its
|
||||
last parameter. tputs_arg_t is defined to always be what tputs
|
||||
expects. Hopefully.
|
||||
*/
|
||||
|
||||
#ifdef NCURSES_VERSION
|
||||
typedef int tputs_arg_t;
|
||||
#else
|
||||
typedef char tputs_arg_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
Maximum number of bytes used by a single utf-8 character
|
||||
*/
|
||||
#define MAX_UTF8_BYTES 6
|
||||
|
||||
/**
|
||||
Color code for set_color. Does not update the color.
|
||||
*/
|
||||
|
||||
#define FISH_COLOR_IGNORE -1
|
||||
|
||||
/**
|
||||
Color code for set_color. Sets the default color.
|
||||
*/
|
||||
#define FISH_COLOR_RESET -2
|
||||
|
||||
/**
|
||||
This is in the unicode private use area.
|
||||
*/
|
||||
#define ENCODE_DIRECT_BASE 0xf100
|
||||
|
||||
/**
|
||||
Highest legal ascii value
|
||||
*/
|
||||
#define ASCII_MAX 127u
|
||||
|
||||
/**
|
||||
Highest legal 16-bit unicode value
|
||||
*/
|
||||
#define UCS2_MAX 0xffffu
|
||||
|
||||
/**
|
||||
Highest legal byte value
|
||||
*/
|
||||
#define BYTE_MAX 0xffu
|
||||
|
||||
/**
|
||||
Save the shell mode on startup so we can restore them on exit
|
||||
*/
|
||||
@@ -147,35 +138,18 @@ wchar_t *wcsdupcat( const wchar_t *a, const wchar_t *b );
|
||||
*/
|
||||
wchar_t *wcsdupcat2( const wchar_t *a, ... );
|
||||
|
||||
|
||||
/**
|
||||
Appends src to string dst of size siz (unlike wcsncat, siz is the
|
||||
full size of dst, not space left). At most siz-1 characters will be
|
||||
copied. Always NUL terminates (unless siz <= wcslen(dst)). Returns
|
||||
wcslen(src) + MIN(siz, wcslen(initial dst)). If retval >= siz,
|
||||
truncation occurred.
|
||||
|
||||
This is the OpenBSD strlcat function, modified for wide characters,
|
||||
and renamed to reflect this change.
|
||||
|
||||
*/
|
||||
size_t wcslcat( wchar_t *dst, const wchar_t *src, size_t siz );
|
||||
|
||||
/**
|
||||
Copy src to string dst of size siz. At most siz-1 characters will
|
||||
be copied. Always NUL terminates (unless siz == 0). Returns
|
||||
wcslen(src); if retval >= siz, truncation occurred.
|
||||
|
||||
This is the OpenBSD strlcpy function, modified for wide characters,
|
||||
and renamed to reflect this change.
|
||||
*/
|
||||
size_t wcslcpy( wchar_t *dst, const wchar_t *src, size_t siz );
|
||||
|
||||
/**
|
||||
Test if the given string is a valid variable name
|
||||
*/
|
||||
|
||||
int wcsvarname( wchar_t *str );
|
||||
|
||||
/**
|
||||
Test if the given string is a valid variable name.
|
||||
|
||||
\return null if this is a valid name, and a pointer to the first invalid character otherwise
|
||||
*/
|
||||
|
||||
wchar_t *wcsvarname( wchar_t *str );
|
||||
|
||||
|
||||
/**
|
||||
@@ -211,9 +185,11 @@ void error_reset();
|
||||
const wchar_t *wsetlocale( int category, const wchar_t *locale );
|
||||
|
||||
/**
|
||||
Checks if \c needle is included in the list of strings specified
|
||||
Checks if \c needle is included in the list of strings specified. A warning is printed if needle is zero.
|
||||
|
||||
\param needle the string to search for in the list
|
||||
|
||||
\return zero is needle is not found, of if needle is null, non-zero otherwise
|
||||
*/
|
||||
int contains_str( const wchar_t *needle, ... );
|
||||
|
||||
@@ -315,10 +291,20 @@ int common_get_height();
|
||||
void common_handle_winch( int signal );
|
||||
|
||||
/**
|
||||
Write paragraph of output to screen. Ignore newlines in message and
|
||||
perform internal line-breaking.
|
||||
Write paragraph of output to the specified stringbuffer, and redo
|
||||
the linebreaks to fit the current screen.
|
||||
*/
|
||||
void write_screen( const wchar_t *msg );
|
||||
void write_screen( const wchar_t *msg, string_buffer_t *buff );
|
||||
|
||||
/**
|
||||
Tokenize the specified string into the specified array_list_t.
|
||||
Each new element is allocated using malloc and must be freed by the
|
||||
caller.
|
||||
|
||||
\param val the input string. The contents of this string is not changed.
|
||||
\param out the list in which to place the elements.
|
||||
*/
|
||||
void tokenize_variable_array( const wchar_t *val, array_list_t *out );
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
35
complete.c
35
complete.c
@@ -1983,7 +1983,8 @@ void complete( const wchar_t *cmd,
|
||||
{
|
||||
if( parser_is_subcommand( tok_last( &tok ) ) )
|
||||
break;
|
||||
|
||||
|
||||
free( current_command );
|
||||
current_command = wcsdup( tok_last( &tok ) );
|
||||
|
||||
on_command = (pos <= tok_get_pos( &tok) + wcslen( tok_last( &tok ) ) );
|
||||
@@ -2022,9 +2023,28 @@ void complete( const wchar_t *cmd,
|
||||
current_token = wcsndup( begin, cursor_pos-(begin-cmd) );
|
||||
|
||||
prev_token = prev_begin ? wcsndup( prev_begin, prev_end - prev_begin ): wcsdup(L"");
|
||||
|
||||
|
||||
// fwprintf( stderr, L"on_command: %d, %ls %ls\n", on_command, current_compmand, current_token );
|
||||
|
||||
if( !had_cmd )
|
||||
{
|
||||
on_command=1;
|
||||
}
|
||||
|
||||
if( !current_token )
|
||||
{
|
||||
current_token = wcsdup(L"");
|
||||
}
|
||||
|
||||
if( !current_command )
|
||||
{
|
||||
current_command = wcsdup(L"");
|
||||
}
|
||||
|
||||
if( !prev_token )
|
||||
{
|
||||
prev_token = wcsdup(L"");
|
||||
}
|
||||
|
||||
if( current_token && current_command && prev_token )
|
||||
{
|
||||
if( on_command )
|
||||
@@ -2044,16 +2064,17 @@ void complete( const wchar_t *cmd,
|
||||
*/
|
||||
|
||||
int do_file;
|
||||
|
||||
|
||||
do_file = complete_param( current_command, prev_token, current_token, comp );
|
||||
complete_param_expand( current_token, comp, do_file );
|
||||
}
|
||||
}
|
||||
|
||||
free( current_token );
|
||||
free( current_command );
|
||||
free( prev_token );
|
||||
}
|
||||
|
||||
free( current_token );
|
||||
free( current_command );
|
||||
free( prev_token );
|
||||
|
||||
error_max=old_error_max;
|
||||
condition_cache_clear();
|
||||
|
||||
192
configure.ac
192
configure.ac
@@ -1,19 +1,21 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(fish,1.21.2,fish-users@lists.sf.net)
|
||||
AC_INIT(fish,1.21.8,fish-users@lists.sf.net)
|
||||
|
||||
# If needed, run autoconf to regenerate the configure file
|
||||
AC_MSG_CHECKING([if autoconf needs to be run])
|
||||
if test configure -ot configure.ac; then
|
||||
AC_MSG_RESULT([yes])
|
||||
if which autoconf >/dev/null; then
|
||||
# No need to provide any error messages if autoconf fails, the
|
||||
# shell and autconf should take care of that themselves
|
||||
AC_MSG_NOTICE([running autoconf])
|
||||
if autoconf; then
|
||||
./configure $@
|
||||
./configure "$@"
|
||||
fi
|
||||
exit
|
||||
exit
|
||||
else
|
||||
AC_MSG_ERROR( [cannot find the autoconf program in your path.
|
||||
This program is needs to be run whenever the configure.ac file is modified.
|
||||
This program needs to be run whenever the configure.ac file is modified.
|
||||
Please install it and try again.])
|
||||
fi
|
||||
else
|
||||
@@ -30,7 +32,7 @@ if test ! -f ./config.h.in -o config.h.in -ot configure.ac; then
|
||||
autoheader
|
||||
else
|
||||
AC_MSG_ERROR( [cannot find the autoheader program in your path.
|
||||
This program is needs to be run whenever the configure.ac file is modified.
|
||||
This program needs to be run whenever the configure.ac file is modified.
|
||||
Please install it and try again.])
|
||||
fi
|
||||
else
|
||||
@@ -83,7 +85,7 @@ AC_PROG_INSTALL
|
||||
# Check for doxygen, which is needed to build
|
||||
AC_CHECK_PROG( has_doxygen, [doxygen], "true")
|
||||
|
||||
if ! test $has_doxygen = "true"; then
|
||||
if ! test "$has_doxygen" = "true"; then
|
||||
AC_MSG_ERROR( [cannot find the Doxygen program in your path.
|
||||
This program is needed to build fish.
|
||||
Please install it and try again.])
|
||||
@@ -110,15 +112,109 @@ else
|
||||
AC_SUBST( XSEL_MAN_PATH,[ ])
|
||||
fi
|
||||
|
||||
#
|
||||
# Test if the compiler accepts the -std=c99 flag. If so, using it
|
||||
# increases the odds of correct compilation, since we want to use the
|
||||
# *wprintf functions, which where defined in C99.
|
||||
#
|
||||
|
||||
XCFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -std=c99"
|
||||
AC_MSG_CHECKING(if -std=c99 works)
|
||||
AC_CACHE_VAL(local_cv_has__std_c99,[
|
||||
AC_TRY_RUN([
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
return 0;
|
||||
}],
|
||||
local_cv_has__std_c99=yes,
|
||||
local_cv_has__std_c99=no,
|
||||
)])
|
||||
AC_MSG_RESULT($local_cv_has__std_c99)
|
||||
case x$local_cv_has__std_c99 in
|
||||
xno) CFLAGS="$XCFLAGS" ;;
|
||||
esac
|
||||
|
||||
#
|
||||
# If we are using gcc, set some flags that increase the odds of the
|
||||
# compiler producing a working binary...
|
||||
#
|
||||
|
||||
if test "$CC" = gcc; then
|
||||
|
||||
#
|
||||
# -fno-optimize-sibling-calls seems to work around a bug where
|
||||
# sending a SIGWINCH to fish on NetBSD causes fish to exit when
|
||||
# compiled with GCC 3.3.3. This is probably either a compiler bug
|
||||
# or a libc bug, but adding this flag seems to fix things for
|
||||
# now. Long term, the real problem should be tracked down and
|
||||
# truly fixed, at which point we can remove this silly flag. This
|
||||
# bug has been verified to not exist on Linux using GCC 3.3.3.
|
||||
#
|
||||
|
||||
CFLAGS="$CFLAGS -fno-optimize-sibling-calls"
|
||||
|
||||
|
||||
#
|
||||
# -Wall is there to keep me on my toes
|
||||
#
|
||||
|
||||
CFLAGS="$CFLAGS -Wall"
|
||||
|
||||
fi
|
||||
|
||||
#
|
||||
# If we are compiling against glibc, set some flags to work around
|
||||
# some rather stupid attempts to hide prototypes for *wprintf
|
||||
# functions, as well as prototypes of various gnu extensions.
|
||||
#
|
||||
|
||||
AC_MSG_CHECKING([if we are compiling against glibc])
|
||||
AC_RUN_IFELSE(
|
||||
[AC_LANG_PROGRAM([
|
||||
#include <stdlib.h>
|
||||
#ifdef __GLIBC__
|
||||
#define STATUS 0
|
||||
#else
|
||||
#define STATUS 1
|
||||
#endif],
|
||||
[return STATUS;])],
|
||||
[glibc=yes],
|
||||
[glibc=no] )
|
||||
|
||||
if test "$glibc" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
|
||||
#
|
||||
# This gives us access to prototypes for gnu extensions and C99
|
||||
# functions if we are compiling agains glibc. All GNU extensions
|
||||
# that are used must have a fallback implementation available in
|
||||
# fallback.h, in order to keep fish working on non-gnu platforms.
|
||||
#
|
||||
|
||||
CFLAGS="$CFLAGS -D _GNU_SOURCE -D _ISOC99_SOURCE"
|
||||
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
# Test cpu for special handling of ppc
|
||||
#
|
||||
# This is used to skip use of tputs on ppc systems, since it seemed to
|
||||
# be broken, at least on older debin-based systems. This is obviously
|
||||
# not the right way to to detect whether this workaround should be
|
||||
# used, since it catches far to many systems, but I do not have the
|
||||
# hardware available to narrow this problem down, and in practice, it
|
||||
# seems that tputs is never really needed.
|
||||
#
|
||||
AC_CANONICAL_TARGET
|
||||
|
||||
if test $target_cpu = powerpc; then
|
||||
AC_DEFINE([TPUTS_KLUDGE],[1],[Evil kludge to get Power based machines to work])
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED([CPU],[L"$target_cpu"],[CPU type])
|
||||
|
||||
|
||||
# Set up PREFIX and related preprocessor symbols. Fish needs to know
|
||||
# where it will be installed. One of the reasons for this is so that
|
||||
@@ -158,6 +254,12 @@ AC_SUBST( [LOCALEDIR], [$datadir/locale])
|
||||
# information about running processes.
|
||||
AC_CHECK_FILES([/proc/self/stat])
|
||||
|
||||
# This is ued to tell the wgetopt library to translate strings. This
|
||||
# way wgetopt can be dropped into any project without requiring i18n.
|
||||
|
||||
AC_DEFINE([HAVE_TRANSLATE_H], [1],
|
||||
[Define to 1 if the wgettext function should be used for translating strings.])
|
||||
|
||||
# Check for presense of various libraries
|
||||
AC_SEARCH_LIBS( gettext, intl, AC_SUBST( HAVE_GETTEXT, [1] ), AC_SUBST( HAVE_GETTEXT, [0] ) )
|
||||
AC_SEARCH_LIBS( connect, socket, , [AC_MSG_ERROR([Cannot find the socket library, needed to build this package.] )] )
|
||||
@@ -174,7 +276,7 @@ AC_CHECK_HEADER([regex.h],
|
||||
# Check for presense of various functions
|
||||
AC_CHECK_FUNCS( wcsdup wcsndup wcslen wcscasecmp wcsncasecmp gettext fwprintf )
|
||||
AC_CHECK_FUNCS( futimes wcwidth wcswidth getopt_long wcstok fputwc fgetwc )
|
||||
AC_CHECK_FUNCS( wcstol dcgettext )
|
||||
AC_CHECK_FUNCS( wcstol dcgettext wcslcat wcslcpy )
|
||||
|
||||
# Here follows a list of small programs used to test for various
|
||||
# features that Autoconf doesn't tell us about
|
||||
@@ -198,9 +300,10 @@ else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
# If we have a fwprintf in libc, test that it actually works. As of
|
||||
# March 2006, it is broken under Dragonfly BSD.
|
||||
if test "$ac_cv_func_fwprintf" = yes; then
|
||||
|
||||
# Check if fwprintf is broken
|
||||
AC_MSG_CHECKING([if fwprintf is broken])
|
||||
AC_RUN_IFELSE(
|
||||
[AC_LANG_PROGRAM([
|
||||
@@ -223,56 +326,6 @@ if test "$ac_cv_func_fwprintf" = yes; then
|
||||
|
||||
fi
|
||||
|
||||
# Check for RLIMIT_NPROC in sys/resource.h.
|
||||
AC_MSG_CHECKING([for RLIMIT_NPROC in sys/resource.h])
|
||||
AC_TRY_COMPILE([#include <sys/resource.h>],
|
||||
[int tmp; tmp=RLIMIT_NPROC;], have_rlimit_as=yes, have_rlimit_as=no)
|
||||
if test "$have_rlimit_as" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([HAVE_RLIMIT_NPROC], [1],
|
||||
[Define to 1 if HAVE_RLIMIT_NPROC is defined in <sys/resource.h>.])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
# Check for RLIMIT_AS in sys/resource.h.
|
||||
AC_MSG_CHECKING([for RLIMIT_AS in sys/resource.h])
|
||||
AC_TRY_COMPILE([#include <sys/resource.h>],
|
||||
[int tmp; tmp=RLIMIT_AS;], have_rlimit_as=yes, have_rlimit_as=no)
|
||||
if test "$have_rlimit_as" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([HAVE_RLIMIT_AS], [1],
|
||||
[Define to 1 if HAVE_RLIMIT_AS is defined in <sys/resource.h>.])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
# Check for RLIMIT_MEMLOCK in sys/resource.h.
|
||||
AC_MSG_CHECKING([for RLIMIT_MEMLOCK in sys/resource.h])
|
||||
AC_TRY_COMPILE([#include <sys/resource.h>],
|
||||
[int tmp; tmp=RLIMIT_MEMLOCK;], have_rlimit_as=yes, have_rlimit_as=no)
|
||||
if test "$have_rlimit_as" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([HAVE_RLIMIT_MEMLOCK], [1],
|
||||
[Define to 1 if HAVE_RLIMIT_MEMLOCK is defined in <sys/resource.h>.])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
# Check for RLIMIT_RSS in sys/resource.h.
|
||||
AC_MSG_CHECKING([for RLIMIT_RSS in sys/resource.h])
|
||||
AC_TRY_COMPILE([#include <sys/resource.h>],
|
||||
[int tmp; tmp=RLIMIT_RSS;], have_rlimit_as=yes, have_rlimit_as=no)
|
||||
if test "$have_rlimit_as" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([HAVE_RLIMIT_RSS], [1],
|
||||
[Define to 1 if HAVE_RLIMIT_RSS is defined in <sys/resource.h>.])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
AC_DEFINE([HAVE_TRANSLATE_H], [1],
|
||||
[Define to 1 if the wgettext function should be used for translating strings.])
|
||||
|
||||
# Check for _nl_msg_cat_cntr symbol
|
||||
AC_MSG_CHECKING([for _nl_msg_cat_cntr symbol])
|
||||
@@ -289,10 +342,23 @@ else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
# Check if we are using basic BSD curses - in that case we redefine
|
||||
# del_curterm as a no-op, to avoid a double-free
|
||||
|
||||
AC_MSG_CHECKING([If we are using BSD curses])
|
||||
case $target_os in
|
||||
*bsd*)
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_CHECK_LIB( ncurses, del_curterm, true, [AC_DEFINE([HAVE_BROKEN_DEL_CURTERM],[1],[We are using basic BSD curses, redefine del_curterm to a no-op to avoid a double-free bug])])
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT(no)
|
||||
;;
|
||||
esac
|
||||
|
||||
# Tell the world what we know
|
||||
AC_CONFIG_FILES([Makefile fish.spec doc_src/fish.1 doc_src/Doxyfile etc/fish etc/fish_interactive.fish seq])
|
||||
AC_CONFIG_FILES([Makefile fish.spec doc_src/fish.1 doc_src/Doxyfile etc/fish etc/fish_interactive.fish share/fish seq])
|
||||
AC_OUTPUT
|
||||
|
||||
echo "fish is now configured."
|
||||
echo "Now run 'make' and 'make install' to built and install fish."
|
||||
echo "Good luck!"
|
||||
echo "Use 'make' and 'make install' to built and install fish."
|
||||
|
||||
@@ -11,6 +11,22 @@ wildcarded values. The \c case statement is used together with the \c
|
||||
switch statement in order to determine which block should be
|
||||
performed.
|
||||
|
||||
Each \c case command is given one or more parameter. The first \c case
|
||||
command with a parameter that matches the string specified in the
|
||||
switch command will be evaluated. \c case parameters may contain
|
||||
wildcards. These need to be escaped or quoted in order to avoid
|
||||
regular wildcard expansion using filenames.
|
||||
|
||||
Note that fish does not fall through on case statements. Though the
|
||||
syntax may look a bit like C switch statements, it behaves more like
|
||||
the case stamantes of traditional shells.
|
||||
|
||||
Also note that command substitutions in a case statement will be
|
||||
evaluated even if it's body is not taken. This may seem
|
||||
counterintuitive at first, but it is unavoidable, since it would be
|
||||
impossible to know if a case command will evaluate to true before all
|
||||
forms of parameter expansion have been performed for the case command.
|
||||
|
||||
\subsection case-example Example
|
||||
|
||||
If the variable \$animal contains the name of an animal, the following
|
||||
@@ -27,9 +43,11 @@ switch $animal
|
||||
echo bird
|
||||
case shark trout stingray
|
||||
echo fish
|
||||
case '*'
|
||||
echo I have no idea what a $animal is
|
||||
end
|
||||
</pre>
|
||||
</p>
|
||||
<p>
|
||||
If the above code was run with \$animal set to \c whale, the output would be \c mammal.
|
||||
If the above code was run with \c \$animal set to \c whale, the output would be \c mammal.
|
||||
</p>
|
||||
|
||||
168
doc_src/doc.hdr
168
doc_src/doc.hdr
@@ -33,8 +33,9 @@ the manual page for the echo command by writing:
|
||||
|
||||
<code>man echo</code>
|
||||
|
||||
\c man is a command for displaying a manual page on a given
|
||||
topic. There are manual pages for almost every command on most
|
||||
\c man is a command for displaying a manual page on a given topic. The
|
||||
man command takes the name of the manual page to display as an
|
||||
argument. There are manual pages for almost every command on most
|
||||
computers. There are also manual pages for many other things, such as
|
||||
system libraries and important files.
|
||||
|
||||
@@ -48,18 +49,29 @@ has to be used.
|
||||
Here is a list of some useful commands:
|
||||
|
||||
- \c cd, change the current directory
|
||||
- \c ls, list the contents of a directory
|
||||
- \c man, print a manual page
|
||||
- \c mv, move files
|
||||
- \c ls, list files and directories
|
||||
- \c man, display a manual page on the screen
|
||||
- \c mv, move (rename) files
|
||||
- \c cp, copy files
|
||||
- \c open, open files with the default application associated with each filetype
|
||||
- \c less, read the contents of files
|
||||
- \c less, list the contents of files
|
||||
|
||||
Commands and parameters are separated by the space character
|
||||
( ). Every command ends with either a newline (i.e. by pressing
|
||||
the return key) or a semicolon (;). More than one command can be
|
||||
written on the same line by separating them with semicolons.
|
||||
|
||||
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
|
||||
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
|
||||
command though, for example '--help' will usually display a help text,
|
||||
'-i' will often turn on interactive prompting before taking action,
|
||||
while '-f' will turn it off.
|
||||
|
||||
\subsection quotes Quotes
|
||||
|
||||
@@ -104,6 +116,7 @@ these characters, so called escape sequences are provided. These are:
|
||||
- <code>'\\*'</code>, escapes the star character
|
||||
- <code>'\\?'</code>, escapes the question mark character
|
||||
- <code>'\\~'</code>, escapes the tilde character
|
||||
- <code>'\\%'</code>, escapes the percent character
|
||||
- <code>'\\#'</code>, escapes the hash character
|
||||
- <code>'\\('</code>, escapes the left parenthesis character
|
||||
- <code>'\\)'</code>, escapes the right parenthesis character
|
||||
@@ -132,7 +145,7 @@ a number called a file descriptor (FD). These are:
|
||||
The reason for providing for two output file descriptors is to allow
|
||||
separation of errors and warnings from regular program output.
|
||||
|
||||
Any file descriptor can be directed to a different output than it's
|
||||
Any file descriptor can be directed to a different output than its
|
||||
default through a simple mechanism called a redirection.
|
||||
|
||||
An example of a file redirection is <code> echo hello \>output.txt</code>,
|
||||
@@ -200,7 +213,15 @@ When you start a job in \c fish, \c fish itself will pause, and give
|
||||
control of the terminal to the program just started. Sometimes, you
|
||||
want to continue using the commandline, and have the job run in the
|
||||
background. To create a background job, append a \& (ampersand) to
|
||||
your command. This will tell fish to run the job in the background.
|
||||
your command. This will tell fish to run the job in the
|
||||
background. Background jobs are very useful when running programs that
|
||||
have a graphical user interface.
|
||||
|
||||
Example:
|
||||
|
||||
<code>emacs \&</code>
|
||||
|
||||
will start the emacs text editor in the background.
|
||||
|
||||
\subsection syntax-job-control Job control
|
||||
|
||||
@@ -211,16 +232,17 @@ programs and do anything you want. If you then want to go back to the
|
||||
suspended command by using the <a href="builtins.html#fg">fg</a>
|
||||
command.
|
||||
|
||||
If you instead want to put a suspended job into the foreground, use
|
||||
the <a href="builtins.html#fg">fg</a> command.
|
||||
If you instead want to put a suspended job into the background, use
|
||||
the <a href="builtins.html#bg">bg</a> command.
|
||||
|
||||
To get a listing of all currently started jobs, use the <a
|
||||
href="builtins.html#jobs">jobs</a> command.
|
||||
|
||||
\subsection syntax-function Shellscript functions
|
||||
|
||||
Functions are used to group together commands and arguments
|
||||
using a single name. For example, the following is a function
|
||||
Functions are used to group together commands and arguments using a
|
||||
single name. It can also be used to start a specific command with
|
||||
additional arguments. For example, the following is a function
|
||||
definition that calls the command 'ls -l' to print a detailed listing
|
||||
of the contents of the current directory:
|
||||
|
||||
@@ -237,14 +259,14 @@ $argv</code> should be called when ll is invoked. $argv is an array
|
||||
variable, which always contains all arguments sent to the function. In
|
||||
the example above, these are simply passed on to the ls command. For
|
||||
more information on functions, see the documentation for the <a
|
||||
href='builtin.html#function'>function builtin</a>.
|
||||
href='builtin.html#function'>function</a> builtin.
|
||||
|
||||
Functions can be defined on the commandline or in a configuration
|
||||
file, but they can also be automatically loaded. Fish automatically
|
||||
searches through any directories in the array variable
|
||||
\$fish_function_path, and any functions defined are automatically
|
||||
loaded when needed. A function definition file must have a filename
|
||||
consisting of the name of the function and the suffix '.fish'.
|
||||
consisting of the name of the function plus the suffix '.fish'.
|
||||
|
||||
The default value for \$fish_function_path is ~/.fish.d/functions,
|
||||
/etc/fish.d/functions /usr/share/fish/functions. The exact path to the
|
||||
@@ -259,12 +281,13 @@ functions and the last one is for default fish functions.
|
||||
This is a short explanation of some of the commonly used words in fish.
|
||||
|
||||
- argument, a parameter given to a command
|
||||
- builtin, a command that is implemented in the shell
|
||||
- command, a program
|
||||
- function, a block of one or more fish commands that can be called as a single command. By using functions, it is possible to string together multiple smaller commands into one more advanced command.
|
||||
- builtin, a command that is implemented in the shell. Builtins are commands that are so closely tied to the shell that it is impossible to implement them as external commands.
|
||||
- command, a program that the shell can run.
|
||||
- function, a block of commands and arguments that can be called as if they where a single command. By using functions, it is possible to string together multiple smaller commands into one more advanced command.
|
||||
- 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.
|
||||
|
||||
\section help Help
|
||||
|
||||
@@ -466,7 +489,7 @@ becomes explicitly NOT a part of the variable name, even if it happens
|
||||
to be a legal variable name character. That's why '{$USER}san' looks
|
||||
for the variable '$USER' and not for the variable '$USERsan'. It's
|
||||
simply a case of one syntax lending itself nicely to solving an
|
||||
unrelated problem in it's spare time.
|
||||
unrelated problem in its spare time.
|
||||
|
||||
Variable expansion is the only type of expansion performed on double
|
||||
quoted strings. There is, however, an important difference in how
|
||||
@@ -518,6 +541,7 @@ a string is expanded into a process id. The following expansions are
|
||||
performed:
|
||||
|
||||
- If the string is the entire word \c self, the shells pid is the result
|
||||
- When inside a command substitution, if the string is the entire word \c caller, the job number (not the pid) of the job the created the command substitution is the result
|
||||
- Otherwise, if the string is the id of a job, the result is the process
|
||||
group id of the job.
|
||||
- Otherwise, if any child processes match the specified string, their
|
||||
@@ -622,7 +646,7 @@ echo $pirate
|
||||
\subsection variables-universal More on universal variables
|
||||
|
||||
Universal variables are variables that are shared between all the
|
||||
users fish sessions on the computer. Fish stores many of it's
|
||||
users fish sessions on the computer. Fish stores many of its
|
||||
configuration options as universal variables. This means that in order
|
||||
to change fish settings, all you have to do is change the variable
|
||||
value once, and it will be automatically updated for all sessions, and
|
||||
@@ -730,28 +754,68 @@ certain environment variables.
|
||||
|
||||
- \c BROWSER, which is the users preferred web browser. If this variable is set, fish will use the specified browser instead of the system default browser to display the fish documentation.
|
||||
- \c CDPATH, which is an array of directories in which to search for the new directory for the \c cd builtin.
|
||||
- \c fish_color_normal, \c fish_color_command, \c fish_color_substitution, \c fish_color_redirection, \c fish_color_end, \c fish_color_error, \c fish_color_param, \c fish_color_comment, \c fish_color_match, \c fish_color_search_match, \c fish_color_cwd, \c fish_pager_color_prefix, \c fish_pager_color_completion, \c fish_pager_color_description and \c fish_pager_color_progress are used to change the color of various elements in \c fish. These variables are universal, i.e. when changing them, their new value will be used by all running fish sessions. The new value will also be retained when restarting fish.
|
||||
- A large number of variable starting with the prefixes \c fish_color and \c fish_pager_color. See <a href='#variables-color'>Variables for changing highlighting colors</a> for more information.
|
||||
- \c LANG, \c LC_ALL, \c LC_COLLATE, \c LC_CTYPE, \c LC_MESSAGES, \c LC_MONETARY, \c LC_NUMERIC and \c LC_TIME set the language option for the shell and subprograms. See the section <a href='#variables-locale'>Locale variables</a> for more information.
|
||||
- \c PATH, which is an array of directories in which to search for commands
|
||||
- \c umask, which is the current file creation mask. The preferred way to change the umask variable is through the <a href="commands.html#umask">umask shellscript function</a>. An attempt to set umask to an invalid value will always fail.
|
||||
|
||||
\c fish also sends additional information to the user through the
|
||||
values of certain environment variables. The user can not change the
|
||||
values of these variables. They are:
|
||||
values of most of these variables.
|
||||
|
||||
- \c _, which is the name of the currently running command.
|
||||
- \c argv, which is an array of arguments to the shell or function. \c argv is only defined when inside a function call, or if fish was invoked with a list of arguments, like 'fish myscript.fish foo bar'. This variable can be changed by the user.
|
||||
- \c history, which is an array containing the last commands that where entered.
|
||||
- \c HOME, which is the users home directory. This variable can only be changed by the root user.
|
||||
- \c PWD, which is the current working directory.
|
||||
- \c status, which is the exit status of the last foreground job to exit. If a job contains pipelines, the status of the last command in the pipeline is the status for the job.
|
||||
- \c USER, which is the username. This variable can only be changed by the root user.
|
||||
- \c LANG, \c LC_ALL, \c LC_COLLATE, \c LC_CTYPE, \c LC_MESSAGES, \c LC_MONETARY, \c LC_NUMERIC and \c LC_TIME set the language option for the shell and subprograms. See the section <a href='#variables-locale'>Locale variables</a> for more information.
|
||||
|
||||
Variables whose name are in uppercase are exported to the commands
|
||||
started by fish. This rule is not enforced by fish, but it is good
|
||||
coding practice to use casing to distinguish between exported and
|
||||
unexported variables. \c fish also uses several variables
|
||||
internally. Such variables are prefixed with the string __FISH or
|
||||
__fish. These should be ignored by the user.
|
||||
started by fish, those in lowercase are not exported. This rule is not
|
||||
enforced by fish, but it is good coding practice to use casing to
|
||||
distinguish between exported and unexported variables. \c fish also
|
||||
uses several variables internally. Such variables are prefixed with
|
||||
the string __FISH or __fish. These should be ignored by the user.
|
||||
|
||||
\subsection variables-color Variables for changing highlighting colors
|
||||
|
||||
The colors used by fish for syntax highlighting can be configured by
|
||||
changing the values of a various variables. The value of these
|
||||
variables can be one of the colors accepted by the <a
|
||||
href='commands.html#set_color'>\c set_color</a> command. The \c --bold
|
||||
or \c -b switches accepted by \c set_color are also accepted.
|
||||
|
||||
The following variables are available to change the highligting colors
|
||||
in fish:
|
||||
|
||||
- \c fish_color_normal, the default color
|
||||
- \c fish_color_command, the color for commands
|
||||
- \c fish_color_quote, the color for quoted blocks of text
|
||||
- \c fish_color_redirection, the color for IO redirections
|
||||
- \c fish_color_end, the color for process separators like ';' and '&'
|
||||
- \c fish_color_error, the color used to highlight potential errors
|
||||
- \c fish_color_param, the color for regular command parameters
|
||||
- \c fish_color_comment, the color used for code comments
|
||||
- \c fish_color_match, the color used to highlight matching parenthesis
|
||||
- \c fish_color_search_match, the color used to highlight history search matches
|
||||
- \c fish_color_operator, the color for parameter expansion operators like '*' and '~'
|
||||
- \c fish_color_escape, the color used to highlight character escapes like '\\n' and '\\x70'
|
||||
- \c fish_color_cwd, the color used for the current working directory in the default prompt
|
||||
|
||||
Additionally, the following variables are available to change the
|
||||
highlighting in the completion pager:
|
||||
|
||||
- \c fish_pager_color_prefix, the color of the prefix string, i.e. the string that is to be completed
|
||||
- \c fish_pager_color_completion, the color of the completion itself
|
||||
- \c fish_pager_color_description, the color of the completion description
|
||||
- \c fish_pager_color_progress, the color of the progress bar at the bottom left corner
|
||||
|
||||
Example:
|
||||
|
||||
To make errors highlighted and red, use:
|
||||
|
||||
<code>set fish_color_error red --bold</code>D
|
||||
|
||||
\subsection variables-locale Locale variables
|
||||
|
||||
@@ -1003,7 +1067,7 @@ Detected errors include:
|
||||
- Mismatched parenthesis
|
||||
|
||||
When the cursor is over a parenthesis or a quote, \c fish also
|
||||
highlights it's matching quote or parenthesis.
|
||||
highlights its matching quote or parenthesis.
|
||||
|
||||
To customize the syntax highlighting, you can set the environment
|
||||
variables \c fish_color_normal, \c fish_color_command, \c
|
||||
@@ -1045,9 +1109,14 @@ where \c prompt_pwd is a shellscript function that displays a condensed version
|
||||
|
||||
\subsection title Programmable title
|
||||
|
||||
When running in a virtual terminal, the user define the \c fish_title
|
||||
function to print a custom titlebar message. The \c fish_title
|
||||
function is executed and the output is used as a titlebar message.
|
||||
When using most virtual terminals, it is possible to set the message
|
||||
displayed in the titlebar of the terminal window. This can be done
|
||||
automatically in fish by defining the \c fish_title function. The \c
|
||||
fish_title function is executed before and after a new command is
|
||||
executed or put into the foreground and the output is used as a
|
||||
titlebar message. The $_ environment variable will always contain the
|
||||
name of the job to be put into the foreground (Or 'fish' if control is
|
||||
returning to the shell) when the fish_prompt function is called.
|
||||
|
||||
Example:
|
||||
<p>
|
||||
@@ -1089,7 +1158,7 @@ command.
|
||||
|
||||
If you install fish in your home directory, fish will not work
|
||||
correctly for any other user than yourself. This is because fish needs
|
||||
it's initalization files to function properly. To solve this
|
||||
its initalization files to function properly. To solve this
|
||||
problem, either copy the initialization files to each fish users home
|
||||
directory, or install them in /etc.
|
||||
|
||||
@@ -1149,7 +1218,7 @@ msgstr "%ls: Inget passande jobb\n"
|
||||
placeholders. These will be replaced by a value by fish at
|
||||
runtime. You must always take care to use exactly the same
|
||||
placeholders in the same order in your translation. (Actually, there
|
||||
are ways to avoid this, but they are to complicated for this short
|
||||
are ways to avoid this, but they are too complicated for this short
|
||||
introduction. See the full manual for the printf C function for more
|
||||
information.)
|
||||
|
||||
@@ -1169,10 +1238,9 @@ compress, wine, xmms, dig, wine, batch, cron,
|
||||
g++, javac, java, gcj, lpr, doxygen, whois, find)
|
||||
- Undo support
|
||||
- Check keybinding commands for output - if nothing has happened, don't repaint to reduce flicker
|
||||
- The jobs builtin should be able to give information on a specific job, such as the pids of the processes in the job
|
||||
- Syntax highlighting should mark cd to non-existing directories as an error
|
||||
- wait shellscript
|
||||
- Signal handler to save the history file before exiting from a signal
|
||||
- Support for the screen clipboard
|
||||
|
||||
|
||||
\subsection todo-possible Possible features
|
||||
@@ -1190,17 +1258,16 @@ g++, javac, java, gcj, lpr, doxygen, whois, find)
|
||||
- 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
|
||||
- Do not actually load/parse .fish_history, only mmap it and use some clever string handling. Should save ~150 kB of memory permanently, but is very hard to implement.
|
||||
- command specific wildcarding (use case * instead of case '*', etc.)
|
||||
- show the whole list of commands on using tab on an empty commandline
|
||||
- Automatically move cursor to the end of the current token before completing
|
||||
- Map variables. (export only the values. When expanding with no key specified, expand to all values.)
|
||||
- Descriptions for variables using 'set -d'.
|
||||
- Parse errors should when possible honor IO redirections
|
||||
- Support for writing strings like /u/l/b/foo and have them expand to /usr/local/bin/foo - perhaps through tab expansion
|
||||
|
||||
|
||||
\subsection bugs Known bugs
|
||||
|
||||
- Completion for gcc -\#\#\# option doesn't work.
|
||||
- Yanking weird characters from clipboard prints Unicode escapes
|
||||
- Yanking weird characters from the clipboard prints Unicode escapes
|
||||
- Suspending and then resuming pipelines containing a builtin is broken. How should this be handled?
|
||||
|
||||
If you think you have found a bug not described here, please send a
|
||||
@@ -1256,7 +1323,7 @@ Examples:
|
||||
|
||||
- Here documents are too similar to using echo inside of a pipeline.
|
||||
- Subshells, command substitution and process substitution are strongly related. \c fish only supports command substitution, the others can be achived either using a block or the psub shellscript function.
|
||||
- Having both aliases and functions is confusing, especially since both of them have limitations and problems. \c fish sunctions have none of the drawbacks of either syntax.
|
||||
- Having both aliases and functions is confusing, especially since both of them have limitations and problems. \c fish functions have none of the drawbacks of either syntax.
|
||||
- The many Posix quoting styles are silly, especially \$''.
|
||||
|
||||
|
||||
@@ -1349,14 +1416,14 @@ Examples:
|
||||
|
||||
\subsection disc The law of discoverability
|
||||
|
||||
The shell should implement it's features in a way that makes them as
|
||||
easy as possible for the user to discover for her/himself.
|
||||
A program should be designed to make its features as
|
||||
easy as possible to discover for the user.
|
||||
|
||||
Rationale:
|
||||
|
||||
A program whose features are discoverable makes a new user into an
|
||||
expert in a shorter span of time, since the user will learn how to use
|
||||
the program simply by using it.
|
||||
A program whose features are discoverable turns a new user into an
|
||||
expert in a shorter span of time, since the user will become an expert
|
||||
on the program simply by using it.
|
||||
|
||||
The main benefit of a graphical program over a command line-based
|
||||
program is discoverability. In a graphical program, one can discover
|
||||
@@ -1378,8 +1445,8 @@ Examples:
|
||||
/** \page license Licenses
|
||||
|
||||
Fish Copyright (C) 2005 Axel Liljencrantz. Fish is released under the
|
||||
GNU General Public License. The license agreement is included
|
||||
below.
|
||||
GNU General Public License, version 2. The license agreement is
|
||||
included below.
|
||||
|
||||
Fish contains code under the BSD license, namely versions of the
|
||||
two functions strlcat and strlcpy, modified for use with wide
|
||||
@@ -1388,11 +1455,16 @@ license agreement is included below.
|
||||
|
||||
The XSel command, written and copyrighted by Conrad Parker, is
|
||||
distributed together with, and used by fish. It is released under the MIT
|
||||
license. The license agreement is included below.
|
||||
license. The license agreement is included below.
|
||||
|
||||
The xdgmime library, written and copyrighted by Red Hat, Inc, is used
|
||||
by the mimedb command, which is a part of fish. It is released under
|
||||
the LGPL license. The license agreement is included below.
|
||||
the LGPL. The license agreement is included below.
|
||||
|
||||
Fish contains code from the glibc library, namely the wcstok
|
||||
function. This code is licensed under the LGPL. The license agreement
|
||||
is included below.
|
||||
|
||||
|
||||
<HR>
|
||||
|
||||
|
||||
@@ -8,10 +8,13 @@
|
||||
The <tt>read</tt> builtin causes fish to read one line from standard
|
||||
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>-pPROMPT_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>.
|
||||
- <tt>-cCMD</tt> or <tt>--command=CMD</tt> specifies that the initial string in the interactive mode command buffer should be CMD.
|
||||
- <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>-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
|
||||
|
||||
Read starts by reading a single line of input from stdin, the line is
|
||||
then tokenized using the <tt>IFS</tt> environment variable. Each variable
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
\subsection set-synopsis Synopsis
|
||||
<code>set [OPTIONS] [VARIABLE_NAME [VALUES...]]</code>
|
||||
|
||||
or
|
||||
|
||||
<code>set [OPTIONS] [VARIABLE_NAME[INDICES]... [VALUES...]]</code>
|
||||
|
||||
The <code>set</code> builtin causes fish to assign the variable <code>VARIABLE_NAME</code> the values <code>VALUES...</code>.
|
||||
|
||||
\subsection set-description Description
|
||||
@@ -29,7 +33,9 @@ elements, it will become an array with zero elements.
|
||||
|
||||
If the variable name is one or more array elements, such as
|
||||
<code>PATH[1 3 7]</code>, only those array elements specified will be
|
||||
changed.
|
||||
changed. When array indices are specified to set, multiple arguments
|
||||
may be used to specify additional indexes, e.g. <code>set PATH[1]
|
||||
PATH[4] /bin /sbin</code>.
|
||||
|
||||
The set command requires all switch arguments to come before any
|
||||
non-switch arguments. For example, <code>set flags -l</code> will have
|
||||
|
||||
@@ -8,7 +8,19 @@
|
||||
|
||||
The \c switch statement is used to perform one of several blocks of
|
||||
commands depending on whether a specified value equals one of several
|
||||
wildcarded values.
|
||||
wildcarded values. The \c case statement is used together with the \c
|
||||
switch statement in order to determine which block should be
|
||||
performed.
|
||||
|
||||
Each \c case command is given one or more parameter. The first \c case
|
||||
command with a parameter that matches the string specified in the
|
||||
switch command will be evaluated. \c case parameters may contain
|
||||
wildcards. These need to be escaped or quoted in order to avoid
|
||||
regular wildcard expansion using filenames.
|
||||
|
||||
Note that fish does not fall through on case statements. Though the
|
||||
syntax may look a bit like C switch statements, it behaves more like
|
||||
the case stamantes of traditional shells.
|
||||
|
||||
\subsection switch-example Example
|
||||
|
||||
@@ -26,12 +38,14 @@ switch $animal
|
||||
echo bird
|
||||
case shark trout stingray
|
||||
echo fish
|
||||
case '*'
|
||||
echo I have no idea what a $animal is
|
||||
end
|
||||
</pre>
|
||||
</p>
|
||||
<p>
|
||||
|
||||
If the above code was run with \$animal set to \c whale, the output
|
||||
If the above code was run with \c \$animal set to \c whale, the output
|
||||
would be \c mammal.
|
||||
|
||||
</p>
|
||||
|
||||
50
env.c
50
env.c
@@ -104,7 +104,7 @@ typedef struct env_node
|
||||
typedef struct var_entry
|
||||
{
|
||||
int export; /**< Whether the variable should be exported */
|
||||
wchar_t val[0]; /**< The value of the variable */
|
||||
wchar_t val[1]; /**< The value of the variable */
|
||||
}
|
||||
var_entry_t;
|
||||
|
||||
@@ -396,7 +396,7 @@ static void setup_path()
|
||||
al_init( &l );
|
||||
|
||||
if( path )
|
||||
expand_variable_array( path, &l );
|
||||
tokenize_variable_array( path, &l );
|
||||
|
||||
for( j=0; path_el[j]; j++ )
|
||||
{
|
||||
@@ -438,7 +438,7 @@ static void setup_path()
|
||||
al_foreach( &l, (void (*)(const void *))&free );
|
||||
path = env_get( L"PATH" );
|
||||
al_truncate( &l, 0 );
|
||||
expand_variable_array( path, &l );
|
||||
tokenize_variable_array( path, &l );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -608,9 +608,9 @@ static env_node_t *env_get_node( const wchar_t *key )
|
||||
return 0;
|
||||
}
|
||||
|
||||
void env_set( const wchar_t *key,
|
||||
const wchar_t *val,
|
||||
int var_mode )
|
||||
int env_set( const wchar_t *key,
|
||||
const wchar_t *val,
|
||||
int var_mode )
|
||||
{
|
||||
int free_val = 0;
|
||||
var_entry_t *entry;
|
||||
@@ -626,7 +626,7 @@ void env_set( const wchar_t *key,
|
||||
if( (var_mode & ENV_USER ) &&
|
||||
hash_get( &env_read_only, key ) )
|
||||
{
|
||||
return;
|
||||
return ENV_PERM;
|
||||
}
|
||||
|
||||
if( wcscmp( key, L"umask" ) == 0)
|
||||
@@ -650,7 +650,7 @@ void env_set( const wchar_t *key,
|
||||
/*
|
||||
Do not actually create a umask variable, on env_get, it will be calculated dynamically
|
||||
*/
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -749,7 +749,7 @@ void env_set( const wchar_t *key,
|
||||
node = top;
|
||||
while( node->next && !node->new_scope )
|
||||
node = node->next;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -797,6 +797,7 @@ void env_set( const wchar_t *key,
|
||||
|
||||
al_init( &ev.arguments );
|
||||
al_push( &ev.arguments, L"VARIABLE" );
|
||||
al_push( &ev.arguments, L"SET" );
|
||||
al_push( &ev.arguments, key );
|
||||
|
||||
// debug( 1, L"env_set: fire events on variable %ls", key );
|
||||
@@ -809,25 +810,33 @@ void env_set( const wchar_t *key,
|
||||
{
|
||||
handle_locale();
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Attempt to remove/free the specified key/value pair from the
|
||||
specified hash table.
|
||||
|
||||
\return zero if the variable was not found, non-zero otherwise
|
||||
*/
|
||||
static int try_remove( env_node_t *n,
|
||||
const wchar_t *key )
|
||||
{
|
||||
const void *old_key_void, *old_val_void;
|
||||
wchar_t *old_key, *old_val;
|
||||
if( n == 0 )
|
||||
return 0;
|
||||
|
||||
hash_remove( &n->env,
|
||||
key,
|
||||
(const void **)&old_key,
|
||||
(const void **)&old_val );
|
||||
&old_key_void,
|
||||
&old_val_void );
|
||||
|
||||
old_key = (wchar_t *)old_key_void;
|
||||
old_val = (wchar_t *)old_val_void;
|
||||
|
||||
if( old_key != 0 )
|
||||
{
|
||||
var_entry_t * v = (var_entry_t *)old_val;
|
||||
@@ -856,7 +865,22 @@ void env_remove( const wchar_t *key, int var_mode )
|
||||
return;
|
||||
}
|
||||
|
||||
if( !try_remove( top, key ) )
|
||||
if( try_remove( top, key ) )
|
||||
{
|
||||
event_t ev;
|
||||
|
||||
ev.type=EVENT_VARIABLE;
|
||||
ev.param1.variable=key;
|
||||
ev.function_name=0;
|
||||
|
||||
al_init( &ev.arguments );
|
||||
al_push( &ev.arguments, L"VARIABLE" );
|
||||
al_push( &ev.arguments, L"ERASE" );
|
||||
al_push( &ev.arguments, key );
|
||||
event_fire( &ev );
|
||||
al_destroy( &ev.arguments );
|
||||
}
|
||||
else
|
||||
{
|
||||
env_universal_remove( key );
|
||||
}
|
||||
|
||||
13
env.h
13
env.h
@@ -41,6 +41,11 @@
|
||||
*/
|
||||
#define ENV_UNIVERSAL 32
|
||||
|
||||
/**
|
||||
Error code for trying to alter read-only variable
|
||||
*/
|
||||
#define ENV_PERM 1
|
||||
|
||||
/**
|
||||
Initialize environment variable data
|
||||
*/
|
||||
@@ -61,9 +66,15 @@ void env_destroy();
|
||||
\param val The value
|
||||
\param mode The type of the variable. Can be any combination of ENV_GLOBAL, ENV_LOCAL, ENV_EXPORT and ENV_USER. If mode is zero, the current variable space is searched and the current mode is used. If no current variable with the same name is found, ENV_LOCAL is assumed.
|
||||
|
||||
\returns 0 on suicess or an error code on failiure.
|
||||
|
||||
The current error codes are:
|
||||
|
||||
* ENV_PERM, can only be returned when setting as a user, e.g. ENV_USER is set. This means that the user tried to change a read-only variable.
|
||||
|
||||
*/
|
||||
|
||||
void env_set( const wchar_t *key,
|
||||
int env_set( const wchar_t *key,
|
||||
const wchar_t *val,
|
||||
int mode );
|
||||
|
||||
|
||||
53
etc/fish.in
53
etc/fish.in
@@ -4,7 +4,7 @@
|
||||
# @configure_input@
|
||||
|
||||
#
|
||||
# Set default search paths
|
||||
# Set default search paths for completions and shellscript functions
|
||||
#
|
||||
|
||||
set -g fish_function_path ~/.fish.d/functions @SYSCONFDIR@/fish.d/functions @DATADIR@/fish/functions
|
||||
@@ -17,39 +17,40 @@ set -g fish_complete_path ~/.fish.d/completions @SYSCONFDIR@/fish.d/completions
|
||||
set -g IFS \ \t\n
|
||||
|
||||
#
|
||||
# Add a few common directories to path, if they exists. Note that pure
|
||||
# console programs like makedep sometimes live in /usr/X11R6/bin, so we
|
||||
# want this even for text-only terminals.
|
||||
# Some things should only be done for login terminals
|
||||
#
|
||||
|
||||
set -l path_list /bin /usr/bin /usr/X11R6/bin @PREFIX@/bin @optbindirs@
|
||||
if status --is-login
|
||||
|
||||
# Root should also have the sbin directories in the path
|
||||
if test "$USER" = root
|
||||
set path_list $path_list /sbin /usr/sbin /usr/local/sbin
|
||||
end
|
||||
#
|
||||
# Set some value for LANG if nothing was set before, and this is a
|
||||
# login shell.
|
||||
#
|
||||
|
||||
for i in $path_list
|
||||
if not expr "$PATH" : .\*$i.\* >/dev/null
|
||||
if test -d $i
|
||||
set PATH $PATH $i
|
||||
if not set -q LANG >/dev/null
|
||||
set -gx LANG en_US.UTF-8
|
||||
end
|
||||
|
||||
# Check for i18n information in
|
||||
# /etc/sysconfig/i18n
|
||||
|
||||
if test -f /etc/sysconfig/i18n
|
||||
eval (cat /etc/sysconfig/i18n |sed -ne 's/^\([a-zA-Z]*\)=\(.*\)$/set -gx \1 \2;/p')
|
||||
end
|
||||
|
||||
#
|
||||
# Put linux consoles in unicode mode.
|
||||
#
|
||||
|
||||
if expr "$LANG" : ".*\.[Uu][Tt][Ff].*" >/dev/null
|
||||
if test "$TERM" = linux
|
||||
if which unicode_start >/dev/null
|
||||
unicode_start
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Put linux console in unicode mode. Should this be done in any other
|
||||
# situation as well?
|
||||
#
|
||||
|
||||
if expr "$LANG" : ".*[Uu][Tt][Ff]" >/dev/null
|
||||
if test linux = "$TERM"
|
||||
unicode_start ^/dev/null
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# There are variables that contain colons that are not arrays. This
|
||||
# reverts them back to regular strings.
|
||||
|
||||
@@ -42,7 +42,7 @@ end
|
||||
|
||||
|
||||
#
|
||||
# Set various color values
|
||||
# Set various defaults using these throwaway functions
|
||||
#
|
||||
|
||||
function set_default -d "Set an universal variable, unless it has already been set"
|
||||
@@ -68,8 +68,11 @@ end
|
||||
set_default fish_color_normal normal
|
||||
set_default fish_color_command green
|
||||
set_default fish_color_redirection normal
|
||||
set_default fish_color_comment brown
|
||||
set_default fish_color_error red
|
||||
set_default fish_color_comment red
|
||||
set_default fish_color_error red --bold
|
||||
set_default fish_color_escape cyan
|
||||
set_default fish_color_operator cyan
|
||||
set_default fish_color_quote brown
|
||||
|
||||
set_default fish_color_cwd green
|
||||
|
||||
@@ -85,7 +88,10 @@ set_default fish_pager_color_completion normal
|
||||
set_default fish_pager_color_description normal
|
||||
set_default fish_pager_color_progress cyan
|
||||
|
||||
#
|
||||
# Directory history colors
|
||||
#
|
||||
|
||||
set_default fish_color_history_current cyan
|
||||
|
||||
|
||||
@@ -96,7 +102,7 @@ set_default fish_color_history_current cyan
|
||||
set_default CDPATH . ~
|
||||
|
||||
#
|
||||
# Remove temporary functions
|
||||
# Remove temporary functions for setting default variable values
|
||||
#
|
||||
|
||||
functions -e set_exported_default
|
||||
|
||||
13
event.c
13
event.c
@@ -57,7 +57,7 @@ typedef struct
|
||||
active, which is the one that new events is written to. The inactive
|
||||
one contains the events that are currently beeing performed.
|
||||
*/
|
||||
static signal_list_t sig_list[2];
|
||||
static signal_list_t sig_list[]={{0,0},{0,0}};
|
||||
|
||||
/**
|
||||
The index of sig_list that is the list of signals currently written to
|
||||
@@ -273,9 +273,12 @@ void event_remove( event_t *criterion )
|
||||
event_t e;
|
||||
|
||||
/*
|
||||
Because of concurrency issues, env_remove does not actually free
|
||||
any events - instead it simply moves all events that should be
|
||||
removed from the event list to the killme list.
|
||||
Because of concurrency issues (env_remove could remove an event
|
||||
that is currently being executed), env_remove does not actually
|
||||
free any events - instead it simply moves all events that should
|
||||
be removed from the event list to the killme list, and the ones
|
||||
that shouldn't be killed to new_list, and then drops the empty
|
||||
events-list.
|
||||
*/
|
||||
|
||||
if( !events )
|
||||
@@ -617,7 +620,6 @@ void event_fire( event_t *event )
|
||||
|
||||
void event_init()
|
||||
{
|
||||
sig_list[active_list].count=0;
|
||||
}
|
||||
|
||||
void event_destroy()
|
||||
@@ -653,3 +655,4 @@ void event_free( event_t *e )
|
||||
free( (void *)e->param1.variable );
|
||||
free( e );
|
||||
}
|
||||
|
||||
|
||||
37
exec.c
37
exec.c
@@ -126,7 +126,7 @@ int exec_pipe( int fd[2])
|
||||
|
||||
if( open_fds == 0 )
|
||||
{
|
||||
open_fds = al_new();
|
||||
open_fds = al_halloc( global_context );
|
||||
}
|
||||
|
||||
al_push( open_fds, (void *)(long)fd[0] );
|
||||
@@ -164,7 +164,8 @@ static int use_fd_in_pipe( int fd, io_data_t *io )
|
||||
the redirection list io. This should make sure that there are no
|
||||
stray opened file descriptors in the child.
|
||||
|
||||
\param io the list of io redirections for this job. Pipes mentioned here should not be closed.
|
||||
\param io the list of io redirections for this job. Pipes mentioned
|
||||
here should not be closed.
|
||||
*/
|
||||
static void close_unused_internal_pipes( io_data_t *io )
|
||||
{
|
||||
@@ -185,20 +186,6 @@ static void close_unused_internal_pipes( io_data_t *io )
|
||||
}
|
||||
}
|
||||
|
||||
void exec_init()
|
||||
{
|
||||
}
|
||||
|
||||
void exec_destroy()
|
||||
{
|
||||
if( open_fds )
|
||||
{
|
||||
al_destroy( open_fds );
|
||||
free( open_fds );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Make sure the fd used by this redirection is not used by i.e. a pipe.
|
||||
*/
|
||||
@@ -564,7 +551,7 @@ static void internal_exec_helper( const wchar_t *def,
|
||||
io_data_t *io_internal = io_transmogrify( io );
|
||||
int is_block_old=is_block;
|
||||
is_block=1;
|
||||
|
||||
|
||||
/*
|
||||
Did the transmogrification fail - if so, set error status and return
|
||||
*/
|
||||
@@ -575,7 +562,7 @@ static void internal_exec_helper( const wchar_t *def,
|
||||
}
|
||||
|
||||
signal_unblock();
|
||||
|
||||
|
||||
eval( def, io_internal, block_type );
|
||||
|
||||
signal_block();
|
||||
@@ -653,8 +640,6 @@ void exec( job_t *j )
|
||||
pid_t pid;
|
||||
int mypipe[2];
|
||||
sigset_t chldset;
|
||||
sigemptyset( &chldset );
|
||||
sigaddset( &chldset, SIGCHLD );
|
||||
int skip_fork;
|
||||
|
||||
io_data_t pipe_read, pipe_write;
|
||||
@@ -667,6 +652,11 @@ void exec( job_t *j )
|
||||
*/
|
||||
int exec_error=0;
|
||||
|
||||
if( no_exec )
|
||||
return;
|
||||
|
||||
sigemptyset( &chldset );
|
||||
sigaddset( &chldset, SIGCHLD );
|
||||
|
||||
debug( 4, L"Exec job '%ls' with id %d", j->command, j->job_id );
|
||||
|
||||
@@ -834,7 +824,7 @@ void exec( job_t *j )
|
||||
io_buffer = io_buffer_create();
|
||||
j->io = io_add( j->io, io_buffer );
|
||||
}
|
||||
|
||||
|
||||
internal_exec_helper( p->argv[0], TOP, j->io );
|
||||
break;
|
||||
|
||||
@@ -849,6 +839,7 @@ void exec( job_t *j )
|
||||
if( p == j->first_process )
|
||||
{
|
||||
io_data_t *in = io_get( j->io, 0 );
|
||||
|
||||
if( in )
|
||||
{
|
||||
switch( in->io_mode )
|
||||
@@ -1206,14 +1197,12 @@ void exec( job_t *j )
|
||||
{
|
||||
proc_last_bg_pid = j->pgid;
|
||||
}
|
||||
|
||||
|
||||
if( !exec_error )
|
||||
{
|
||||
job_continue (j, 0);
|
||||
}
|
||||
|
||||
debug( 3, L"End of exec()" );
|
||||
|
||||
}
|
||||
|
||||
int exec_subshell( const wchar_t *cmd,
|
||||
|
||||
11
exec.h
11
exec.h
@@ -18,17 +18,6 @@
|
||||
*/
|
||||
#define PIPE_ERROR _(L"An error occurred while setting up pipe")
|
||||
|
||||
/**
|
||||
Initialize the exec library
|
||||
*/
|
||||
void exec_init();
|
||||
|
||||
/**
|
||||
Destroy dynamically allocated data and other resources used by the
|
||||
exec library
|
||||
*/
|
||||
void exec_destroy();
|
||||
|
||||
/**
|
||||
Execute the processes specified by j.
|
||||
|
||||
|
||||
188
expand.c
188
expand.c
@@ -76,27 +76,6 @@ parameter expansion.
|
||||
*/
|
||||
#define COMPLETE_LAST_DESC _( L"Last background job")
|
||||
|
||||
/**
|
||||
Error issued on invalid variable name
|
||||
*/
|
||||
#define COMPLETE_VAR_DESC _( L"The '$' character begins a variable name. The character '%lc', which directly followed a '$', is not allowed as a part of a variable name, and variable names may not be zero characters long. To learn more about variable expansion in fish, type 'help expand-variable'.")
|
||||
|
||||
/**
|
||||
Error issued on invalid variable name
|
||||
*/
|
||||
#define COMPLETE_VAR_NULL_DESC _( L"The '$' begins a variable name. It was given at the end of an argument. Variable names may not be zero characters long. To learn more about variable expansion in fish, type 'help expand-variable'.")
|
||||
|
||||
/**
|
||||
Error issued on invalid variable name
|
||||
*/
|
||||
#define COMPLETE_VAR_BRACKET_DESC _( L"Did you mean {$VARIABLE}? The '$' character begins a variable name. A bracket, which directly followed a '$', is not allowed as a part of a variable name, and variable names may not be zero characters long. To learn more about variable expansion in fish, type 'help expand-variable'." )
|
||||
|
||||
/**
|
||||
Error issued on invalid variable name
|
||||
*/
|
||||
#define COMPLETE_VAR_PARAN_DESC _( L"Did you mean (COMMAND)? In fish, the '$' character is only used for accessing variables. To learn more about command substitution in fish, type 'help expand-command-substitution'.")
|
||||
|
||||
|
||||
/**
|
||||
String in process expansion denoting ourself
|
||||
*/
|
||||
@@ -117,15 +96,7 @@ parameter expansion.
|
||||
*/
|
||||
#define UNCLEAN L"$*?\\\"'({})"
|
||||
|
||||
/**
|
||||
Test if the specified argument is clean, i.e. it does not contain
|
||||
any tokens which need to be expanded or otherwise altered. Clean
|
||||
strings can be passed through expand_string and expand_one without
|
||||
changing them. About 90% of all strings are clean, so skipping
|
||||
expansion on them actually does save a small amount of time, since
|
||||
it avoids multiple memory allocations during the expansion process.
|
||||
*/
|
||||
static int is_clean( const wchar_t *in )
|
||||
int expand_is_clean( const wchar_t *in )
|
||||
{
|
||||
|
||||
const wchar_t * str = in;
|
||||
@@ -159,32 +130,6 @@ static wchar_t *expand_var( wchar_t *in )
|
||||
return env_get( in );
|
||||
}
|
||||
|
||||
void expand_variable_array( const wchar_t *val, array_list_t *out )
|
||||
{
|
||||
if( val )
|
||||
{
|
||||
wchar_t *cpy = wcsdup( val );
|
||||
wchar_t *pos, *start;
|
||||
|
||||
if( !cpy )
|
||||
{
|
||||
die_mem();
|
||||
}
|
||||
|
||||
for( start=pos=cpy; *pos; pos++ )
|
||||
{
|
||||
if( *pos == ARRAY_SEP )
|
||||
{
|
||||
*pos=0;
|
||||
al_push( out, start==cpy?cpy:wcsdup(start) );
|
||||
start=pos+1;
|
||||
}
|
||||
}
|
||||
al_push( out, start==cpy?cpy:wcsdup(start) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Test if the specified string does not contain character which can
|
||||
not be used inside a quoted string.
|
||||
@@ -217,7 +162,7 @@ wchar_t *expand_escape_variable( const wchar_t *in )
|
||||
string_buffer_t buff;
|
||||
|
||||
al_init( &l );
|
||||
expand_variable_array( in, &l );
|
||||
tokenize_variable_array( in, &l );
|
||||
sb_init( &buff );
|
||||
|
||||
switch( al_get_count( &l) )
|
||||
@@ -225,7 +170,7 @@ wchar_t *expand_escape_variable( const wchar_t *in )
|
||||
case 0:
|
||||
sb_append( &buff, L"''");
|
||||
break;
|
||||
|
||||
|
||||
case 1:
|
||||
{
|
||||
wchar_t *el = (wchar_t *)al_get( &l, 0 );
|
||||
@@ -281,28 +226,19 @@ wchar_t *expand_escape_variable( const wchar_t *in )
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Tests if all characters in the string are numeric
|
||||
*/
|
||||
static int isnumeric( const char *n )
|
||||
{
|
||||
if( *n == '\0' )
|
||||
return 1;
|
||||
if( *n < '0' || *n > '9' )
|
||||
return 0;
|
||||
return isnumeric( n+1 );
|
||||
}
|
||||
|
||||
/**
|
||||
Tests if all characters in the wide string are numeric
|
||||
*/
|
||||
static int iswnumeric( const wchar_t *n )
|
||||
{
|
||||
if( *n == L'\0' )
|
||||
return 1;
|
||||
if( *n < L'0' || *n > L'9' )
|
||||
return 0;
|
||||
return iswnumeric( n+1 );
|
||||
for( ; *n; n++ )
|
||||
{
|
||||
if( *n < L'0' || *n > L'9' )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -377,9 +313,9 @@ static int find_process( const wchar_t *proc,
|
||||
array_list_t *out )
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *next;
|
||||
char *pdir_name;
|
||||
char *pfile_name;
|
||||
struct wdirent *next;
|
||||
wchar_t *pdir_name;
|
||||
wchar_t *pfile_name;
|
||||
wchar_t *cmd=0;
|
||||
int sz=0;
|
||||
int found = 0;
|
||||
@@ -421,17 +357,18 @@ static int find_process( const wchar_t *proc,
|
||||
{
|
||||
|
||||
int jid = wcstol( proc, 0, 10 );
|
||||
|
||||
j = job_get( jid );
|
||||
if( (j != 0) && (j->command != 0 ) )
|
||||
if( jid > 0 )
|
||||
{
|
||||
|
||||
j = job_get( jid );
|
||||
if( (j != 0) && (j->command != 0 ) )
|
||||
{
|
||||
result = malloc(sizeof(wchar_t)*16 );
|
||||
swprintf( result, 16, L"%d", j->pgid );
|
||||
//fwprintf( stderr, L"pid %d %ls\n", j->pgid, result );
|
||||
al_push( out, result );
|
||||
found = 1;
|
||||
|
||||
{
|
||||
result = malloc(sizeof(wchar_t)*16 );
|
||||
swprintf( result, 16, L"%d", j->pgid );
|
||||
al_push( out, result );
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -441,12 +378,9 @@ static int find_process( const wchar_t *proc,
|
||||
|
||||
for( j=first_job; j != 0; j=j->next )
|
||||
{
|
||||
// fwprintf( stderr, L"..." );
|
||||
if( j->command == 0 )
|
||||
continue;
|
||||
|
||||
// fwprintf( stderr, L"match '%ls' '%ls'\n\n\n", j->command, proc );
|
||||
|
||||
if( match_pid( j->command, proc, flags ) )
|
||||
{
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
@@ -455,8 +389,6 @@ static int find_process( const wchar_t *proc,
|
||||
COMPLETE_SEP_STR,
|
||||
COMPLETE_JOB_DESC,
|
||||
(void *)0 );
|
||||
// fwprintf( stderr, L"Woot %ls\n", res );
|
||||
|
||||
al_push( out, res );
|
||||
}
|
||||
else
|
||||
@@ -482,12 +414,9 @@ static int find_process( const wchar_t *proc,
|
||||
for( p=j->first_process; p; p=p->next )
|
||||
{
|
||||
|
||||
// fwprintf( stderr, L"..." );
|
||||
if( p->actual_cmd == 0 )
|
||||
continue;
|
||||
|
||||
// fwprintf( stderr, L"match '%ls' '%ls'\n\n\n", j->command, proc );
|
||||
|
||||
if( match_pid( p->actual_cmd, proc, flags ) )
|
||||
{
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
@@ -522,20 +451,20 @@ static int find_process( const wchar_t *proc,
|
||||
return 1;
|
||||
}
|
||||
|
||||
pdir_name = malloc( 256 );
|
||||
pfile_name = malloc( 64 );
|
||||
strcpy( pdir_name, "/proc/" );
|
||||
|
||||
while( (next=readdir(dir))!=0 )
|
||||
pdir_name = malloc( sizeof(wchar_t)*256 );
|
||||
pfile_name = malloc( sizeof(wchar_t)*64 );
|
||||
wcscpy( pdir_name, L"/proc/" );
|
||||
|
||||
while( (next=wreaddir(dir))!=0 )
|
||||
{
|
||||
char *name = next->d_name;
|
||||
wchar_t *name = next->d_name;
|
||||
struct stat buf;
|
||||
|
||||
if( !isnumeric( name ) )
|
||||
if( !iswnumeric( name ) )
|
||||
continue;
|
||||
|
||||
strcpy( pdir_name + 6, name );
|
||||
if( stat( pdir_name, &buf ) )
|
||||
wcscpy( pdir_name + 6, name );
|
||||
if( wstat( pdir_name, &buf ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -543,17 +472,17 @@ static int find_process( const wchar_t *proc,
|
||||
{
|
||||
continue;
|
||||
}
|
||||
strcpy( pfile_name, pdir_name );
|
||||
strcat( pfile_name, "/cmdline" );
|
||||
wcscpy( pfile_name, pdir_name );
|
||||
wcscat( pfile_name, L"/cmdline" );
|
||||
|
||||
if( !stat( pfile_name, &buf ) )
|
||||
if( !wstat( pfile_name, &buf ) )
|
||||
{
|
||||
/*
|
||||
the 'cmdline' file exists, it should contain the commandline
|
||||
*/
|
||||
FILE *cmdfile;
|
||||
|
||||
if((cmdfile=fopen( pfile_name, "r" ))==0)
|
||||
if((cmdfile=wfopen( pfile_name, "r" ))==0)
|
||||
{
|
||||
wperror( L"fopen" );
|
||||
continue;
|
||||
@@ -568,15 +497,15 @@ static int find_process( const wchar_t *proc,
|
||||
else
|
||||
{
|
||||
#ifdef SunOS
|
||||
strcpy( pfile_name, pdir_name );
|
||||
strcat( pfile_name, "/psinfo" );
|
||||
if( !stat( pfile_name, &buf ) )
|
||||
wcscpy( pfile_name, pdir_name );
|
||||
wcscat( pfile_name, L"/psinfo" );
|
||||
if( !wstat( pfile_name, &buf ) )
|
||||
{
|
||||
psinfo_t info;
|
||||
|
||||
FILE *psfile;
|
||||
|
||||
if((psfile=fopen( pfile_name, "r" ))==0)
|
||||
if((psfile=wfopen( pfile_name, "r" ))==0)
|
||||
{
|
||||
wperror( L"fopen" );
|
||||
continue;
|
||||
@@ -615,7 +544,7 @@ static int find_process( const wchar_t *proc,
|
||||
}
|
||||
else
|
||||
{
|
||||
wchar_t *res = str2wcs(name);
|
||||
wchar_t *res = wcsdup(name);
|
||||
if( res )
|
||||
al_push( out, res );
|
||||
}
|
||||
@@ -687,27 +616,22 @@ static int expand_pid( wchar_t *in,
|
||||
}
|
||||
}
|
||||
|
||||
// fwprintf( stderr, L"expand_pid() %ls\n", in );
|
||||
int prev = al_get_count( out );
|
||||
if( !find_process( in+1, flags, out ) )
|
||||
return 0;
|
||||
|
||||
if( prev == al_get_count( out ) )
|
||||
{
|
||||
// fwprintf( stderr, L"no match\n" );
|
||||
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
free( in );
|
||||
else
|
||||
{
|
||||
*in = L'%';
|
||||
// fwprintf( stderr, L"return %ls\n", in );
|
||||
al_push( out, in );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// fwprintf( stderr, L"match\n" );
|
||||
free( in );
|
||||
}
|
||||
|
||||
@@ -816,8 +740,7 @@ static int expand_variables( wchar_t *in, array_list_t *out, int last_idx )
|
||||
{
|
||||
error( SYNTAX_ERROR,
|
||||
-1,
|
||||
COMPLETE_VAR_NULL_DESC,
|
||||
in[stop_pos] );
|
||||
COMPLETE_VAR_NULL_DESC );
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -885,7 +808,7 @@ static int expand_variables( wchar_t *in, array_list_t *out, int last_idx )
|
||||
|
||||
if( is_ok )
|
||||
{
|
||||
expand_variable_array( var_val, &var_item_list );
|
||||
tokenize_variable_array( var_val, &var_item_list );
|
||||
if( !all_vars )
|
||||
{
|
||||
int j;
|
||||
@@ -967,7 +890,7 @@ static int expand_variables( wchar_t *in, array_list_t *out, int last_idx )
|
||||
else
|
||||
{
|
||||
|
||||
wcsncpy( new_in, in, start_pos-1 );
|
||||
wcslcpy( new_in, in, start_pos );
|
||||
|
||||
if(start_pos>1 && new_in[start_pos-2]!=VARIABLE_EXPAND)
|
||||
{
|
||||
@@ -980,7 +903,6 @@ static int expand_variables( wchar_t *in, array_list_t *out, int last_idx )
|
||||
wcscat( new_in, next );
|
||||
wcscat( new_in, &in[stop_pos] );
|
||||
|
||||
// fwprintf( stderr, L"New value %ls\n", new_in );
|
||||
is_ok &= expand_variables( new_in, out, i );
|
||||
}
|
||||
}
|
||||
@@ -1059,9 +981,6 @@ static int expand_brackets( wchar_t *in, int flags, array_list_t *out )
|
||||
wchar_t *item_begin;
|
||||
int len1, len2, tot_len;
|
||||
|
||||
// fwprintf( stderr, L"expand %ls\n", in );
|
||||
|
||||
|
||||
for( pos=in;
|
||||
(!bracket_end) && (*pos) && !syntax_error;
|
||||
pos++ )
|
||||
@@ -1153,8 +1072,8 @@ static int expand_brackets( wchar_t *in, int flags, array_list_t *out )
|
||||
int item_len = pos-item_begin;
|
||||
|
||||
whole_item = malloc( sizeof(wchar_t)*(tot_len + item_len + 1) );
|
||||
wcsncpy( whole_item, in, len1 );
|
||||
wcsncpy( whole_item+len1, item_begin, item_len );
|
||||
wcslcpy( whole_item, in, len1+1 );
|
||||
wcslcpy( whole_item+len1, item_begin, item_len+1 );
|
||||
wcscpy( whole_item+len1+item_len, bracket_end+1 );
|
||||
|
||||
expand_brackets( whole_item, flags, out );
|
||||
@@ -1234,7 +1153,7 @@ static int expand_subshell( wchar_t *in, array_list_t *out )
|
||||
return 0;
|
||||
}
|
||||
|
||||
wcsncpy( subcmd, paran_begin+1, paran_end-paran_begin-1 );
|
||||
wcslcpy( subcmd, paran_begin+1, paran_end-paran_begin );
|
||||
subcmd[ paran_end-paran_begin-1]=0;
|
||||
|
||||
if( exec_subshell( subcmd, &sub_res)==-1 )
|
||||
@@ -1310,7 +1229,6 @@ static wchar_t * expand_tilde_internal( wchar_t *in )
|
||||
wchar_t *new_in=0;
|
||||
wchar_t *old_in=0;
|
||||
|
||||
// fwprintf( stderr, L"Tilde expand ~%ls\n", (*ptr)+1 );
|
||||
if( in[1] == '/' || in[1] == '\0' )
|
||||
{
|
||||
/* Current users home directory */
|
||||
@@ -1420,7 +1338,6 @@ static void remove_internal_separator( const void *s, int conv )
|
||||
*out=0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
The real expansion function. expand_one is just a wrapper around this one.
|
||||
*/
|
||||
@@ -1437,10 +1354,7 @@ int expand_string( void *context,
|
||||
int res = EXPAND_OK;
|
||||
int start_count = al_get_count( end_out );
|
||||
|
||||
// debug( 1, L"Expand %ls", str );
|
||||
|
||||
|
||||
if( (!(flags & ACCEPT_INCOMPLETE)) && is_clean( str ) )
|
||||
if( (!(flags & ACCEPT_INCOMPLETE)) && expand_is_clean( str ) )
|
||||
{
|
||||
halloc_register( context, str );
|
||||
al_push( end_out, str );
|
||||
@@ -1685,8 +1599,8 @@ wchar_t *expand_one( void *context, wchar_t *string, int flags )
|
||||
array_list_t l;
|
||||
int res;
|
||||
wchar_t *one;
|
||||
|
||||
if( (!(flags & ACCEPT_INCOMPLETE)) && is_clean( string ) )
|
||||
|
||||
if( (!(flags & ACCEPT_INCOMPLETE)) && expand_is_clean( string ) )
|
||||
{
|
||||
halloc_register( context, string );
|
||||
return string;
|
||||
|
||||
36
expand.h
36
expand.h
@@ -112,6 +112,27 @@ enum
|
||||
/** String containing the character for separating two array elements */
|
||||
#define ARRAY_SEP_STR L"\x1e"
|
||||
|
||||
/**
|
||||
Error issued on invalid variable name
|
||||
*/
|
||||
#define COMPLETE_VAR_DESC _( L"The '$' character begins a variable name. The character '%lc', which directly followed a '$', is not allowed as a part of a variable name, and variable names may not be zero characters long. To learn more about variable expansion in fish, type 'help expand-variable'.")
|
||||
|
||||
/**
|
||||
Error issued on invalid variable name
|
||||
*/
|
||||
#define COMPLETE_VAR_NULL_DESC _( L"The '$' begins a variable name. It was given at the end of an argument. Variable names may not be zero characters long. To learn more about variable expansion in fish, type 'help expand-variable'.")
|
||||
|
||||
/**
|
||||
Error issued on invalid variable name
|
||||
*/
|
||||
#define COMPLETE_VAR_BRACKET_DESC _( L"Did you mean {$VARIABLE}? The '$' character begins a variable name. A bracket, which directly followed a '$', is not allowed as a part of a variable name, and variable names may not be zero characters long. To learn more about variable expansion in fish, type 'help expand-variable'." )
|
||||
|
||||
/**
|
||||
Error issued on invalid variable name
|
||||
*/
|
||||
#define COMPLETE_VAR_PARAN_DESC _( L"Did you mean (COMMAND)? In fish, the '$' character is only used for accessing variables. To learn more about command substitution in fish, type 'help expand-command-substitution'.")
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@@ -158,13 +179,14 @@ wchar_t *expand_tilde(wchar_t *in);
|
||||
|
||||
|
||||
/**
|
||||
Tokenize the specified string into the specified array_list_t.
|
||||
Each new element is allocated using malloc and must be freed by the
|
||||
caller.
|
||||
|
||||
\param val the input string. The contents of this string is not changed.
|
||||
\param out the list in which to place the elements.
|
||||
Test if the specified argument is clean, i.e. it does not contain
|
||||
any tokens which need to be expanded or otherwise altered. Clean
|
||||
strings can be passed through expand_string and expand_one without
|
||||
changing them. About two thirds of all strings are clean, so
|
||||
skipping expansion on them actually does save a small amount of
|
||||
time, since it avoids multiple memory allocations during the
|
||||
expansion process.
|
||||
*/
|
||||
void expand_variable_array( const wchar_t *val, array_list_t *out );
|
||||
int expand_is_clean( const wchar_t *in );
|
||||
|
||||
#endif
|
||||
|
||||
124
fallback.c
124
fallback.c
@@ -38,17 +38,17 @@
|
||||
#include <ncurses/term.h>
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
#include "fallback.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
#ifdef TPUTS_KLUDGE
|
||||
|
||||
int tputs(const char *str, int affcnt, int (*putc)(tputs_arg_t))
|
||||
int tputs(const char *str, int affcnt, int (*fish_putc)(tputs_arg_t))
|
||||
{
|
||||
while( *str )
|
||||
{
|
||||
putc( *str++ );
|
||||
fish_putc( *str++ );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -818,8 +818,7 @@ wchar_t *wcsndup( const wchar_t *in, int c )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
wcsncpy( res, in, c+1 );
|
||||
res[c] = L'\0';
|
||||
wcslcpy( res, in, c+1 );
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
@@ -888,6 +887,121 @@ long wcstol(const wchar_t *nptr,
|
||||
nptr++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifndef HAVE_WCSLCAT
|
||||
|
||||
/*$OpenBSD: strlcat.c,v 1.11 2003/06/17 21:56:24 millert Exp $*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
size_t
|
||||
wcslcat(wchar_t *dst, const wchar_t *src, size_t siz)
|
||||
{
|
||||
|
||||
register wchar_t *d = dst;
|
||||
register const wchar_t *s = src;
|
||||
register size_t n = siz;
|
||||
size_t dlen;
|
||||
|
||||
/* Find the end of dst and adjust bytes left but don't go past end */
|
||||
while (n-- != 0 && *d != '\0')
|
||||
d++;
|
||||
|
||||
dlen = d - dst;
|
||||
n = siz - dlen;
|
||||
|
||||
if (n == 0)
|
||||
return(dlen + wcslen(s));
|
||||
|
||||
while (*s != '\0')
|
||||
{
|
||||
if (n != 1)
|
||||
{
|
||||
*d++ = *s;
|
||||
n--;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
*d = '\0';
|
||||
|
||||
return(dlen + (s - src));
|
||||
/* count does not include NUL */
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifndef HAVE_WCSLCPY
|
||||
|
||||
/*$OpenBSD: strlcpy.c,v 1.8 2003/06/17 21:56:24 millert Exp $*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
size_t
|
||||
wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz)
|
||||
{
|
||||
register wchar_t *d = dst;
|
||||
register const wchar_t *s = src;
|
||||
register size_t n = siz;
|
||||
|
||||
/* Copy as many bytes as will fit */
|
||||
if (n != 0 && --n != 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
if ((*d++ = *s++) == 0)
|
||||
break;
|
||||
}
|
||||
while (--n != 0);
|
||||
}
|
||||
|
||||
/* Not enough room in dst, add NUL and traverse rest of src */
|
||||
if (n == 0)
|
||||
{
|
||||
if (siz != 0)
|
||||
*d = '\0';
|
||||
/* NUL-terminate dst */
|
||||
while (*s++)
|
||||
;
|
||||
}
|
||||
return(s - src - 1);
|
||||
/* count does not include NUL */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BROKEN_DEL_CURTERM
|
||||
|
||||
int del_curterm(TERMINAL *oterm)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
120
fallback.h
120
fallback.h
@@ -3,26 +3,43 @@
|
||||
#define FISH_FALLBACK_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <wctype.h>
|
||||
#include <wchar.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef WCHAR_MAX
|
||||
/**
|
||||
This _should_ be defined by wchar.h, but e.g. OpenBSD doesn't.
|
||||
*/
|
||||
#define WCHAR_MAX INT_MAX
|
||||
#endif
|
||||
|
||||
/**
|
||||
Under curses, tputs expects an int (*func)(char) as its last
|
||||
parameter, but in ncurses, tputs expects a int (*func)(int) as its
|
||||
last parameter. tputs_arg_t is defined to always be what tputs
|
||||
expects. Hopefully.
|
||||
*/
|
||||
|
||||
#ifdef NCURSES_VERSION
|
||||
typedef int tputs_arg_t;
|
||||
#else
|
||||
typedef char tputs_arg_t;
|
||||
#endif
|
||||
|
||||
#ifdef TPUTS_KLUDGE
|
||||
|
||||
|
||||
/**
|
||||
Linux on PPC seems to have a tputs implementation that sometimes
|
||||
behaves strangely. This fallback seems to fix things.
|
||||
*/
|
||||
int tputs(const char *str, int affcnt, int (*putc)(tputs_arg_t));
|
||||
int tputs(const char *str, int affcnt, int (*fish_putc)(tputs_arg_t));
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
Here follows the prototypes for fallback implementations of various
|
||||
standarcs libc functions relating to wide character support. Some of
|
||||
these prototypes are always defined, since some libc versions
|
||||
include the code, but you have to use special magical #defines for
|
||||
the prototype to appear.
|
||||
*/
|
||||
#ifndef HAVE_FWPRINTF
|
||||
|
||||
/**
|
||||
Print formated string. Some operating systems (Like NetBSD) do not
|
||||
@@ -79,6 +96,9 @@ int vfwprintf( FILE *f, const wchar_t *filter, va_list va );
|
||||
*/
|
||||
int vswprintf( wchar_t *out, size_t n, const wchar_t *filter, va_list va );
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FGETWC
|
||||
/**
|
||||
Fallback implementation of fgetwc
|
||||
*/
|
||||
@@ -89,6 +109,10 @@ wint_t fgetwc(FILE *stream);
|
||||
*/
|
||||
wint_t getwc(FILE *stream);
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FPUTWC
|
||||
|
||||
/**
|
||||
Fallback implementation of fputwc
|
||||
*/
|
||||
@@ -98,11 +122,18 @@ wint_t fputwc(wchar_t wc, FILE *stream);
|
||||
*/
|
||||
wint_t putwc(wchar_t wc, FILE *stream);
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCSTOK
|
||||
|
||||
/**
|
||||
Fallback implementation of wcstok. Uses code borrowed from glibc.
|
||||
*/
|
||||
wchar_t *wcstok(wchar_t *wcs, const wchar_t *delim, wchar_t **ptr);
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCWIDTH
|
||||
|
||||
/**
|
||||
Return the number of columns used by a character. This is a libc
|
||||
@@ -117,14 +148,28 @@ wchar_t *wcstok(wchar_t *wcs, const wchar_t *delim, wchar_t **ptr);
|
||||
*/
|
||||
int wcwidth( wchar_t c );
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCSDUP
|
||||
|
||||
/**
|
||||
Create a duplicate string. Wide string version of strdup. Will
|
||||
automatically exit if out of memory.
|
||||
*/
|
||||
wchar_t *wcsdup(const wchar_t *in);
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCSLEN
|
||||
|
||||
/**
|
||||
Fallback for wcsen. Returns the length of the specified string.
|
||||
*/
|
||||
size_t wcslen(const wchar_t *in);
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCSCASECMP
|
||||
/**
|
||||
Case insensitive string compare function. Wide string version of
|
||||
strcasecmp.
|
||||
@@ -138,6 +183,10 @@ size_t wcslen(const wchar_t *in);
|
||||
*/
|
||||
int wcscasecmp( const wchar_t *a, const wchar_t *b );
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCSNCASECMP
|
||||
|
||||
/**
|
||||
Case insensitive string compare function. Wide string version of
|
||||
strncasecmp.
|
||||
@@ -157,14 +206,28 @@ int wcsncasecmp( const wchar_t *a, const wchar_t *b, int count );
|
||||
always null terminated, and the null is not included in the string
|
||||
length.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCSNDUP
|
||||
|
||||
/**
|
||||
Fallback for wcsndup function. Returns a copy of \c in, truncated
|
||||
to a maximum length of \c c.
|
||||
*/
|
||||
wchar_t *wcsndup( const wchar_t *in, int c );
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
Converts from wide char to digit in the specified base. If d is not
|
||||
a valid digit in the specified base, return -1.
|
||||
a valid digit in the specified base, return -1. This is a helper
|
||||
function for wcstol, but it is useful itself, so it is exported.
|
||||
*/
|
||||
long convert_digit( wchar_t d, int base );
|
||||
|
||||
#ifndef HAVE_WCSTOL
|
||||
|
||||
/**
|
||||
Fallback implementation. Convert a wide character string to a
|
||||
number in the specified base. This functions is the wide character
|
||||
@@ -177,6 +240,43 @@ long wcstol(const wchar_t *nptr,
|
||||
wchar_t **endptr,
|
||||
int base);
|
||||
|
||||
#endif
|
||||
#ifndef HAVE_WCSLCAT
|
||||
|
||||
/**
|
||||
Appends src to string dst of size siz (unlike wcsncat, siz is the
|
||||
full size of dst, not space left). At most siz-1 characters will be
|
||||
copied. Always NUL terminates (unless siz <= wcslen(dst)). Returns
|
||||
wcslen(src) + MIN(siz, wcslen(initial dst)). If retval >= siz,
|
||||
truncation occurred.
|
||||
|
||||
This is the OpenBSD strlcat function, modified for wide characters,
|
||||
and renamed to reflect this change.
|
||||
|
||||
*/
|
||||
size_t wcslcat( wchar_t *dst, const wchar_t *src, size_t siz );
|
||||
|
||||
#endif
|
||||
#ifndef HAVE_WCSLCPY
|
||||
|
||||
/**
|
||||
Copy src to string dst of size siz. At most siz-1 characters will
|
||||
be copied. Always NUL terminates (unless siz == 0). Returns
|
||||
wcslen(src); if retval >= siz, truncation occurred.
|
||||
|
||||
This is the OpenBSD strlcpy function, modified for wide characters,
|
||||
and renamed to reflect this change.
|
||||
*/
|
||||
size_t wcslcpy( wchar_t *dst, const wchar_t *src, size_t siz );
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BROKEN_DEL_CURTERM
|
||||
|
||||
/**
|
||||
BSD del_curterm seems to do a double-free. We redefine it as a no-op
|
||||
*/
|
||||
int del_curterm(TERMINAL *oterm);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
%define xinclude %( if test -d /usr/X11R6/include; then echo /usr/X11R6/include; else echo /usr/include; fi )
|
||||
|
||||
Summary: A friendly interactive shell
|
||||
Name: @PACKAGE_NAME@
|
||||
|
||||
@@ -11,8 +13,9 @@ URL: http://roo.no-ip.org/fish/
|
||||
Source0: http://roo.no-ip.org/%{name}/files/%{version}/%{name}-%{version}.tar.bz2
|
||||
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
BuildRequires: doxygen ncurses-devel xorg-x11-devel
|
||||
|
||||
BuildRequires: doxygen ncurses-devel
|
||||
BuildRequires: %{xinclude}/X11/StringDefs.h, %{xinclude}/X11/Xlib.h
|
||||
BuildRequires: %{xinclude}/X11/Intrinsic.h, %{xinclude}/X11/Xatom.h
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -990,9 +990,12 @@ int main( int argc, char **argv )
|
||||
|
||||
fwprintf( out_file, L"%ls", (wchar_t *)out_buff.buff );
|
||||
if( is_ca_mode )
|
||||
{
|
||||
writembs(exit_ca_mode);
|
||||
pager_flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
destroy();
|
||||
}
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ static int pq_compare( void *e1, void *e2 )
|
||||
/**
|
||||
Test priority queue functionality
|
||||
*/
|
||||
static int pq_test( int elements )
|
||||
static void pq_test( int elements )
|
||||
{
|
||||
int i;
|
||||
int prev;
|
||||
@@ -290,7 +290,7 @@ static int hash_test( int elements )
|
||||
/**
|
||||
Arraylist test
|
||||
*/
|
||||
static int al_test( int sz)
|
||||
static void al_test( int sz)
|
||||
{
|
||||
int i;
|
||||
array_list_t l;
|
||||
@@ -690,7 +690,6 @@ int main( int argc, char **argv )
|
||||
proc_init();
|
||||
halloc_util_init();
|
||||
event_init();
|
||||
exec_init();
|
||||
parser_init();
|
||||
function_init();
|
||||
builtin_init();
|
||||
@@ -718,7 +717,6 @@ int main( int argc, char **argv )
|
||||
builtin_destroy();
|
||||
complete_destroy();
|
||||
wutil_destroy();
|
||||
exec_destroy();
|
||||
event_destroy();
|
||||
proc_destroy();
|
||||
halloc_util_destroy();
|
||||
|
||||
9
fishd.c
9
fishd.c
@@ -110,6 +110,11 @@ time the original barrier request was sent have been received.
|
||||
*/
|
||||
#define LOCKTIMEOUT 1
|
||||
|
||||
/**
|
||||
Getopt short switches for fishd
|
||||
*/
|
||||
#define GETOPT_STRING "hv"
|
||||
|
||||
/**
|
||||
The list of connections to clients
|
||||
*/
|
||||
@@ -502,14 +507,14 @@ int main( int argc, char ** argv )
|
||||
|
||||
int opt = getopt_long( argc,
|
||||
argv,
|
||||
"hv",
|
||||
GETOPT_STRING,
|
||||
long_options,
|
||||
&opt_index );
|
||||
|
||||
#else
|
||||
int opt = getopt( argc,
|
||||
argv,
|
||||
"hv" );
|
||||
GETOPT_STRING );
|
||||
#endif
|
||||
if( opt == -1 )
|
||||
break;
|
||||
|
||||
45
function.c
45
function.c
@@ -87,7 +87,7 @@ static void autoload_names( array_list_t *out, int get_hidden )
|
||||
|
||||
al_init( &path_list );
|
||||
|
||||
expand_variable_array( path_var, &path_list );
|
||||
tokenize_variable_array( path_var, &path_list );
|
||||
for( i=0; i<al_get_count( &path_list ); i++ )
|
||||
{
|
||||
wchar_t *ndir = (wchar_t *)al_get( &path_list, i );
|
||||
@@ -195,14 +195,17 @@ int function_exists( const wchar_t *cmd )
|
||||
void function_remove( const wchar_t *name )
|
||||
{
|
||||
void *key;
|
||||
const void *dv;
|
||||
function_data_t *d;
|
||||
event_t ev;
|
||||
|
||||
hash_remove( &function,
|
||||
name,
|
||||
(const void **) &key,
|
||||
(const void **)&d );
|
||||
&dv );
|
||||
|
||||
d=(function_data_t *)dv;
|
||||
|
||||
if( !key )
|
||||
return;
|
||||
|
||||
@@ -245,6 +248,19 @@ void function_set_desc( const wchar_t *name, const wchar_t *desc )
|
||||
data->desc =wcsdup(desc);
|
||||
}
|
||||
|
||||
static int al_contains_str( array_list_t *list, const wchar_t * str )
|
||||
{
|
||||
int i;
|
||||
for( i=0; i<al_get_count( list ); i++ )
|
||||
{
|
||||
if( wcscmp( al_get( list, i ), str) == 0 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Helper function for removing hidden functions
|
||||
*/
|
||||
@@ -255,8 +271,25 @@ static void get_names_internal( const void *key,
|
||||
wchar_t *name = (wchar_t *)key;
|
||||
function_data_t *f = (function_data_t *)val;
|
||||
|
||||
if( name[0] != L'_' && !f->is_binding)
|
||||
if( name[0] != L'_' && !f->is_binding && !al_contains_str( (array_list_t *)aux, name ) )
|
||||
{
|
||||
al_push( (array_list_t *)aux, name );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Helper function for removing hidden functions
|
||||
*/
|
||||
static void get_names_internal_all( const void *key,
|
||||
const void *val,
|
||||
void *aux )
|
||||
{
|
||||
wchar_t *name = (wchar_t *)key;
|
||||
|
||||
if( !al_contains_str( (array_list_t *)aux, name ) )
|
||||
{
|
||||
al_push( (array_list_t *)aux, name );
|
||||
}
|
||||
}
|
||||
|
||||
void function_get_names( array_list_t *list, int get_hidden )
|
||||
@@ -264,9 +297,13 @@ void function_get_names( array_list_t *list, int get_hidden )
|
||||
autoload_names( list, get_hidden );
|
||||
|
||||
if( get_hidden )
|
||||
hash_get_keys( &function, list );
|
||||
{
|
||||
hash_foreach2( &function, &get_names_internal_all, list );
|
||||
}
|
||||
else
|
||||
{
|
||||
hash_foreach2( &function, &get_names_internal, list );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
8
halloc.c
8
halloc.c
@@ -41,7 +41,7 @@ typedef struct halloc
|
||||
|
||||
static halloc_t *halloc_from_data( void *data )
|
||||
{
|
||||
return (halloc_t *)(data - sizeof( halloc_t ) );
|
||||
return (halloc_t *)(((char *)data) - sizeof( halloc_t ) );
|
||||
}
|
||||
|
||||
static void late_free( void *data)
|
||||
@@ -83,7 +83,7 @@ void *halloc( void *context, size_t size )
|
||||
{
|
||||
res = parent->scratch;
|
||||
parent->scratch_free -= size;
|
||||
parent->scratch += size;
|
||||
parent->scratch = ((char *)parent->scratch)+size;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -98,7 +98,7 @@ void *halloc( void *context, size_t size )
|
||||
alloc_spill += parent->scratch_free;
|
||||
#endif
|
||||
res = calloc( 1, size + HALLOC_BLOCK_SIZE );
|
||||
parent->scratch = res + size;
|
||||
parent->scratch = (char *)res + size;
|
||||
parent->scratch_free = HALLOC_BLOCK_SIZE;
|
||||
}
|
||||
else
|
||||
@@ -121,7 +121,7 @@ void *halloc( void *context, size_t size )
|
||||
#ifdef HALLOC_DEBUG
|
||||
parent_count++;
|
||||
#endif
|
||||
me->scratch = ((void *)me) + sizeof(halloc_t) + size;
|
||||
me->scratch = ((char *)me) + sizeof(halloc_t) + size;
|
||||
me->scratch_free = HALLOC_BLOCK_SIZE;
|
||||
|
||||
al_init( &me->children );
|
||||
|
||||
308
highlight.c
308
highlight.c
@@ -40,11 +40,10 @@ static void highlight_universal_internal( wchar_t * buff,
|
||||
/**
|
||||
The environment variables used to specify the color of different tokens.
|
||||
*/
|
||||
static wchar_t *hightlight_var[] =
|
||||
static wchar_t *highlight_var[] =
|
||||
{
|
||||
L"fish_color_normal",
|
||||
L"fish_color_command",
|
||||
L"fish_color_subshell",
|
||||
L"fish_color_redirection",
|
||||
L"fish_color_end",
|
||||
L"fish_color_error",
|
||||
@@ -52,24 +51,24 @@ static wchar_t *hightlight_var[] =
|
||||
L"fish_color_comment",
|
||||
L"fish_color_match",
|
||||
L"fish_color_search_match",
|
||||
L"fish_color_pager_prefix",
|
||||
L"fish_color_pager_completion",
|
||||
L"fish_color_pager_description",
|
||||
L"fish_color_pager_progress"
|
||||
L"fish_color_operator",
|
||||
L"fish_color_escape",
|
||||
L"fish_color_quote"
|
||||
}
|
||||
;
|
||||
|
||||
#define VAR_COUNT ( sizeof(highlight_var)/sizeof(wchar_t *) )
|
||||
|
||||
int highlight_get_color( int highlight )
|
||||
{
|
||||
if( highlight < 0 )
|
||||
return FISH_COLOR_NORMAL;
|
||||
if( highlight >= (12) )
|
||||
if( highlight >= VAR_COUNT )
|
||||
return FISH_COLOR_NORMAL;
|
||||
|
||||
wchar_t *val = env_get( hightlight_var[highlight]);
|
||||
wchar_t *val = env_get( highlight_var[highlight]);
|
||||
if( val == 0 )
|
||||
val = env_get( hightlight_var[HIGHLIGHT_NORMAL]);
|
||||
val = env_get( highlight_var[HIGHLIGHT_NORMAL]);
|
||||
|
||||
if( val == 0 )
|
||||
{
|
||||
@@ -79,6 +78,289 @@ int highlight_get_color( int highlight )
|
||||
return output_color_code( val );
|
||||
}
|
||||
|
||||
/**
|
||||
Highligt operators (such as $, ~, %, as well as escaped characters.
|
||||
*/
|
||||
static void highlight_param( const wchar_t * buff,
|
||||
int *color,
|
||||
int pos,
|
||||
array_list_t *error )
|
||||
{
|
||||
|
||||
|
||||
int mode = 0;
|
||||
int in_pos, len = wcslen( buff );
|
||||
int bracket_count=0;
|
||||
wchar_t c;
|
||||
|
||||
for( in_pos=0;
|
||||
in_pos<len;
|
||||
in_pos++ )
|
||||
{
|
||||
c = buff[in_pos];
|
||||
switch( mode )
|
||||
{
|
||||
|
||||
/*
|
||||
Mode 0 means unquoted string
|
||||
*/
|
||||
case 0:
|
||||
{
|
||||
if( c == L'\\' )
|
||||
{
|
||||
int start_pos = in_pos;
|
||||
in_pos++;
|
||||
|
||||
if( wcschr( L"~%", buff[in_pos] ) )
|
||||
{
|
||||
if( in_pos == 1 )
|
||||
{
|
||||
color[start_pos] = HIGHLIGHT_ESCAPE;
|
||||
color[in_pos+1] = HIGHLIGHT_NORMAL;
|
||||
}
|
||||
}
|
||||
else if( buff[in_pos]==L',' )
|
||||
{
|
||||
if( bracket_count )
|
||||
{
|
||||
color[start_pos] = HIGHLIGHT_ESCAPE;
|
||||
color[in_pos+1] = HIGHLIGHT_NORMAL;
|
||||
}
|
||||
}
|
||||
else if( wcschr( L"nrtbe*?$(){}'\"<>^ \\#;|&", buff[in_pos] ) )
|
||||
{
|
||||
color[start_pos]=HIGHLIGHT_ESCAPE;
|
||||
color[in_pos+1]=HIGHLIGHT_NORMAL;
|
||||
}
|
||||
else if( wcschr( L"uUxX01234567", buff[in_pos] ) )
|
||||
{
|
||||
int i;
|
||||
long long res=0;
|
||||
int chars=2;
|
||||
int base=16;
|
||||
|
||||
int byte = 0;
|
||||
wchar_t max_val = ASCII_MAX;
|
||||
|
||||
switch( buff[in_pos] )
|
||||
{
|
||||
case L'u':
|
||||
{
|
||||
chars=4;
|
||||
max_val = UCS2_MAX;
|
||||
break;
|
||||
}
|
||||
|
||||
case L'U':
|
||||
{
|
||||
chars=8;
|
||||
max_val = WCHAR_MAX;
|
||||
break;
|
||||
}
|
||||
|
||||
case L'x':
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
case L'X':
|
||||
{
|
||||
byte=1;
|
||||
max_val = BYTE_MAX;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
base=8;
|
||||
chars=3;
|
||||
in_pos--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for( i=0; i<chars; i++ )
|
||||
{
|
||||
int d = convert_digit( buff[++in_pos],base);
|
||||
|
||||
if( d < 0 )
|
||||
{
|
||||
in_pos--;
|
||||
break;
|
||||
}
|
||||
|
||||
res=(res*base)|d;
|
||||
}
|
||||
|
||||
if( (res <= max_val) )
|
||||
{
|
||||
color[start_pos] = HIGHLIGHT_ESCAPE;
|
||||
color[in_pos+1] = HIGHLIGHT_NORMAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
color[start_pos] = HIGHLIGHT_ERROR;
|
||||
color[in_pos+1] = HIGHLIGHT_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( buff[in_pos]){
|
||||
case L'~':
|
||||
case L'%':
|
||||
{
|
||||
if( in_pos == 0 )
|
||||
{
|
||||
color[in_pos] = HIGHLIGHT_OPERATOR;
|
||||
color[in_pos+1] = HIGHLIGHT_NORMAL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case L'*':
|
||||
case L'?':
|
||||
case L'$':
|
||||
case L'(':
|
||||
case L')':
|
||||
{
|
||||
color[in_pos] = HIGHLIGHT_OPERATOR;
|
||||
color[in_pos+1] = HIGHLIGHT_NORMAL;
|
||||
break;
|
||||
}
|
||||
|
||||
case L'{':
|
||||
{
|
||||
color[in_pos] = HIGHLIGHT_OPERATOR;
|
||||
color[in_pos+1] = HIGHLIGHT_NORMAL;
|
||||
bracket_count++;
|
||||
break;
|
||||
}
|
||||
|
||||
case L'}':
|
||||
{
|
||||
color[in_pos] = HIGHLIGHT_OPERATOR;
|
||||
color[in_pos+1] = HIGHLIGHT_NORMAL;
|
||||
bracket_count--;
|
||||
break;
|
||||
}
|
||||
|
||||
case L',':
|
||||
{
|
||||
if( bracket_count )
|
||||
{
|
||||
color[in_pos] = HIGHLIGHT_OPERATOR;
|
||||
color[in_pos+1] = HIGHLIGHT_NORMAL;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case L'\'':
|
||||
{
|
||||
color[in_pos] = HIGHLIGHT_QUOTE;
|
||||
mode = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case L'\"':
|
||||
{
|
||||
color[in_pos] = HIGHLIGHT_QUOTE;
|
||||
mode = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
Mode 1 means single quoted string, i.e 'foo'
|
||||
*/
|
||||
case 1:
|
||||
{
|
||||
if( c == L'\\' )
|
||||
{
|
||||
int start_pos = in_pos;
|
||||
switch( buff[++in_pos] )
|
||||
{
|
||||
case '\\':
|
||||
case L'\'':
|
||||
{
|
||||
color[start_pos] = HIGHLIGHT_ESCAPE;
|
||||
color[in_pos+1] = HIGHLIGHT_QUOTE;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0:
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if( c == L'\'' )
|
||||
{
|
||||
mode = 0;
|
||||
color[in_pos+1] = HIGHLIGHT_NORMAL;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
Mode 2 means double quoted string, i.e. "foo"
|
||||
*/
|
||||
case 2:
|
||||
{
|
||||
switch( c )
|
||||
{
|
||||
case '"':
|
||||
{
|
||||
mode = 0;
|
||||
color[in_pos+1] = HIGHLIGHT_NORMAL;
|
||||
break;
|
||||
}
|
||||
|
||||
case '\\':
|
||||
{
|
||||
int start_pos = in_pos;
|
||||
switch( buff[++in_pos] )
|
||||
{
|
||||
case L'\0':
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
case '\\':
|
||||
case L'$':
|
||||
case '"':
|
||||
{
|
||||
color[start_pos] = HIGHLIGHT_ESCAPE;
|
||||
color[in_pos+1] = HIGHLIGHT_QUOTE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case '$':
|
||||
{
|
||||
color[in_pos] = HIGHLIGHT_OPERATOR;
|
||||
color[in_pos+1] = HIGHLIGHT_QUOTE;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void highlight_shell( wchar_t * buff,
|
||||
int *color,
|
||||
@@ -125,6 +407,12 @@ void highlight_shell( wchar_t * buff,
|
||||
{
|
||||
color[ tok_get_pos( &tok ) ] = HIGHLIGHT_PARAM;
|
||||
}
|
||||
|
||||
highlight_param( param,
|
||||
&color[tok_get_pos( &tok )],
|
||||
pos-tok_get_pos( &tok ),
|
||||
error );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -383,7 +671,7 @@ void highlight_shell( wchar_t * buff,
|
||||
*end=0;
|
||||
|
||||
highlight_shell( begin+1, color +(begin-buffcpy)+1, -1, error );
|
||||
color[end-buffcpy]=HIGHLIGHT_PARAM;
|
||||
color[end-buffcpy]=HIGHLIGHT_OPERATOR;
|
||||
|
||||
if( done )
|
||||
break;
|
||||
|
||||
@@ -202,6 +202,10 @@ static void history_to_hash()
|
||||
{
|
||||
history_data *d;
|
||||
|
||||
if( !history_last )
|
||||
return;
|
||||
|
||||
|
||||
d = (history_data *)hash_get( &history_table,
|
||||
mode_name );
|
||||
|
||||
@@ -291,7 +295,7 @@ static void history_save()
|
||||
history_count=0;
|
||||
past_end=1;
|
||||
|
||||
history_load( mode_name );
|
||||
history_load();
|
||||
if( real_pos != 0 )
|
||||
{
|
||||
/*
|
||||
|
||||
21
input.c
21
input.c
@@ -119,7 +119,8 @@ const wchar_t *name_arr[] =
|
||||
L"history-token-search-backward",
|
||||
L"history-token-search-forward",
|
||||
L"self-insert",
|
||||
L"null"
|
||||
L"null",
|
||||
L"eof"
|
||||
}
|
||||
;
|
||||
|
||||
@@ -155,7 +156,8 @@ const wchar_t *desc_arr[] =
|
||||
L"Search backward through list of previous commands for matching token",
|
||||
L"Search forward through list of previous commands for matching token",
|
||||
L"Insert the pressed key",
|
||||
L"Do nothing"
|
||||
L"Do nothing",
|
||||
L"End of file"
|
||||
}
|
||||
;
|
||||
|
||||
@@ -191,7 +193,8 @@ const wchar_t code_arr[] =
|
||||
R_HISTORY_TOKEN_SEARCH_BACKWARD,
|
||||
R_HISTORY_TOKEN_SEARCH_FORWARD,
|
||||
R_SELF_INSERT,
|
||||
R_NULL
|
||||
R_NULL,
|
||||
R_EOF
|
||||
}
|
||||
;
|
||||
|
||||
@@ -228,6 +231,8 @@ static int inputrc_block_count=0;
|
||||
*/
|
||||
static int inputrc_error = 0;
|
||||
|
||||
static int is_init = 0;
|
||||
|
||||
wchar_t input_get_code( wchar_t *name )
|
||||
{
|
||||
|
||||
@@ -1346,6 +1351,11 @@ int input_init()
|
||||
{
|
||||
wchar_t *fn;
|
||||
|
||||
if( is_init )
|
||||
return 1;
|
||||
|
||||
is_init = 1;
|
||||
|
||||
input_common_init( &interrupt_handler );
|
||||
|
||||
if( setupterm( 0, STDOUT_FILENO, 0) == ERR )
|
||||
@@ -1424,6 +1434,11 @@ static void destroy_mapping( const void *key, const void *val )
|
||||
|
||||
void input_destroy()
|
||||
{
|
||||
if( !is_init )
|
||||
return;
|
||||
|
||||
is_init=0;
|
||||
|
||||
input_common_destroy();
|
||||
|
||||
hash_foreach( &all_mappings, &destroy_mapping );
|
||||
|
||||
3
input.h
3
input.h
@@ -9,6 +9,7 @@ inputrc information for key bindings.
|
||||
#define FISH_INPUT_H
|
||||
|
||||
#include <wchar.h>
|
||||
#include "input_common.h"
|
||||
|
||||
/**
|
||||
Key codes for inputrc-style keyboard functions that are passed on
|
||||
@@ -16,7 +17,7 @@ inputrc information for key bindings.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
R_BEGINNING_OF_LINE = R_NULL+1,
|
||||
R_BEGINNING_OF_LINE = R_NULL+10, /* This give input_common ten slots for lowlevel keycodes */
|
||||
R_END_OF_LINE,
|
||||
R_FORWARD_CHAR,
|
||||
R_BACKWARD_CHAR,
|
||||
|
||||
@@ -64,7 +64,7 @@ static wint_t readb()
|
||||
{
|
||||
unsigned char arr[1];
|
||||
int do_loop = 0;
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
fd_set fd;
|
||||
@@ -89,28 +89,25 @@ static wint_t readb()
|
||||
case EINTR:
|
||||
case EAGAIN:
|
||||
{
|
||||
// wperror( L"select" );
|
||||
if( interrupt_handler )
|
||||
{
|
||||
int res = interrupt_handler();
|
||||
|
||||
/* debug( 0,
|
||||
L"interrupt, %d is %ls",
|
||||
res,
|
||||
(res==R_NULL?L"good": L"Bad") );
|
||||
*/
|
||||
if( res )
|
||||
{
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
do_loop = 1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
debug( 0, L"Error while reading input from keyboard, shutting down" );
|
||||
wperror(L"read");
|
||||
exit(1);
|
||||
/*
|
||||
The teminal has been closed. Save and exit.
|
||||
*/
|
||||
return R_EOF;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,17 +119,17 @@ static wint_t readb()
|
||||
{
|
||||
debug( 3, L"Wake up on universal variable event" );
|
||||
env_universal_read_all();
|
||||
debug( 3, L"Return R_NULL" );
|
||||
return R_NULL;
|
||||
do_loop = 1;
|
||||
}
|
||||
}
|
||||
if( FD_ISSET( 0, &fd ) )
|
||||
{
|
||||
if( read_blocked( 0, arr, 1 ) == -1 )
|
||||
if( read_blocked( 0, arr, 1 ) != 1 )
|
||||
{
|
||||
debug( 0, L"Error while reading input from keyboard, shutting down" );
|
||||
wperror(L"read");
|
||||
exit(1);
|
||||
/*
|
||||
The teminal has been closed. Save and exit.
|
||||
*/
|
||||
return R_EOF;
|
||||
}
|
||||
do_loop = 0;
|
||||
}
|
||||
@@ -143,6 +140,7 @@ static wint_t readb()
|
||||
return arr[0];
|
||||
}
|
||||
|
||||
|
||||
wchar_t input_common_readch( int timed )
|
||||
{
|
||||
if( lookahead_count == 0 )
|
||||
@@ -186,8 +184,8 @@ wchar_t input_common_readch( int timed )
|
||||
|
||||
int sz;
|
||||
|
||||
if( b == R_NULL )
|
||||
return R_NULL;
|
||||
if( (b == R_NULL) || (b == R_EOF) )
|
||||
return b;
|
||||
|
||||
bb=b;
|
||||
|
||||
|
||||
@@ -20,7 +20,8 @@ enum
|
||||
requested but none could be delivered, or when an exception
|
||||
happened.
|
||||
*/
|
||||
R_NULL = INPUT_COMMON_RESERVED
|
||||
R_NULL = INPUT_COMMON_RESERVED,
|
||||
R_EOF
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
17
io.c
17
io.c
@@ -213,37 +213,34 @@ io_data_t *io_get( io_data_t *io, int fd )
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
static void io_print( io_data_t *io )
|
||||
|
||||
void io_print( io_data_t *io )
|
||||
{
|
||||
if( !io )
|
||||
{
|
||||
fwprintf( stderr, L"\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
fwprintf( stderr, L"IO fd %d, type ",
|
||||
debug( 1, L"IO fd %d, type ",
|
||||
io->fd );
|
||||
switch( io->io_mode )
|
||||
{
|
||||
case IO_PIPE:
|
||||
fwprintf(stderr, L"PIPE, data %d\n", io->pipe_fd[io->fd?1:0] );
|
||||
debug( 1, L"PIPE, data %d", io->param1.pipe_fd[io->fd?1:0] );
|
||||
break;
|
||||
|
||||
case IO_FD:
|
||||
fwprintf(stderr, L"FD, copy %d\n", io->old_fd );
|
||||
debug( 1, L"FD, copy %d", io->param1.old_fd );
|
||||
break;
|
||||
|
||||
case IO_BUFFER:
|
||||
fwprintf( stderr, L"BUFFER\n" );
|
||||
debug( 1, L"BUFFER" );
|
||||
break;
|
||||
|
||||
default:
|
||||
fwprintf( stderr, L"OTHER\n" );
|
||||
debug( 1, L"OTHER" );
|
||||
}
|
||||
|
||||
io_print( io->next );
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
2
io.h
2
io.h
@@ -89,4 +89,6 @@ io_data_t *io_buffer_create();
|
||||
*/
|
||||
void io_buffer_read( io_data_t *d );
|
||||
|
||||
void io_print( io_data_t *io );
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
Type ^C to exit the program.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -13,6 +15,8 @@
|
||||
#include <locale.h>
|
||||
#include <termcap.h>
|
||||
|
||||
#include "fallback.h"
|
||||
|
||||
#include "input_common.h"
|
||||
|
||||
int writestr( char *str )
|
||||
|
||||
54
main.c
54
main.c
@@ -61,6 +61,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#include "output.h"
|
||||
#include "translate.h"
|
||||
#include "halloc_util.h"
|
||||
#include "history.h"
|
||||
|
||||
/**
|
||||
The string describing the single-character options accepted by the main fish binary
|
||||
*/
|
||||
#define GETOPT_STRING "hilnvc:p:d:"
|
||||
|
||||
/**
|
||||
Parse init files
|
||||
@@ -69,7 +75,7 @@ static int read_init()
|
||||
{
|
||||
char cwd[4096];
|
||||
wchar_t *wcwd;
|
||||
|
||||
|
||||
if( !getcwd( cwd, 4096 ) )
|
||||
{
|
||||
wperror( L"getcwd" );
|
||||
@@ -77,11 +83,11 @@ static int read_init()
|
||||
}
|
||||
|
||||
env_set( L"__fish_help_dir", DOCDIR, 0);
|
||||
|
||||
eval( L"builtin cd " DATADIR L"/fish 2>/dev/null; . fish 2>/dev/null", 0, TOP );
|
||||
eval( L"builtin cd " SYSCONFDIR L" 2>/dev/null; . fish 2>/dev/null", 0, TOP );
|
||||
eval( L"builtin cd 2>/dev/null;. .fish 2>/dev/null", 0, TOP );
|
||||
|
||||
|
||||
eval( L"builtin cd " DATADIR L"/fish 2>/dev/null; and . fish 2>/dev/null", 0, TOP );
|
||||
eval( L"builtin cd " SYSCONFDIR L" 2>/dev/null; and . fish 2>/dev/null", 0, TOP );
|
||||
eval( L"builtin cd 2>/dev/null; and . .fish 2>/dev/null", 0, TOP );
|
||||
|
||||
if( chdir( cwd ) == -1 )
|
||||
{
|
||||
// fwprintf( stderr, L"Invalid directory: %s\n", cwd );
|
||||
@@ -137,6 +143,10 @@ int main( int argc, char **argv )
|
||||
"login", no_argument, 0, 'l'
|
||||
}
|
||||
,
|
||||
{
|
||||
"no-execute", no_argument, 0, 'n'
|
||||
}
|
||||
,
|
||||
{
|
||||
"profile", required_argument, 0, 'p'
|
||||
}
|
||||
@@ -159,14 +169,14 @@ int main( int argc, char **argv )
|
||||
|
||||
int opt = getopt_long( argc,
|
||||
argv,
|
||||
"hilvc:p:d:",
|
||||
GETOPT_STRING,
|
||||
long_options,
|
||||
&opt_index );
|
||||
|
||||
#else
|
||||
int opt = getopt( argc,
|
||||
argv,
|
||||
"hilvc:p:d:" );
|
||||
GETOPT_STRING );
|
||||
#endif
|
||||
if( opt == -1 )
|
||||
break;
|
||||
@@ -209,6 +219,10 @@ int main( int argc, char **argv )
|
||||
is_login=1;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
no_exec=1;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
profile = optarg;
|
||||
break;
|
||||
@@ -235,12 +249,20 @@ int main( int argc, char **argv )
|
||||
is_interactive_session &= isatty(STDIN_FILENO);
|
||||
is_interactive_session |= force_interactive;
|
||||
|
||||
/*
|
||||
No-exec is prohibited when in interactive mode
|
||||
*/
|
||||
if( is_interactive_session && no_exec)
|
||||
{
|
||||
debug( 1, _(L"Can not use the no-execute mode when running an interactive session") );
|
||||
no_exec = 0;
|
||||
}
|
||||
|
||||
common_init();
|
||||
halloc_util_init();
|
||||
|
||||
proc_init();
|
||||
event_init();
|
||||
exec_init();
|
||||
wutil_init();
|
||||
parser_init();
|
||||
builtin_init();
|
||||
@@ -248,7 +270,8 @@ int main( int argc, char **argv )
|
||||
env_init();
|
||||
complete_init();
|
||||
reader_init();
|
||||
|
||||
history_init();
|
||||
|
||||
if( read_init() )
|
||||
{
|
||||
if( cmd != 0 )
|
||||
@@ -256,7 +279,7 @@ int main( int argc, char **argv )
|
||||
wchar_t *cmd_wcs = str2wcs( cmd );
|
||||
res = eval( cmd_wcs, 0, TOP );
|
||||
free(cmd_wcs);
|
||||
reader_exit(0);
|
||||
reader_exit(0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -279,10 +302,10 @@ int main( int argc, char **argv )
|
||||
return 1;
|
||||
}
|
||||
|
||||
sb_init( &sb );
|
||||
|
||||
if( *(argv+2))
|
||||
{
|
||||
sb_init( &sb );
|
||||
|
||||
for( i=1,ptr = argv+2; *ptr; i++, ptr++ )
|
||||
{
|
||||
if( i != 1 )
|
||||
@@ -318,7 +341,8 @@ int main( int argc, char **argv )
|
||||
}
|
||||
|
||||
proc_fire_event( L"PROCESS_EXIT", EVENT_EXIT, getpid(), res );
|
||||
|
||||
|
||||
history_destroy();
|
||||
complete_destroy();
|
||||
proc_destroy();
|
||||
env_destroy();
|
||||
@@ -327,12 +351,12 @@ int main( int argc, char **argv )
|
||||
reader_destroy();
|
||||
parser_destroy();
|
||||
wutil_destroy();
|
||||
exec_destroy();
|
||||
event_destroy();
|
||||
|
||||
common_destroy();
|
||||
halloc_util_destroy();
|
||||
intern_free_all();
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
9
mimedb.c
9
mimedb.c
@@ -88,6 +88,11 @@ license. Read the source code of the library for more information.
|
||||
*/
|
||||
#define MIMEDB "mimedb"
|
||||
|
||||
/**
|
||||
Getopt short switches for mimedb
|
||||
*/
|
||||
#define GETOPT_STRING "tfimdalhv"
|
||||
|
||||
/**
|
||||
All types of input and output possible
|
||||
*/
|
||||
@@ -1216,14 +1221,14 @@ int main (int argc, char *argv[])
|
||||
|
||||
int opt = getopt_long( argc,
|
||||
argv,
|
||||
"tfimdalhv",
|
||||
GETOPT_STRING,
|
||||
long_options,
|
||||
&opt_index );
|
||||
|
||||
#else
|
||||
int opt = getopt( argc,
|
||||
argv,
|
||||
"tfimdalhv" );
|
||||
GETOPT_STRING );
|
||||
#endif
|
||||
if( opt == -1 )
|
||||
break;
|
||||
|
||||
91
output.c
91
output.c
@@ -128,9 +128,20 @@ void set_color( int c, int c2 )
|
||||
{
|
||||
static int last_color = FISH_COLOR_NORMAL;
|
||||
static int last_color2 = FISH_COLOR_NORMAL;
|
||||
static int was_bold=0;
|
||||
int bg_set=0, last_bg_set=0;
|
||||
char *fg = 0, *bg=0;
|
||||
|
||||
int is_bold = 0;
|
||||
|
||||
is_bold |= (c&FISH_COLOR_BOLD)!=0;
|
||||
is_bold |= (c2&FISH_COLOR_BOLD)!=0;
|
||||
|
||||
// debug( 1, L"WOO %d %d %d", is_bold, c&FISH_COLOR_BOLD,c2&FISH_COLOR_BOLD);
|
||||
|
||||
c = c&(~FISH_COLOR_BOLD);
|
||||
c2 = c2&(~FISH_COLOR_BOLD);
|
||||
|
||||
if( (set_a_foreground != 0) && (strlen( set_a_foreground) != 0 ) )
|
||||
{
|
||||
fg = set_a_foreground;
|
||||
@@ -145,14 +156,31 @@ void set_color( int c, int c2 )
|
||||
if( (c == FISH_COLOR_RESET) || (c2 == FISH_COLOR_RESET))
|
||||
{
|
||||
c = c2 = FISH_COLOR_NORMAL;
|
||||
was_bold=0;
|
||||
if( fg )
|
||||
{
|
||||
/*
|
||||
If we exit attibute mode, we must first set a color, or
|
||||
previously coloured text might lose it's
|
||||
color. Terminals are weird...
|
||||
*/
|
||||
writembs( tparm( fg, 0 ) );
|
||||
}
|
||||
writembs( exit_attribute_mode );
|
||||
return;
|
||||
}
|
||||
|
||||
if( was_bold && !is_bold )
|
||||
{
|
||||
/*
|
||||
Only way to exit bold mode is a reset of all attributes.
|
||||
*/
|
||||
writembs( exit_attribute_mode );
|
||||
last_color = FISH_COLOR_NORMAL;
|
||||
last_color2 = FISH_COLOR_NORMAL;
|
||||
was_bold=0;
|
||||
}
|
||||
|
||||
if( last_color2 != FISH_COLOR_NORMAL &&
|
||||
last_color2 != FISH_COLOR_RESET &&
|
||||
last_color2 != FISH_COLOR_IGNORE )
|
||||
@@ -164,7 +192,6 @@ void set_color( int c, int c2 )
|
||||
}
|
||||
|
||||
if( c2 != FISH_COLOR_NORMAL &&
|
||||
c2 != FISH_COLOR_RESET &&
|
||||
c2 != FISH_COLOR_IGNORE )
|
||||
{
|
||||
/*
|
||||
@@ -180,7 +207,8 @@ void set_color( int c, int c2 )
|
||||
{
|
||||
/*
|
||||
Background color changed and is set, so we enter bold
|
||||
mode to make reading easier
|
||||
mode to make reading easier. This means bold mode is
|
||||
_always_ on when the background color is set.
|
||||
*/
|
||||
writembs( enter_bold_mode );
|
||||
}
|
||||
@@ -252,8 +280,21 @@ void set_color( int c, int c2 )
|
||||
last_color2 = c2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Lastly, we set bold mode correctly
|
||||
*/
|
||||
if( (enter_bold_mode != 0) && (strlen(enter_bold_mode) > 0) && !bg_set )
|
||||
{
|
||||
if( is_bold && !was_bold )
|
||||
{
|
||||
writembs( tparm( enter_bold_mode ) );
|
||||
}
|
||||
was_bold = is_bold;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
perm_left_cursor and parm_right_cursor don't seem to be properly
|
||||
emulated by many terminal emulators, so we only use plain
|
||||
@@ -475,23 +516,37 @@ int writespace( int c )
|
||||
|
||||
int output_color_code( const wchar_t *val )
|
||||
{
|
||||
int i, color=-1;
|
||||
int j, i, color=FISH_COLOR_NORMAL;
|
||||
array_list_t el;
|
||||
int is_bold=0;
|
||||
|
||||
for( i=0; i<COLORS; i++ )
|
||||
{
|
||||
if( wcscasecmp( col[i], val ) == 0 )
|
||||
{
|
||||
color = col_idx[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( color >= 0 )
|
||||
{
|
||||
return color;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !val )
|
||||
return FISH_COLOR_NORMAL;
|
||||
|
||||
al_init( &el );
|
||||
tokenize_variable_array( val, &el );
|
||||
|
||||
for( j=0; j<al_get_count( &el ); j++ )
|
||||
{
|
||||
wchar_t *next = (wchar_t *)al_get( &el, j );
|
||||
|
||||
is_bold |= (wcsncmp( next, L"--bold", wcslen(next) ) == 0 ) && wcslen(next)>=3;
|
||||
is_bold |= wcscmp( next, L"-b" ) == 0;
|
||||
|
||||
for( i=0; i<COLORS; i++ )
|
||||
{
|
||||
if( wcscasecmp( col[i], next ) == 0 )
|
||||
{
|
||||
color = col_idx[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
al_foreach( &el, (void (*)(const void *))&free );
|
||||
al_destroy( &el );
|
||||
|
||||
return color | (is_bold?FISH_COLOR_BOLD:0);
|
||||
|
||||
}
|
||||
|
||||
11
output.h
11
output.h
@@ -14,7 +14,6 @@ enum
|
||||
{
|
||||
HIGHLIGHT_NORMAL,
|
||||
HIGHLIGHT_COMMAND,
|
||||
HIGHLIGHT_SUBSHELL,
|
||||
HIGHLIGHT_REDIRECTION,
|
||||
HIGHLIGHT_END,
|
||||
HIGHLIGHT_ERROR,
|
||||
@@ -22,6 +21,9 @@ enum
|
||||
HIGHLIGHT_COMMENT,
|
||||
HIGHLIGHT_MATCH,
|
||||
HIGHLIGHT_SEARCH_MATCH,
|
||||
HIGHLIGHT_OPERATOR,
|
||||
HIGHLIGHT_ESCAPE,
|
||||
HIGHLIGHT_QUOTE,
|
||||
}
|
||||
;
|
||||
|
||||
@@ -39,10 +41,13 @@ enum
|
||||
FISH_COLOR_CYAN,
|
||||
FISH_COLOR_WHITE,
|
||||
/** The default fg color of the terminal */
|
||||
FISH_COLOR_NORMAL
|
||||
FISH_COLOR_NORMAL,
|
||||
FISH_COLOR_IGNORE,
|
||||
FISH_COLOR_RESET
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
#define FISH_COLOR_BOLD 0x80
|
||||
|
||||
/**
|
||||
Sets the fg and bg color. May be called as often as you like, since
|
||||
|
||||
@@ -558,7 +558,7 @@ int parse_util_load( const wchar_t *cmd,
|
||||
else
|
||||
sb_clear( path );
|
||||
|
||||
expand_variable_array( path_var, path_list );
|
||||
tokenize_variable_array( path_var, path_list );
|
||||
|
||||
/*
|
||||
Iterate over path searching for suitable completion files
|
||||
|
||||
22
parser.h
22
parser.h
@@ -259,6 +259,12 @@ int parser_is_subcommand( const wchar_t *cmd );
|
||||
*/
|
||||
int parser_is_reserved( const wchar_t *word );
|
||||
|
||||
/**
|
||||
Test if the specified string is command that opens a new block
|
||||
*/
|
||||
|
||||
int parser_is_block( const wchar_t *word);
|
||||
|
||||
/**
|
||||
Returns a string describing the current parser pisition in the format 'FILENAME (line LINE_NUMBER): LINE'.
|
||||
Example:
|
||||
@@ -309,10 +315,20 @@ const wchar_t *parser_get_block_desc( int block );
|
||||
|
||||
|
||||
/**
|
||||
Test if the specified string can be parsed, or if more bytes need to be read first.
|
||||
The result has the first bit set if the string contains errors, and the second bit is set if the string contains an unclosed block.
|
||||
Test if the specified string can be parsed, or if more bytes need
|
||||
to be read first. The result has the first bit set if the string
|
||||
contains errors, and the second bit is set if the string contains
|
||||
an unclosed block.
|
||||
*/
|
||||
int parser_test( wchar_t * buff, int babble );
|
||||
int parser_test( const wchar_t * buff, int babble );
|
||||
|
||||
/**
|
||||
Test if the specified string can be parsed as an argument list,
|
||||
e.g. sent to eval_args. The result has the first bit set if the
|
||||
string contains errors, and the second bit is set if the string
|
||||
contains an unclosed block.
|
||||
*/
|
||||
int parser_test_args( const wchar_t * buff, int babble );
|
||||
|
||||
/**
|
||||
Returns the full path of the specified directory. If the \c in is a
|
||||
|
||||
91
po/sv.po
91
po/sv.po
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Project-Id-Version: fish 1.20.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2006-03-07 13:37+0100\n"
|
||||
"PO-Revision-Date: 2006-03-07 03:20+0100\n"
|
||||
"PO-Revision-Date: 2006-03-13 18:06+0100\n"
|
||||
"Last-Translator: Axel Liljencrantz <liljencrantz@gmail.com>\n"
|
||||
"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -3079,16 +3079,16 @@ msgstr ""
|
||||
|
||||
#: share/completions/cdrecord.fish:14
|
||||
msgid "Complete CD/DVD-Recorder recording process with the laser turned off"
|
||||
msgstr ""
|
||||
msgstr "Fullfölj CD/DVD-brännarens inspelningsprocess med lasern avstängd"
|
||||
|
||||
#: share/completions/cdrecord.fish:15
|
||||
msgid "Tells cdrecord to handle images created by readcd -clone"
|
||||
msgstr ""
|
||||
msgstr "Ange att cdrecord ska hantera bilder skapade av readcd -clone"
|
||||
|
||||
#: share/completions/cdrecord.fish:17
|
||||
msgid "Set SAO (Session At Once) mode, usually called Disk At Once mode"
|
||||
msgstr ""
|
||||
"<Välj SAO- (Session At Once) skrivläge, vanlightvis kallat Disk At Once-"
|
||||
"Välj SAO- (Session At Once) skrivläge, vanligtvis kallat Disk At Once-"
|
||||
"skrivläge"
|
||||
|
||||
#: share/completions/cdrecord.fish:18
|
||||
@@ -3102,112 +3102,110 @@ msgstr "Välj RAW-skrivläge"
|
||||
|
||||
#: share/completions/cdrecord.fish:20
|
||||
msgid "Select Set RAW writing, the preferred raw writing mode"
|
||||
msgstr ""
|
||||
msgstr "Välj det bättre RAW-skrivläget"
|
||||
|
||||
#: share/completions/cdrecord.fish:21
|
||||
msgid "Select Set RAW writing, the less preferred raw writing mode"
|
||||
msgstr ""
|
||||
msgstr "Välj det mindre bra RAW-skrivläget"
|
||||
|
||||
#: share/completions/cdrecord.fish:22
|
||||
msgid ""
|
||||
"Select Set RAW writing, the preferred raw writing mode if raw96r is not "
|
||||
"supported"
|
||||
msgstr ""
|
||||
msgstr "Välj det RAW-skrivläget som är bäst om stöd saknas för raw96r"
|
||||
|
||||
#: share/completions/cdrecord.fish:23
|
||||
msgid "Allow multi session CDs to be made"
|
||||
msgstr ""
|
||||
msgstr "Tillåt skapandet av multisessions-CD"
|
||||
|
||||
#: share/completions/cdrecord.fish:24
|
||||
msgid ""
|
||||
"Retrieve multi session info in a form suitable for mkisofs-1.10 or later"
|
||||
msgstr ""
|
||||
msgstr "Hämta multisessionsinfo i ett format lämpligt för mkisofs-1.10 och senare"
|
||||
|
||||
#: share/completions/cdrecord.fish:25
|
||||
msgid "Retrieve and print out the table of content or PMA of a CD"
|
||||
msgstr ""
|
||||
msgstr "Hämta och skriv ut innehållsförteckningen eller PMA för en CD"
|
||||
|
||||
#: share/completions/cdrecord.fish:26
|
||||
msgid "Retrieve and print out the ATIP (absolute Time in Pre-groove) info"
|
||||
msgstr ""
|
||||
msgstr "Hämta och skriv ut ATIP (absolute Time in Pre-groove) info"
|
||||
|
||||
#: share/completions/cdrecord.fish:27
|
||||
msgid "The disk will only be fixated"
|
||||
msgstr ""
|
||||
msgstr "Fixera endast skivan"
|
||||
|
||||
#: share/completions/cdrecord.fish:28
|
||||
msgid "Do not fixate the disk after writing the tracks"
|
||||
msgstr ""
|
||||
msgstr "Fixera inte skivan efter stt spåren skrivits"
|
||||
|
||||
#: share/completions/cdrecord.fish:29
|
||||
msgid ""
|
||||
"Wait for input to become available on standard input before trying to open "
|
||||
"the SCSI driver"
|
||||
msgstr ""
|
||||
msgstr "Vänta på att indata ska bli tillgängligt från standard in innan försök rill att öppna SCSI-enheten"
|
||||
|
||||
#: share/completions/cdrecord.fish:30
|
||||
msgid "Load the media and exit"
|
||||
msgstr ""
|
||||
msgstr "Ladda mediet och avsluta"
|
||||
|
||||
#: share/completions/cdrecord.fish:31
|
||||
msgid "Load the media, lock the door and exit"
|
||||
msgstr ""
|
||||
msgstr "Ladda mediet, lås luckan och avsluta"
|
||||
|
||||
#: share/completions/cdrecord.fish:32
|
||||
msgid "Eject disk after doing the work"
|
||||
msgstr ""
|
||||
msgstr "Skicka ut skivan efter arbetets utförande"
|
||||
|
||||
#: share/completions/cdrecord.fish:33
|
||||
msgid "Set the speed factor of the writing process to #"
|
||||
msgstr ""
|
||||
msgstr "Sätt hastighetsfaktorn för skrivprocessen"
|
||||
|
||||
#: share/completions/cdrecord.fish:34
|
||||
msgid "Blank a CD-RW and exit or blank a CD-RW before writing"
|
||||
msgstr ""
|
||||
msgstr "Töm en CD-RW och avsluta eller töm en CD-RW för skrivning"
|
||||
|
||||
#: share/completions/cdrecord.fish:35
|
||||
msgid "Format a CD-RW/DVD-RW/DVD+RW disc"
|
||||
msgstr ""
|
||||
msgstr "Formatera en CD-RW/DVD-RW/DVD+RW-skiva"
|
||||
|
||||
#: share/completions/cdrecord.fish:36
|
||||
#, fuzzy
|
||||
msgid "Set the FIFO (ring buffer) size to #"
|
||||
msgstr "Välj minnesbuffertstorlek"
|
||||
msgstr "Välj FIFO- (ringbuffert) storlek"
|
||||
|
||||
#: share/completions/cdrecord.fish:37
|
||||
msgid "Set the maximum transfer size for a single SCSI command to #"
|
||||
msgstr ""
|
||||
msgstr "Välj maximal överföringshastighet för ett enkilt SCSI-kommando"
|
||||
|
||||
#: share/completions/cdrecord.fish:38
|
||||
msgid "Sets the SCSI target for the CD/DVD-Recorder"
|
||||
msgstr ""
|
||||
msgstr "Välj SCSI-målet för CD/DVD-brännaren"
|
||||
|
||||
#: share/completions/cdrecord.fish:39
|
||||
msgid "Set the grace time before starting to write to ># seconds"
|
||||
msgstr ""
|
||||
msgstr "Välj väntetiden i sekunder innan skrivning till skivan påbörjas"
|
||||
|
||||
#: share/completions/cdrecord.fish:40
|
||||
msgid "Set the default SCSI command timeout value to # seconds"
|
||||
msgstr ""
|
||||
msgstr "Välj standard-SCSI-timeoutvärdet i sekunder"
|
||||
|
||||
#: share/completions/cdrecord.fish:41
|
||||
msgid "Allows the user to manually select a driver for the device"
|
||||
msgstr ""
|
||||
msgstr "Låter användaren manuellt välja en drivrutin för enheten"
|
||||
|
||||
#: share/completions/cdrecord.fish:45
|
||||
#, fuzzy
|
||||
msgid "Set driver specific options"
|
||||
msgstr "Välj konfigurationsinställningar"
|
||||
msgstr "Välj drivrutinsspecifika inställningar"
|
||||
|
||||
#: share/completions/cdrecord.fish:46
|
||||
msgid ""
|
||||
"Set the driveropts specified by driveropts=option list, the speed of the "
|
||||
"drive and the dummy flag and exit"
|
||||
msgstr ""
|
||||
msgstr "Välj drivrutinsinställningar angivna av listandriveropt=inställning, hastigheten på enheten och dunny-flaggan och avsluta"
|
||||
|
||||
#: share/completions/cdrecord.fish:47
|
||||
msgid "Checks if a driver for the current drive is present and exit"
|
||||
msgstr ""
|
||||
msgstr "Kontrollerar om en drivrutin för den nuvarande enheten finns tillgänglig och avsluta"
|
||||
|
||||
#: share/completions/cdrecord.fish:48
|
||||
msgid ""
|
||||
@@ -3217,64 +3215,63 @@ msgstr ""
|
||||
|
||||
#: share/completions/cdrecord.fish:49
|
||||
msgid "Do an inquiry for the drive, print the inquiry info and exit"
|
||||
msgstr ""
|
||||
msgstr "Utför en föffrågan på enheten, visa förfrågningsinformationen och avsluta"
|
||||
|
||||
#: share/completions/cdrecord.fish:50
|
||||
msgid "Scan all SCSI devices on all SCSI busses and print the inquiry strings"
|
||||
msgstr ""
|
||||
msgstr "Genomsök alla SCSI-enheter på alla SCSI-bussar och skriv ut förfrågningssträngarna"
|
||||
|
||||
#: share/completions/cdrecord.fish:51
|
||||
msgid "Try to reset the SCSI bus where the CD recorder is located"
|
||||
msgstr ""
|
||||
msgstr "Försök att återställa SCSI-bussen som CD-brännaren befinner sig på"
|
||||
|
||||
#: share/completions/cdrecord.fish:52
|
||||
msgid "Try to send an abort sequence to the drive"
|
||||
msgstr ""
|
||||
msgstr "Försök skicka en avbrottssekvens till enheten"
|
||||
|
||||
#: share/completions/cdrecord.fish:53
|
||||
msgid "Allow cdrecord to write more than the official size of a medium"
|
||||
msgstr ""
|
||||
msgstr "Tillåt cdrecord att skriva mer än den officiella storleken på ett medium"
|
||||
|
||||
#: share/completions/cdrecord.fish:54
|
||||
msgid "Ignore the known size of the medium, use for debugging only"
|
||||
msgstr ""
|
||||
msgstr "Ignorera den kända storleken på ett medium, använd endast vid debuggning"
|
||||
|
||||
#: share/completions/cdrecord.fish:55
|
||||
#, fuzzy
|
||||
msgid "Use *.inf files to overwrite audio options"
|
||||
msgstr "Svar till överskrivningsfrågor"
|
||||
msgstr "Använd *.inf-filer för att skriva över ljudinställningar"
|
||||
|
||||
#: share/completions/cdrecord.fish:56
|
||||
msgid "Set the default pre-gap size for all tracks except track nr 1"
|
||||
msgstr ""
|
||||
msgstr "Välj standard-pre-gap-storlek för alla spår utom spår 1"
|
||||
|
||||
#: share/completions/cdrecord.fish:57
|
||||
msgid "Set Packet writing mode (experimental interface)"
|
||||
msgstr ""
|
||||
msgstr "Välj paketskrivningsläge (experimentellt gränssnitt)"
|
||||
|
||||
#: share/completions/cdrecord.fish:58
|
||||
msgid "Set the packet size to #, forces fixed packet mode (experimental)"
|
||||
msgstr ""
|
||||
msgstr "Ange paketstorlek, tvingar fast paket-läge (experimentell)"
|
||||
|
||||
#: share/completions/cdrecord.fish:59
|
||||
msgid ""
|
||||
"Do not close the current track, only when in packet writing mode "
|
||||
"(experimental)"
|
||||
msgstr ""
|
||||
msgstr "Avsluta inte det nuvarande spåret, bara i paketskrivningsläge (experimentell)"
|
||||
|
||||
#: share/completions/cdrecord.fish:60
|
||||
msgid "Set the Media Catalog Number of the CD"
|
||||
msgstr ""
|
||||
msgstr "Välj Mediakatalog-nummer för CD:n"
|
||||
|
||||
#: share/completions/cdrecord.fish:61
|
||||
msgid ""
|
||||
"Write CD-Text info based on info taken from a file that contains ascii info "
|
||||
"for the text strings"
|
||||
msgstr ""
|
||||
msgstr "Skriv CD-Text-infromation baserat på information tagen från fil i ascii-format"
|
||||
|
||||
#: share/completions/cdrecord.fish:62
|
||||
msgid "Write CD-Text based on info found in the binary file filename"
|
||||
msgstr ""
|
||||
msgstr "Skriv CD-Text-infromation baserat på information tagen från fil i binärt format"
|
||||
|
||||
#: share/completions/cdrecord.fish:63
|
||||
msgid "Take all recording related info from a CDRWIN compliant CUE sheet file"
|
||||
@@ -4766,7 +4763,7 @@ msgstr "Skriv ut NUM rader av unifieradt sammanhang"
|
||||
|
||||
#: share/completions/diff.fish:16
|
||||
msgid "Output 3 lines of unified context"
|
||||
msgstr "Skriv ut 3 rader av unifieradt sammanhang"
|
||||
msgstr "Skriv ut 3 rader av unifierat sammanhang"
|
||||
|
||||
#: share/completions/diff.fish:17
|
||||
msgid "Output only whether the files differ"
|
||||
|
||||
47
proc.c
47
proc.c
@@ -90,6 +90,8 @@ int is_event=0;
|
||||
int proc_had_barrier;
|
||||
pid_t proc_last_bg_pid = 0;
|
||||
int job_control_mode = JOB_CONTROL_INTERACTIVE;
|
||||
int no_exec=0;
|
||||
|
||||
|
||||
/**
|
||||
The event variable used to send all process event
|
||||
@@ -180,7 +182,7 @@ int proc_get_last_status()
|
||||
|
||||
job_t *job_create()
|
||||
{
|
||||
int free_id=0;
|
||||
int free_id=1;
|
||||
job_t *res;
|
||||
|
||||
while( job_get( free_id ) != 0 )
|
||||
@@ -192,7 +194,7 @@ job_t *job_create()
|
||||
|
||||
res->job_control = (job_control_mode==JOB_CONTROL_ALL) ||
|
||||
((job_control_mode == JOB_CONTROL_INTERACTIVE) && (is_interactive));
|
||||
|
||||
|
||||
// if( res->job_id > 2 )
|
||||
// fwprintf( stderr, L"Create job %d\n", res->job_id );
|
||||
return res;
|
||||
@@ -202,7 +204,7 @@ job_t *job_create()
|
||||
job_t *job_get( int id )
|
||||
{
|
||||
job_t *res = first_job;
|
||||
if( id == -1 )
|
||||
if( id <= 0 )
|
||||
{
|
||||
return res;
|
||||
}
|
||||
@@ -263,28 +265,12 @@ int job_is_completed( const job_t *j )
|
||||
{
|
||||
if (!p->completed)
|
||||
{
|
||||
// fwprintf( stderr, L"Process %ls not finished\n", p->argv[0] );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
Return true if all processes in the job have completed.
|
||||
|
||||
\param j the job to test
|
||||
*/
|
||||
static int job_last_is_completed( const job_t *j )
|
||||
{
|
||||
process_t *p;
|
||||
|
||||
for (p = j->first_process; p->next; p = p->next)
|
||||
;
|
||||
return p->completed;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Store the status of the process pid that was returned by waitpid.
|
||||
Return 0 if all went well, nonzero otherwise.
|
||||
@@ -501,6 +487,11 @@ int job_reap( int interactive )
|
||||
static int locked = 0;
|
||||
|
||||
locked++;
|
||||
|
||||
/*
|
||||
job_read may fire an event handler, we do not want to call
|
||||
ourselves recursively (to avoid infinite recursion).
|
||||
*/
|
||||
if( locked>1 )
|
||||
return 0;
|
||||
|
||||
@@ -509,6 +500,11 @@ int job_reap( int interactive )
|
||||
process_t *p;
|
||||
jnext = j->next;
|
||||
|
||||
/*
|
||||
If we are reaping only jobs who do not need status messages
|
||||
sent to the console, do not consider reaping jobs that need
|
||||
status messages
|
||||
*/
|
||||
if( (!j->skip_notification) && (!interactive) && (!j->fg))
|
||||
{
|
||||
continue;
|
||||
@@ -813,8 +809,7 @@ static void read_try( job_t *j )
|
||||
else
|
||||
{
|
||||
b_append( buff->param2.out_buffer, b, l );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -829,14 +824,14 @@ void job_continue (job_t *j, int cont)
|
||||
j->next = first_job;
|
||||
first_job = j;
|
||||
j->notified = 0;
|
||||
|
||||
|
||||
debug( 4,
|
||||
L"Continue on job %d (%ls), %ls, %ls",
|
||||
L"Continue job %d (%ls), %ls, %ls",
|
||||
j->job_id,
|
||||
j->command,
|
||||
job_is_completed( j )?L"COMPLETED":L"UNCOMPLETED",
|
||||
is_interactive?L"INTERACTIVE":L"NON-INTERACTIVE" );
|
||||
|
||||
|
||||
if( !job_is_completed( j ) )
|
||||
{
|
||||
if( j->terminal && j->fg )
|
||||
@@ -914,7 +909,7 @@ void job_continue (job_t *j, int cont)
|
||||
do
|
||||
{
|
||||
got_signal = 0;
|
||||
quit = job_is_stopped( j ) || job_last_is_completed( j );
|
||||
quit = job_is_stopped( j ) || job_is_completed( j );
|
||||
}
|
||||
while( got_signal && !quit );
|
||||
if( !quit )
|
||||
@@ -1038,7 +1033,7 @@ void proc_sanity_check()
|
||||
/*
|
||||
More than one foreground job?
|
||||
*/
|
||||
if( j->fg && !(job_is_stopped(j) || job_last_is_completed(j) ) )
|
||||
if( j->fg && !(job_is_stopped(j) || job_is_completed(j) ) )
|
||||
{
|
||||
if( fg_job != 0 )
|
||||
{
|
||||
|
||||
11
proc.h
11
proc.h
@@ -231,6 +231,12 @@ extern pid_t proc_last_bg_pid;
|
||||
*/
|
||||
extern int job_control_mode;
|
||||
|
||||
/**
|
||||
If this flag is set, fish will never fork or run execve.
|
||||
*/
|
||||
extern int no_exec;
|
||||
|
||||
|
||||
/**
|
||||
Sets the status of the last process to exit
|
||||
*/
|
||||
@@ -255,7 +261,7 @@ job_t *job_create();
|
||||
|
||||
/**
|
||||
Return the job with the specified job id.
|
||||
If id is -1, return the last job used.
|
||||
If id is 0 or less, return the last job used.
|
||||
*/
|
||||
job_t *job_get(int id);
|
||||
|
||||
@@ -322,7 +328,8 @@ void proc_update_jiffies();
|
||||
void proc_sanity_check();
|
||||
|
||||
/**
|
||||
Send of an process/job exit event notification. This function is a conveniance wrapper around event_fire().
|
||||
Send a process/job exit event notification. This function is a
|
||||
conveniance wrapper around event_fire().
|
||||
*/
|
||||
void proc_fire_event( const wchar_t *msg, int type, pid_t pid, int status );
|
||||
|
||||
|
||||
198
reader.c
198
reader.c
@@ -232,6 +232,11 @@ typedef struct reader_data
|
||||
When this is true, the reader will exit
|
||||
*/
|
||||
int end_loop;
|
||||
/**
|
||||
If this is true, exit reader even if there are running
|
||||
jobs. This happens if we press e.g. ^D twice.
|
||||
*/
|
||||
int prev_end_loop;
|
||||
|
||||
/**
|
||||
Pointer to previous reader_data
|
||||
@@ -269,12 +274,6 @@ static struct stat prev_buff_1, prev_buff_2, post_buff_1, post_buff_2;
|
||||
*/
|
||||
static array_list_t prompt_list;
|
||||
|
||||
/**
|
||||
Stores the previous termios mode so we can reset the modes when
|
||||
we execute programs and when the shell exits.
|
||||
*/
|
||||
static struct termios saved_modes;
|
||||
|
||||
|
||||
/**
|
||||
Store the pid of the parent process, so the exit function knows whether it should reset the terminal or not.
|
||||
@@ -295,10 +294,21 @@ static struct termios old_modes;
|
||||
Prototypes for a bunch of functions defined later on.
|
||||
*/
|
||||
|
||||
/**
|
||||
Stores the previous termios mode so we can reset the modes when
|
||||
we execute programs and when the shell exits.
|
||||
*/
|
||||
static struct termios saved_modes;
|
||||
|
||||
static void reader_save_status();
|
||||
static void reader_check_status();
|
||||
static void reader_super_highlight_me_plenty( wchar_t * buff, int *color, int pos, array_list_t *error );
|
||||
|
||||
/**
|
||||
Variable to keep track of forced exits - see \c reader_exit_forced();
|
||||
*/
|
||||
static int exit_forced;
|
||||
|
||||
|
||||
/**
|
||||
Give up control of terminal
|
||||
@@ -370,6 +380,12 @@ static int room_for_usec(struct stat *st)
|
||||
return res;
|
||||
}
|
||||
|
||||
int reader_exit_forced()
|
||||
{
|
||||
return exit_forced;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
string_buffer used as temporary storage for the reader_readline function
|
||||
*/
|
||||
@@ -841,6 +857,16 @@ static void write_cmdline()
|
||||
|
||||
void reader_init()
|
||||
{
|
||||
tcgetattr(0,&shell_modes); /* get the current terminal modes */
|
||||
memcpy( &saved_modes,
|
||||
&shell_modes,
|
||||
sizeof(saved_modes)); /* save a copy so we can reset the terminal later */
|
||||
|
||||
shell_modes.c_lflag &= ~ICANON; /* turn off canonical mode */
|
||||
shell_modes.c_lflag &= ~ECHO; /* turn off echo mode */
|
||||
shell_modes.c_cc[VMIN]=1;
|
||||
shell_modes.c_cc[VTIME]=0;
|
||||
|
||||
al_init( ¤t_filename);
|
||||
}
|
||||
|
||||
@@ -854,14 +880,19 @@ void reader_destroy()
|
||||
free( readline_buffer );
|
||||
readline_buffer=0;
|
||||
}
|
||||
tcsetattr(0, TCSANOW, &saved_modes);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void reader_exit( int do_exit )
|
||||
void reader_exit( int do_exit, int forced )
|
||||
{
|
||||
if( data )
|
||||
data->end_loop=do_exit;
|
||||
end_loop=do_exit;
|
||||
if( forced )
|
||||
exit_forced = 1;
|
||||
|
||||
}
|
||||
|
||||
void repaint()
|
||||
@@ -886,7 +917,7 @@ void repaint()
|
||||
if( steps )
|
||||
move_cursor( -steps );
|
||||
|
||||
set_color( FISH_COLOR_NORMAL, -1 );
|
||||
set_color( FISH_COLOR_NORMAL, FISH_COLOR_IGNORE );
|
||||
reader_save_status();
|
||||
}
|
||||
|
||||
@@ -1113,7 +1144,7 @@ static int insert_char( int c )
|
||||
}
|
||||
else
|
||||
writech(c);
|
||||
set_color( FISH_COLOR_NORMAL, -1 );
|
||||
set_color( FISH_COLOR_NORMAL, FISH_COLOR_IGNORE );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1571,18 +1602,6 @@ static int handle_completions( array_list_t *comp )
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Reset the terminal. This function is placed in the list of
|
||||
functions to call when exiting by using the atexit function. It
|
||||
checks whether it is the original parent process that is exiting
|
||||
and not a subshell, and if it is the parent, it restores the
|
||||
terminal.
|
||||
*/
|
||||
static void exit_func()
|
||||
{
|
||||
if( getpid() == original_pid )
|
||||
tcsetattr(0, TCSANOW, &saved_modes);
|
||||
}
|
||||
|
||||
/**
|
||||
Initialize data for interactive use
|
||||
@@ -1631,20 +1650,9 @@ static void reader_interactive_init()
|
||||
|
||||
|
||||
al_init( &prompt_list );
|
||||
history_init();
|
||||
|
||||
common_handle_winch(0);
|
||||
|
||||
tcgetattr(0,&shell_modes); /* get the current terminal modes */
|
||||
memcpy( &saved_modes,
|
||||
&shell_modes,
|
||||
sizeof(saved_modes)); /* save a copy so we can reset the terminal later */
|
||||
|
||||
shell_modes.c_lflag &= ~ICANON; /* turn off canonical mode */
|
||||
shell_modes.c_lflag &= ~ECHO; /* turn off echo mode */
|
||||
shell_modes.c_cc[VMIN]=1;
|
||||
shell_modes.c_cc[VTIME]=0;
|
||||
|
||||
if( tcsetattr(0,TCSANOW,&shell_modes)) /* set the new modes */
|
||||
{
|
||||
wperror(L"tcsetattr");
|
||||
@@ -1657,9 +1665,6 @@ static void reader_interactive_init()
|
||||
*/
|
||||
original_pid = getpid();
|
||||
|
||||
if( atexit( &exit_func ) )
|
||||
debug( 1, _( L"Could not set exit function" ) );
|
||||
|
||||
env_set( L"_", L"fish", ENV_GLOBAL );
|
||||
}
|
||||
|
||||
@@ -1671,7 +1676,6 @@ static void reader_interactive_destroy()
|
||||
kill_destroy();
|
||||
al_foreach( &prompt_list, (void (*)(const void *))&free );
|
||||
al_destroy( &prompt_list );
|
||||
history_destroy();
|
||||
|
||||
writestr( L"\n" );
|
||||
set_color( FISH_COLOR_RESET, FISH_COLOR_RESET );
|
||||
@@ -2078,7 +2082,7 @@ void reader_run_command( wchar_t *cmd )
|
||||
|
||||
term_steal();
|
||||
|
||||
env_set( L"_", L"fish", ENV_GLOBAL );
|
||||
env_set( L"_", program_name, ENV_GLOBAL );
|
||||
|
||||
#ifdef HAVE__PROC_SELF_STAT
|
||||
proc_update_jiffies();
|
||||
@@ -2095,7 +2099,13 @@ void reader_run_command( wchar_t *cmd )
|
||||
|
||||
static int shell_test( wchar_t *b )
|
||||
{
|
||||
return !wcslen(b);
|
||||
if( parser_test( b, 0 ) )
|
||||
{
|
||||
writech( L'\n' );
|
||||
parser_test( b, 1 );
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2245,7 +2255,6 @@ int exit_status()
|
||||
*/
|
||||
static int read_i()
|
||||
{
|
||||
int prev_end_loop=0;
|
||||
|
||||
reader_push(L"fish");
|
||||
reader_set_complete_function( &complete );
|
||||
@@ -2253,6 +2262,7 @@ static int read_i()
|
||||
reader_set_test_function( &shell_test );
|
||||
|
||||
data->prompt_width=60;
|
||||
data->prev_end_loop=0;
|
||||
|
||||
while( (!data->end_loop) && (!sanity_check()) )
|
||||
{
|
||||
@@ -2269,26 +2279,40 @@ static int read_i()
|
||||
during evaluation.
|
||||
*/
|
||||
|
||||
tmp = wcsdup( reader_readline() );
|
||||
|
||||
data->buff_pos=data->buff_len=0;
|
||||
data->buff[data->buff_len]=L'\0';
|
||||
reader_run_command( tmp );
|
||||
free( tmp );
|
||||
tmp = reader_readline();
|
||||
|
||||
if( data->end_loop)
|
||||
{
|
||||
if( !prev_end_loop && first_job != 0 )
|
||||
job_t *j;
|
||||
int has_job=0;
|
||||
|
||||
for( j=first_job; j; j=j->next )
|
||||
{
|
||||
if( !job_is_completed(j) )
|
||||
{
|
||||
has_job = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !reader_exit_forced() && !data->prev_end_loop && has_job )
|
||||
{
|
||||
writestr(_( L"There are stopped jobs\n" ));
|
||||
write_prompt();
|
||||
data->end_loop = 0;
|
||||
prev_end_loop=1;
|
||||
data->prev_end_loop=1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prev_end_loop=0;
|
||||
tmp = wcsdup( tmp );
|
||||
|
||||
data->buff_pos=data->buff_len=0;
|
||||
data->buff[data->buff_len]=L'\0';
|
||||
reader_run_command( tmp );
|
||||
free( tmp );
|
||||
|
||||
data->prev_end_loop=0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2445,6 +2469,13 @@ wchar_t *reader_readline()
|
||||
break;
|
||||
}
|
||||
|
||||
case R_EOF:
|
||||
{
|
||||
exit_forced = 1;
|
||||
data->end_loop=1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* complete */
|
||||
case R_COMPLETE:
|
||||
{
|
||||
@@ -2459,15 +2490,21 @@ wchar_t *reader_readline()
|
||||
if( comp_empty )
|
||||
{
|
||||
const wchar_t *begin, *end;
|
||||
const wchar_t *token_begin, *token_end;
|
||||
wchar_t *buffcpy;
|
||||
|
||||
int len;
|
||||
int cursor_steps;
|
||||
|
||||
parse_util_cmdsubst_extent( data->buff, data->buff_pos, &begin, &end );
|
||||
|
||||
int len = data->buff_pos - (data->buff - begin);
|
||||
parse_util_token_extent( begin, data->buff_pos - (begin-data->buff), &token_begin, &token_end, 0, 0 );
|
||||
cursor_steps = token_end - data->buff- data->buff_pos;
|
||||
data->buff_pos += cursor_steps;
|
||||
move_cursor( cursor_steps );
|
||||
|
||||
len = data->buff_pos - (data->buff - begin);
|
||||
buffcpy = wcsndup( begin, len );
|
||||
|
||||
//fwprintf( stderr, L"String is %ls\n", buffcpy );
|
||||
|
||||
reader_save_status();
|
||||
data->complete_func( buffcpy, &comp );
|
||||
reader_check_status();
|
||||
@@ -2476,6 +2513,7 @@ wchar_t *reader_readline()
|
||||
remove_duplicates( &comp );
|
||||
|
||||
free( buffcpy );
|
||||
|
||||
}
|
||||
if( (comp_empty =
|
||||
handle_completions( &comp ) ) )
|
||||
@@ -2496,7 +2534,6 @@ wchar_t *reader_readline()
|
||||
|
||||
|
||||
repaint();
|
||||
// wcscpy(data->search_buff,data->buff);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2516,7 +2553,6 @@ wchar_t *reader_readline()
|
||||
reader_super_highlight_me_plenty( data->buff, data->color, data->buff_pos, 0 );
|
||||
|
||||
repaint();
|
||||
// wcscpy(data->search_buff,data->buff);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2528,7 +2564,6 @@ wchar_t *reader_readline()
|
||||
reader_super_highlight_me_plenty( data->buff, data->color, data->buff_pos, 0 );
|
||||
|
||||
repaint();
|
||||
// wcscpy(data->search_buff,data->buff);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2537,7 +2572,6 @@ wchar_t *reader_readline()
|
||||
{ yank_str = kill_yank();
|
||||
insert_str( yank_str );
|
||||
yank = wcslen( yank_str );
|
||||
// wcscpy(data->search_buff,data->buff);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2700,6 +2734,7 @@ wchar_t *reader_readline()
|
||||
|
||||
/* Move left*/
|
||||
case R_BACKWARD_CHAR:
|
||||
{
|
||||
if( data->buff_pos > 0 )
|
||||
{
|
||||
data->buff_pos--;
|
||||
@@ -2714,8 +2749,9 @@ wchar_t *reader_readline()
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* Move right*/
|
||||
}
|
||||
|
||||
/* Move right*/
|
||||
case R_FORWARD_CHAR:
|
||||
{
|
||||
if( data->buff_pos < data->buff_len )
|
||||
@@ -2799,7 +2835,16 @@ wchar_t *reader_readline()
|
||||
if( (!wchar_private(c)) && (c>31) && (c != 127) )
|
||||
insert_char( c );
|
||||
else
|
||||
debug( 0, _( L"Unknown keybinding %d" ), c );
|
||||
{
|
||||
/*
|
||||
Carriage returns happen - they are usually a
|
||||
sign of an incorrectly set terminal, but there
|
||||
really isn't very much we can do at this point,
|
||||
so we ignore them.
|
||||
*/
|
||||
if( c != 13 )
|
||||
debug( 0, _( L"Unknown keybinding %d" ), c );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2822,14 +2867,17 @@ wchar_t *reader_readline()
|
||||
}
|
||||
|
||||
al_destroy( &comp );
|
||||
if( tcsetattr(0,TCSANOW,&old_modes)) /* return to previous mode */
|
||||
{
|
||||
wperror(L"tcsetattr");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
set_color( FISH_COLOR_RESET, FISH_COLOR_RESET );
|
||||
|
||||
if( !reader_exit_forced() )
|
||||
{
|
||||
if( tcsetattr(0,TCSANOW,&old_modes)) /* return to previous mode */
|
||||
{
|
||||
wperror(L"tcsetattr");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
set_color( FISH_COLOR_RESET, FISH_COLOR_RESET );
|
||||
}
|
||||
|
||||
return data->buff;
|
||||
}
|
||||
|
||||
@@ -2873,7 +2921,7 @@ static int read_ni( int fd )
|
||||
_( L"Error while reading commands" ) );
|
||||
|
||||
/*
|
||||
Reset buffer. We won't evaluate incomplete files.
|
||||
Reset buffer on error. We won't evaluate incomplete files.
|
||||
*/
|
||||
acc.used=0;
|
||||
break;
|
||||
@@ -2894,13 +2942,10 @@ static int read_ni( int fd )
|
||||
res = 1;
|
||||
}
|
||||
|
||||
// fwprintf( stderr, L"Woot is %d chars\n", wcslen( acc.buff ) );
|
||||
|
||||
if( str )
|
||||
{
|
||||
if( !parser_test( str, 1 ) )
|
||||
{
|
||||
//fwprintf( stderr, L"We parse it\n" );
|
||||
eval( str, 0, TOP );
|
||||
}
|
||||
else
|
||||
@@ -2943,19 +2988,20 @@ static int read_ni( int fd )
|
||||
int reader_read( int fd )
|
||||
{
|
||||
int res;
|
||||
|
||||
/*
|
||||
If reader_read is called recursively through the '.' builtin,
|
||||
we need to preserve is_interactive, so we save the
|
||||
original state. We also update the signal handlers.
|
||||
If reader_read is called recursively through the '.' builtin, we
|
||||
need to preserve is_interactive. This, and signal handler setup
|
||||
is handled by proc_push_interactive/proc_pop_interactive.
|
||||
*/
|
||||
|
||||
proc_push_interactive( ((fd == 0) && isatty(STDIN_FILENO)));
|
||||
|
||||
|
||||
res= is_interactive?read_i():read_ni( fd );
|
||||
|
||||
/*
|
||||
If the exit command was called in a script, only exit the
|
||||
script, not the program
|
||||
script, not the program.
|
||||
*/
|
||||
if( data )
|
||||
data->end_loop = 0;
|
||||
|
||||
7
reader.h
7
reader.h
@@ -21,7 +21,7 @@ int reader_read( int fd);
|
||||
/**
|
||||
Tell the shell that it should exit after the currently running command finishes.
|
||||
*/
|
||||
void reader_exit( int do_exit );
|
||||
void reader_exit( int do_exit, int force );
|
||||
|
||||
/**
|
||||
Check that the reader is in a sane state
|
||||
@@ -162,5 +162,10 @@ void reader_replace_current_token( wchar_t *new_token );
|
||||
*/
|
||||
void reader_handle_int( int signal );
|
||||
|
||||
/**
|
||||
This function returns true if fish is exiting by force, i.e. because stdin died
|
||||
*/
|
||||
int reader_exit_forced();
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
4
seq.in
4
seq.in
@@ -34,14 +34,14 @@ switch (count $argv)
|
||||
|
||||
case '*'
|
||||
printf (_ "%s: Expected 1, 2 or 3 arguments, got %d\n") seq (count $argv)
|
||||
return 1
|
||||
exit 1
|
||||
|
||||
end
|
||||
|
||||
for i in $from $step $to
|
||||
if not echo $i | grep '^-\?[0-9]*\(\|.[0-9]\+\)$' >/dev/null
|
||||
printf (_ "%s: '%s' is not a number\n") seq $i
|
||||
return 1
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -49,6 +49,11 @@
|
||||
*/
|
||||
#define SET_COLOR "set_color"
|
||||
|
||||
/**
|
||||
Getopt short switches for set_color
|
||||
*/
|
||||
#define GETOPT_STRING "b:hvoc"
|
||||
|
||||
#if HAVE_GETTEXT
|
||||
#define _(string) gettext(string)
|
||||
#else
|
||||
@@ -186,13 +191,13 @@ int main( int argc, char **argv )
|
||||
|
||||
int opt = getopt_long( argc,
|
||||
argv,
|
||||
"b:hvoc",
|
||||
GETOPT_STRING,
|
||||
long_options,
|
||||
&opt_index );
|
||||
#else
|
||||
int opt = getopt( argc,
|
||||
argv,
|
||||
"b:hvoc" );
|
||||
GETOPT_STRING );
|
||||
#endif
|
||||
if( opt == -1 )
|
||||
break;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
function __fish_complete_apropos
|
||||
if test (commandline -ct)
|
||||
set str (commandline -ct)
|
||||
apropos $str|sed -e "s/^\(.*$str\([^ ]*\).*\)$/$str\2"\t"\1/"
|
||||
apropos $str|sed -e "s/^\(.*$str\([^ ]*\).*\)\$/$str\2"\t"\1/"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ 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 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]')
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
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 -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')
|
||||
|
||||
@@ -9,6 +9,6 @@ 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 -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')
|
||||
|
||||
|
||||
@@ -12,3 +12,4 @@ complete -c complete -s u -l unauthorative -d (N_ "Option list is not complete")
|
||||
complete -c complete -s e -l erase -d (N_ "Remove completion")
|
||||
complete -c complete -s h -l help -d (N_ "Display help and exit")
|
||||
complete -c complete -s C -l do-complete -d (N_ "Print all completions for the specified commandline")
|
||||
complete -c complete -s n -l complete -d (N_ "The completion should only be used if the specified command has a zero exit status") -r
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
complete -c fish -s c -l "command" -d (N_ "Run fish with this command")
|
||||
complete -c fish -s h -l help -d (N_ "Display help and exit")
|
||||
complete -c fish -s v -l version -d (N_ "Display version and exit")
|
||||
complete -c fish -s n -l no-execute -d (N_ "Only parse input, do not execute")
|
||||
complete -c fish -s i -l interactive -d (N_ "Run in interactive mode")
|
||||
complete -c fish -s l -l login -d (N_ "Run in login mode")
|
||||
complete -c fish -s p -l profile -d (N_ "Output profiling information to specified file") -f
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
complete -c fusermount -d (N_ "Mount point") -x -a '
|
||||
(
|
||||
cat /etc/mtab | grep "^sshfs" | cut -d " " -f 1-2|tr " " \n|sed -e "s/[0-9\.]*:\//\//"|grep "^/"
|
||||
cat /etc/mtab | grep "^fuseiso" | cut -d " " -f 1-2|tr " " \n|sed -e "s/[0-9\.]*:\//\//"|grep "^/"
|
||||
)
|
||||
'
|
||||
|
||||
@@ -15,3 +16,4 @@ complete -c fusermount -s o -x -d (N_ "Mount options")
|
||||
complete -c fusermount -s u -d (N_ "Unmount")
|
||||
complete -c fusermount -s q -d (N_ "Quiet")
|
||||
complete -c fusermount -s z -d (N_ "Lazy unmount")
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ for i in (builtin -n)
|
||||
complete -c help -x -a $i -d (N_ "Help for the specified builtin")
|
||||
end
|
||||
|
||||
for i in count dirh dirs help mimedb nextd open popd prevd pushd set_color psub umask type
|
||||
for i in case (sed -n < /usr/share/doc/fish-1.21.7/commands.html -e "s/.*<h2><a class=\"anchor\" name=\"\([^\"]*\)\">.*/\1/p")
|
||||
complete -c help -x -a $i -d (N_ "Help for the specified command")
|
||||
end
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ complete -x -c ssh -s b -d (N_ "Interface to transmit from") -a "
|
||||
)
|
||||
"
|
||||
|
||||
complete -x -c ssh -s e -d (N_ "Escape character") -a "^ none"
|
||||
complete -x -c ssh -s e -d (N_ "Escape character") -a "\^ none"
|
||||
complete -c ssh -s f -d (N_ "Go to background")
|
||||
complete -c ssh -s g -d (N_ "Allow remote host to connect to local forwarded ports")
|
||||
complete -c ssh -s I -d (N_ "Smartcard device")
|
||||
|
||||
25
share/completions/telnet.fish
Normal file
25
share/completions/telnet.fish
Normal file
@@ -0,0 +1,25 @@
|
||||
#
|
||||
# Load common telnet options
|
||||
#
|
||||
# Written by: Sean C. Higgins
|
||||
#
|
||||
|
||||
complete -x -c telnet -d Hostname -a "(__fish_print_hostnames)"
|
||||
|
||||
complete -c telnet -s 8 -d (_ "Specifies an 8-bit data path.")
|
||||
complete -c telnet -s 7 -d (_ "Do not try to negotiate TELNET BINARY option.")
|
||||
complete -c telnet -s E -d (_ "Stops any character from being recognized as an escape character.")
|
||||
complete -c telnet -s F -d (_ "Use local Kerberos authentication, if possible.")
|
||||
complete -c telnet -s K -d (_ "Specifies no automatic login to remote system.")
|
||||
complete -c telnet -s L -d (_ "Specifies an 8-bit data path.")
|
||||
complete -c telnet -s a -d (_ "Attempt automatic login.")
|
||||
complete -c telnet -s c -d (_ "Disables reading user's .telnetrc")
|
||||
complete -c telnet -s d -d (_ "Sets debug mode.")
|
||||
complete -c telnet -s S -x -d (_ "Sets IP TOS.")
|
||||
complete -c telnet -s X -x -d (_ "Disables atype type of authentication.")
|
||||
complete -c telnet -s l -x -a "(__fish_complete_users)" -d (_ "User login.")
|
||||
complete -c telnet -s n -x -d (_ "Log to tracefile.")
|
||||
complete -c telnet -s x -d (_ "Turn on encryption.")
|
||||
complete -c telnet -s r -d (_ "User interface similar to rlogin.")
|
||||
complete -c telnet -s k -x -d (_ "Use Kerberos realm for authentication.")
|
||||
|
||||
@@ -43,7 +43,7 @@ complete -xc valgrind -l input-fd -d (N_ "File descriptor for input") -a "0 1 2
|
||||
|
||||
|
||||
# Memcheck-specific options
|
||||
complete -n "__fish_valgrind_skin memcheck" -xc valgrind -l leak-check -d (N_ "Check for memory leaks") -a "no\tDon't\ check\ for\ memory\ leaks summary\t'Show a leak summary' full\t'Describe memory leaks in detail'"
|
||||
complete -n "__fish_valgrind_skin memcheck" -xc valgrind -l leak-check -d (N_ "Check for memory leaks") -a "no\tDon\'t\ check\ for\ memory\ leaks summary\t'Show a leak summary' full\t'Describe memory leaks in detail'"
|
||||
complete -n "__fish_valgrind_skin memcheck" -xc valgrind -l show-reachable -d (N_ "Show reachable leaked memory") -a "yes\t'Show reachable leaked memory' no\t'Do not show reachable leaked memory'"
|
||||
complete -n "__fish_valgrind_skin memcheck" -xc valgrind -l leak-resolution -d (N_ "Determines how willing Memcheck is to consider different backtraces to be the same") -a "low\t'Two entries need to match' med\t'Four entries need to match' high\t'All entries need to match'"
|
||||
complete -n "__fish_valgrind_skin memcheck" -xc valgrind -l freelist-vol -d (N_ "Set size of freed memory pool")
|
||||
|
||||
@@ -12,9 +12,9 @@ complete -c xargs -s l -l max-lines -d (N_ "Use at most max-lines nonblank input
|
||||
complete -c xargs -s L -r -f -d (N_ "Use at most max-lines nonblank input lines per command line")
|
||||
complete -c xargs -s n -l max-args -r -f -d (N_ "Use at most max-args arguments per command line")
|
||||
complete -c xargs -s p -l interactive -d (N_ "Prompt the user about whether to run each command line and read a line from the terminal")
|
||||
complete -c xargs -s r -l no-run-if-empty (N_ "If the standard input does not contain any nonblanks, do not run the command")
|
||||
complete -c xargs -s r -l no-run-if-empty -d (N_ "If the standard input does not contain any nonblanks, do not run the command")
|
||||
complete -c xargs -s s -l max-chars -r -f -d (N_ "Use at most max-chars characters per command line")
|
||||
complete -c xargs -s t -l verbose -d (N_ "Print the command line on the standard error output before executing it")
|
||||
complete -c xargs -l version -d (N_ "Display version and exit")
|
||||
complete -c xargs -s x -l exit -d (N_ "Exit if the size is exceeded")
|
||||
complete -c xargs -s P -l max-procs -r -f (N_ "Run up to max-procs processes at a time")
|
||||
complete -c xargs -s P -l max-procs -r -f -d (N_ "Run up to max-procs processes at a time")
|
||||
|
||||
@@ -11,17 +11,44 @@
|
||||
set -g fish_function_path $PWD/functions/
|
||||
|
||||
#
|
||||
# Set some value for LANG if nothing was set before, and this is a
|
||||
# login shell. Also check for i18n information in /etc/sysconfig/i18n
|
||||
# Make sure there are no invalid entries in the PATH
|
||||
#
|
||||
|
||||
if status --is-login
|
||||
if not set -q LANG >/dev/null
|
||||
set -gx LANG en_US.UTF-8
|
||||
end
|
||||
set -l erase_idx
|
||||
for idx in (seq (count $PATH))
|
||||
set i $PATH[$idx]
|
||||
if not test -d $i
|
||||
set erase_idx $erase_idx $idx
|
||||
printf (_ '%s: Warning: The directory %s has been removed from your PATH, because it does not exist\n') fish $i
|
||||
end
|
||||
end
|
||||
|
||||
if test -f /etc/sysconfig/i18n
|
||||
eval (cat /etc/sysconfig/i18n |sed -ne 's/^\([a-zA-Z]*\)=\(.*\)$/set -gx \1 \2;/p')
|
||||
if count $erase_idx >/dev/null
|
||||
set -e PATH[(echo $erase_idx)]
|
||||
end
|
||||
|
||||
#
|
||||
# Add a few common directories to path, if they exists. Note that pure
|
||||
# console programs like makedep sometimes live in /usr/X11R6/bin, so we
|
||||
# want this even for text-only terminals.
|
||||
#
|
||||
|
||||
set -l path_list /bin /usr/bin /usr/X11R6/bin @PREFIX@/bin @optbindirs@
|
||||
|
||||
# Root should also have the sbin directories in the path
|
||||
if test "$USER" = root
|
||||
set path_list $path_list /sbin /usr/sbin /usr/local/sbin
|
||||
end
|
||||
|
||||
# Make a regular expression that matches any component in the PATH. A
|
||||
# trailing slash is ok. The sed call is to remove the last '\|'.
|
||||
|
||||
|
||||
set -l path_regexp \\\((printf "%s" \^$PATH'\(\|/\)$\|' | sed -e "s/..\$//")\\\)
|
||||
|
||||
for i in (printf "%s\n" $path_list|grep -v $path_regexp)
|
||||
if test -d $i
|
||||
set PATH $PATH $i
|
||||
end
|
||||
end
|
||||
|
||||
@@ -37,8 +64,8 @@ end
|
||||
# Convenience functions
|
||||
#
|
||||
# The naming heuristic is that __fish_complete_* prints completions
|
||||
# and descriptions, while __fish_print_* only prints the completion,
|
||||
# without the description
|
||||
# and descriptions, while __fish_print_* only prints the completions
|
||||
# and no descriptions
|
||||
#
|
||||
|
||||
function __fish_complete_users -d "Print a list of local users, with the real user name as a description"
|
||||
@@ -69,9 +96,8 @@ end
|
||||
# Completions for the shell and it's builtin commands and functions
|
||||
#
|
||||
|
||||
set -l __fish_help_desc (_ "Display help and exit")
|
||||
for i in (builtin -n|grep -vE '(while|for|if|function|switch)' )
|
||||
complete -c $i -s h -l help -d $__fish_help_desc
|
||||
for i in (builtin -n|grep -v '\(while\|for\|if\|function\|switch\)' )
|
||||
complete -c $i -s h -l help -d "Display help and exit"
|
||||
end
|
||||
|
||||
|
||||
6
share/functions/N_.fish
Normal file
6
share/functions/N_.fish
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
|
||||
function N_ -d "No-op"
|
||||
printf "%s" $argv
|
||||
end
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
# Alias for gettext (or a fallback if gettext isn't installed)
|
||||
#
|
||||
|
||||
if which gettext ^/dev/null >/dev/null
|
||||
set -l path (which $i ^/dev/null)
|
||||
if test -x (echo $path)
|
||||
function _ -d "Alias for the gettext command"
|
||||
gettext fish $argv
|
||||
end
|
||||
|
||||
@@ -65,7 +65,7 @@ function __fish_complete_ls -d "Compleletions for ls and it's aliases"
|
||||
complete $cmds -l quoting-style -x -a "literal locale shell shell-always c escape" -d (N_ "Select quoting style")
|
||||
complete $cmds -l sort -x -d (N_ "Sort criteria") -a "
|
||||
extension\t'Sort by file extension'
|
||||
none\tDon't\ sort
|
||||
none\tDon\'t\ sort
|
||||
size\t'Sort by size'
|
||||
time\t'Sort by modification time'
|
||||
version\t'Sort by version'
|
||||
@@ -106,4 +106,4 @@ function __fish_complete_ls -d "Compleletions for ls and it's aliases"
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,8 +6,8 @@ function __fish_describe_command -d "Command used to find descriptions for comma
|
||||
apropos $argv | awk -v FS=" +- +" '{
|
||||
split($1, names, ", ");
|
||||
for (name in names)
|
||||
if (names[name] ~ /^'"$argv"'.* *\([18]\)/) {
|
||||
sub("( |\t)*\\([18]\\)", "", names[name]);
|
||||
if (names[name] ~ /^'"$argv"'.* *\([18]\)/ ) {
|
||||
sub( "( |\t)*\\\([18]\\\)", "", names[name] );
|
||||
print names[name] "\t" $2;
|
||||
}
|
||||
}'
|
||||
|
||||
@@ -12,7 +12,7 @@ function __fish_print_packages
|
||||
#Get the word 'Package' in the current language
|
||||
set -l package (_ Package)
|
||||
|
||||
if which apt-cache >/dev/null ^/dev/null
|
||||
if type -f apt-cache >/dev/null
|
||||
# Apply the following filters to output of apt-cache:
|
||||
# 1) Remove package names with parentesis in them, since these seem to not correspond to actual packages as reported by rpm
|
||||
# 2) Remove package names that are .so files, since these seem to not correspond to actual packages as reported by rpm
|
||||
@@ -25,7 +25,7 @@ function __fish_print_packages
|
||||
# Rpm is too slow for this job, so we set it up to do completions
|
||||
# as a background job and cache the results.
|
||||
|
||||
if which rpm >/dev/null ^/dev/null
|
||||
if type -f rpm >/dev/null
|
||||
|
||||
# If the cache is less than five minutes old, we do not recalculate it
|
||||
|
||||
@@ -46,7 +46,7 @@ function __fish_print_packages
|
||||
# This completes the package name from the portage tree.
|
||||
# True for installing new packages. Function for printing
|
||||
# installed on the system packages is in completions/emerge.fish
|
||||
if which emerge >/dev/null ^/dev/null
|
||||
if type -f emerge >/dev/null
|
||||
emerge -s \^(commandline -tc) |grep "^*" |cut -d\ -f3 |cut -d/ -f2
|
||||
return
|
||||
end
|
||||
|
||||
@@ -11,7 +11,7 @@ function cd -d (N_ "Change directory")
|
||||
end
|
||||
|
||||
# Avoid set completions
|
||||
set previous (command pwd)
|
||||
set previous $PWD
|
||||
|
||||
if test $argv[1] = - ^/dev/null
|
||||
if test $__fish_cd_direction = next ^/dev/null
|
||||
@@ -24,7 +24,7 @@ function cd -d (N_ "Change directory")
|
||||
|
||||
builtin cd $argv[1]
|
||||
|
||||
if test $status = 0 -a (command pwd) != $previous
|
||||
if test $status = 0 -a $PWD != $previous
|
||||
set -g dirprev $dirprev $previous
|
||||
set -e dirnext
|
||||
set -g __fish_cd_direction prev
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
#
|
||||
# This file defines various shellscript functions. Most of them are
|
||||
# meant to be used directly by the user, but some of them, typically
|
||||
# the ones whose name start with '__fish_', are only meant to be used
|
||||
# internally by fish.
|
||||
#
|
||||
|
||||
function contains -d (N_ "Test if a key is contained in a set of values")
|
||||
while set -q argv
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
# string has a newline before and after, so that fish will know how
|
||||
# long it is.
|
||||
|
||||
# This event handler makes sure the prompt is repainted when fish_color_cwd changes value
|
||||
function __fish_repaint --on-variable fish_color_cwd -d (N_ "Event handler, repaints the prompt when fish_color_cwd changes")
|
||||
commandline -f null
|
||||
end
|
||||
|
||||
function fish_prompt -d (N_ "Write out the prompt")
|
||||
|
||||
# Just calculate these once, to save a few cycles when displaying the prompt
|
||||
|
||||
@@ -36,7 +36,7 @@ function help -d (N_ "Show help for the fish shell")
|
||||
else
|
||||
# Check for a text-based browser.
|
||||
for i in $text_browsers
|
||||
if which $i 2>/dev/null >/dev/null
|
||||
if type -f $i >/dev/null
|
||||
set fish_browser $i
|
||||
break
|
||||
end
|
||||
@@ -46,7 +46,7 @@ function help -d (N_ "Show help for the fish shell")
|
||||
# browser to use instead.
|
||||
if test "$DISPLAY" -a \( "$XAUTHORITY" = "$HOME/.Xauthority" -o "$XAUTHORITY" = "" \)
|
||||
for i in $graphical_browsers
|
||||
if which $i 2>/dev/null >/dev/null
|
||||
if type -f $i >/dev/null
|
||||
set fish_browser $i
|
||||
set fish_browser_bg 1
|
||||
break
|
||||
@@ -74,12 +74,17 @@ function help -d (N_ "Show help for the fish shell")
|
||||
set fish_help_page "index.html\#expand"
|
||||
case (builtin -n)
|
||||
set fish_help_page "builtins.html\#$fish_help_item"
|
||||
case contains count dirh dirs help mimedb nextd open popd prevd pushd set_color tokenize psub umask type vared
|
||||
|
||||
# This command substitution should locate all commands with
|
||||
# documentation. It's a bit of a hack, since it relies on the
|
||||
# Doxygen markup format to never change...
|
||||
|
||||
case (sed -n < /usr/share/doc/fish-1.21.7/commands.html -e "s/.*<h2><a class=\"anchor\" name=\"\([^\"]*\)\">.*/\1/p")
|
||||
set fish_help_page "commands.html\#$fish_help_item"
|
||||
case $help_topics
|
||||
set fish_help_page "index.html\#$fish_help_item"
|
||||
case "*"
|
||||
if which $fish_help_item >/dev/null ^/dev/null
|
||||
if type -f $fish_help_item >/dev/null
|
||||
man $fish_help_item
|
||||
return
|
||||
end
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
#
|
||||
|
||||
function pwd -d (N_ "Print working directory")
|
||||
command pwd | sed -e 's|/private||' -e "s|^$HOME|~|"
|
||||
echo $PWD | sed -e 's|/private||' -e "s|^$HOME|~|"
|
||||
end
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
function type -d (N_ "Print the type of a command")
|
||||
|
||||
# Initialize
|
||||
set -l status 1
|
||||
set -l res 1
|
||||
set -l mode normal
|
||||
set -l selection all
|
||||
|
||||
@@ -66,7 +66,7 @@ function type -d (N_ "Print the type of a command")
|
||||
if test $selection != files
|
||||
|
||||
if contains -- $i (functions -na)
|
||||
set status 0
|
||||
set res 0
|
||||
set found 1
|
||||
switch $mode
|
||||
case normal
|
||||
@@ -86,7 +86,8 @@ function type -d (N_ "Print the type of a command")
|
||||
end
|
||||
|
||||
if contains -- $i (builtin -n)
|
||||
set status 0
|
||||
|
||||
set res 0
|
||||
set found 1
|
||||
switch $mode
|
||||
case normal
|
||||
@@ -105,18 +106,19 @@ function type -d (N_ "Print the type of a command")
|
||||
|
||||
end
|
||||
|
||||
if which $i ^/dev/null >/dev/null
|
||||
set status 0
|
||||
set -l path (which $i ^/dev/null)
|
||||
if test -x (echo $path)
|
||||
set res 0
|
||||
set found 1
|
||||
switch $mode
|
||||
case normal
|
||||
printf (_ '%s is %s\n') $i (which $i)
|
||||
printf (_ '%s is %s\n') $i $path
|
||||
|
||||
case type
|
||||
printf (_ 'file\n')
|
||||
|
||||
case path
|
||||
which $i
|
||||
echo $path
|
||||
end
|
||||
if test $selection != multi
|
||||
continue
|
||||
@@ -124,11 +126,11 @@ function type -d (N_ "Print the type of a command")
|
||||
end
|
||||
|
||||
if test $found = 0
|
||||
printf (_ "%s: Could not find '%s'") type $i
|
||||
printf (_ "%s: Could not find '%s'\n") type $i
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return $status
|
||||
return $res
|
||||
end
|
||||
|
||||
|
||||
112
signal.c
112
signal.c
@@ -55,143 +55,189 @@ static int block_count=0;
|
||||
*/
|
||||
static struct lookup_entry lookup[] =
|
||||
{
|
||||
#ifdef SIGHUP
|
||||
{
|
||||
SIGHUP,
|
||||
L"SIGHUP",
|
||||
N_( L"Terminal hung up" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGINT
|
||||
{
|
||||
SIGINT,
|
||||
L"SIGINT",
|
||||
N_( L"Quit request from job control (^C)" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGQUIT
|
||||
{
|
||||
SIGQUIT,
|
||||
L"SIGQUIT",
|
||||
N_( L"Quit request from job control with core dump (^\\)" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGILL
|
||||
{
|
||||
SIGILL,
|
||||
L"SIGILL",
|
||||
N_( L"Illegal instruction" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGTRAP
|
||||
{
|
||||
SIGTRAP,
|
||||
L"SIGTRAP",
|
||||
N_( L"Trace or breakpoint trap" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGABRT
|
||||
{
|
||||
SIGABRT,
|
||||
L"SIGABRT",
|
||||
N_( L"Abort" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGBUS
|
||||
{
|
||||
SIGBUS,
|
||||
L"SIGBUS",
|
||||
N_( L"Misaligned address error" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGFPE
|
||||
{
|
||||
SIGFPE,
|
||||
L"SIGFPE",
|
||||
N_( L"Floating point exception" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGKILL
|
||||
{
|
||||
SIGKILL,
|
||||
L"SIGKILL",
|
||||
N_( L"Forced quit" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGUSR1
|
||||
{
|
||||
SIGUSR1,
|
||||
L"SIGUSR1",
|
||||
N_( L"User defined signal 1" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGUSR2
|
||||
{
|
||||
SIGUSR2, L"SIGUSR2",
|
||||
N_( L"User defined signal 2" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGSEGV
|
||||
{
|
||||
SIGSEGV,
|
||||
L"SIGSEGV",
|
||||
N_( L"Address boundary error" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGPIPE
|
||||
{
|
||||
SIGPIPE,
|
||||
L"SIGPIPE",
|
||||
N_( L"Broken pipe" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGALRM
|
||||
{
|
||||
SIGALRM,
|
||||
L"SIGALRM",
|
||||
N_( L"Timer expired" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGTERM
|
||||
{
|
||||
SIGTERM,
|
||||
L"SIGTERM",
|
||||
N_( L"Polite quit request" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGCHLD
|
||||
{
|
||||
SIGCHLD,
|
||||
L"SIGCHLD",
|
||||
N_( L"Child process status changed" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGCONT
|
||||
{
|
||||
SIGCONT,
|
||||
L"SIGCONT",
|
||||
N_( L"Continue previously stopped process" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGSTOP
|
||||
{
|
||||
SIGSTOP,
|
||||
L"SIGSTOP",
|
||||
N_( L"Forced stop" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGTSTP
|
||||
{
|
||||
SIGTSTP,
|
||||
L"SIGTSTP",
|
||||
N_( L"Stop request from job control (^Z)" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGTTIN
|
||||
{
|
||||
SIGTTIN,
|
||||
L"SIGTTIN",
|
||||
N_( L"Stop from terminal input" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGTTOU
|
||||
{
|
||||
SIGTTOU,
|
||||
L"SIGTTOU",
|
||||
N_( L"Stop from terminal output" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGURG
|
||||
{
|
||||
SIGURG,
|
||||
L"SIGURG",
|
||||
N_( L"Urgent socket condition" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGXCPY
|
||||
{
|
||||
SIGXCPU,
|
||||
L"SIGXCPU",
|
||||
N_( L"CPU time limit exceeded" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGXFSZ
|
||||
{
|
||||
SIGXFSZ,
|
||||
@@ -200,12 +246,14 @@ static struct lookup_entry lookup[] =
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGVTALRM
|
||||
{
|
||||
SIGVTALRM,
|
||||
L"SIGVTALRM",
|
||||
N_( L"Virtual timer expired" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGPROF
|
||||
{
|
||||
SIGPROF,
|
||||
@@ -230,12 +278,14 @@ static struct lookup_entry lookup[] =
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGWIO
|
||||
{
|
||||
SIGIO,
|
||||
L"SIGIO",
|
||||
N_( L"I/O on asynchronous file descriptor is possible" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGPWR
|
||||
{
|
||||
SIGPWR,
|
||||
@@ -338,6 +388,7 @@ int wcs2sig( const wchar_t *str )
|
||||
const wchar_t *sig2wcs( int sig )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i=0; lookup[i].desc ; i++ )
|
||||
{
|
||||
if( lookup[i].signal == sig )
|
||||
@@ -345,12 +396,14 @@ const wchar_t *sig2wcs( int sig )
|
||||
return lookup[i].name;
|
||||
}
|
||||
}
|
||||
return L"Unknown";
|
||||
|
||||
return _(L"Unknown");
|
||||
}
|
||||
|
||||
const wchar_t *signal_get_desc( int sig )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i=0; lookup[i].desc ; i++ )
|
||||
{
|
||||
if( lookup[i].signal == sig )
|
||||
@@ -358,7 +411,8 @@ const wchar_t *signal_get_desc( int sig )
|
||||
return _(lookup[i].desc);
|
||||
}
|
||||
}
|
||||
return L"Unknown";
|
||||
|
||||
return _(L"Unknown");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -367,11 +421,16 @@ const wchar_t *signal_get_desc( int sig )
|
||||
static void default_handler(int signal, siginfo_t *info, void *context)
|
||||
{
|
||||
event_t e;
|
||||
|
||||
e.type=EVENT_SIGNAL;
|
||||
e.param1.signal = signal;
|
||||
e.function_name=0;
|
||||
|
||||
event_fire( &e );
|
||||
if( event_get( &e, 0 ) )
|
||||
{
|
||||
|
||||
event_fire( &e );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -383,6 +442,28 @@ static void handle_winch( int sig, siginfo_t *info, void *context )
|
||||
default_handler( sig, 0, 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
Respond to a winch signal by checking the terminal size
|
||||
*/
|
||||
static void handle_hup( int sig, siginfo_t *info, void *context )
|
||||
{
|
||||
event_t e;
|
||||
|
||||
e.type=EVENT_SIGNAL;
|
||||
e.param1.signal = SIGHUP;
|
||||
e.function_name=0;
|
||||
|
||||
if( event_get( &e, 0 ) )
|
||||
{
|
||||
default_handler( sig, 0, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
reader_exit( 1, 1 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Interactive mode ^C handler. Respond to int signal by setting
|
||||
interrupted-flag and stopping all loops and conditionals.
|
||||
@@ -431,7 +512,7 @@ void signal_set_handlers()
|
||||
sigemptyset( & act.sa_mask );
|
||||
act.sa_flags=SA_SIGINFO;
|
||||
act.sa_sigaction = &default_handler;
|
||||
|
||||
|
||||
/*
|
||||
First reset everything to a use default_handler, a function
|
||||
whose sole action is to fire of an event
|
||||
@@ -479,7 +560,7 @@ void signal_set_handlers()
|
||||
wperror( L"sigaction" );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
act.sa_flags = SA_SIGINFO;
|
||||
act.sa_sigaction= &handle_winch;
|
||||
if( sigaction( SIGWINCH, &act, 0 ) )
|
||||
@@ -488,6 +569,14 @@ void signal_set_handlers()
|
||||
exit(1);
|
||||
}
|
||||
|
||||
act.sa_flags = SA_SIGINFO;
|
||||
act.sa_sigaction= &handle_hup;
|
||||
if( sigaction( SIGHUP, &act, 0 ) )
|
||||
{
|
||||
wperror( L"sigaction" );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -510,12 +599,13 @@ void signal_set_handlers()
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void signal_handle( int sig, int do_handle )
|
||||
{
|
||||
struct sigaction act;
|
||||
|
||||
|
||||
/*
|
||||
These should always be handled
|
||||
*/
|
||||
@@ -527,15 +617,15 @@ void signal_handle( int sig, int do_handle )
|
||||
(sig == SIGCHLD) )
|
||||
return;
|
||||
|
||||
sigemptyset( & act.sa_mask );
|
||||
sigemptyset( &act.sa_mask );
|
||||
if( do_handle )
|
||||
{
|
||||
act.sa_flags=SA_SIGINFO;
|
||||
act.sa_flags = SA_SIGINFO;
|
||||
act.sa_sigaction = &default_handler;
|
||||
}
|
||||
else
|
||||
{
|
||||
act.sa_flags=0;
|
||||
act.sa_flags = 0;
|
||||
act.sa_handler = SIG_DFL;
|
||||
}
|
||||
|
||||
@@ -551,16 +641,20 @@ void signal_block()
|
||||
sigfillset( &chldset );
|
||||
sigprocmask(SIG_BLOCK, &chldset, 0);
|
||||
}
|
||||
|
||||
block_count++;
|
||||
}
|
||||
|
||||
void signal_unblock()
|
||||
{
|
||||
sigset_t chldset;
|
||||
|
||||
block_count--;
|
||||
|
||||
if( !block_count )
|
||||
{
|
||||
sigfillset( &chldset );
|
||||
sigprocmask(SIG_UNBLOCK, &chldset, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -611,7 +611,7 @@ void tok_next( tokenizer *tok )
|
||||
|
||||
wchar_t *tok_string( tokenizer *tok )
|
||||
{
|
||||
return tok->orig_buff;
|
||||
return tok?tok->orig_buff:0;
|
||||
}
|
||||
|
||||
wchar_t *tok_first( const wchar_t *str )
|
||||
|
||||
@@ -2,6 +2,19 @@
|
||||
<head>
|
||||
<title>fish user documentation</title>
|
||||
<link href="doxygen.css" rel="stylesheet" type="text/css">
|
||||
<!--
|
||||
Override the default doxygen stylesheet to make the difference between different header levels larger
|
||||
-->
|
||||
<style type='text/css'>
|
||||
H2
|
||||
{
|
||||
}
|
||||
|
||||
H3
|
||||
{
|
||||
padding-left:2%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
1
util.c
1
util.c
@@ -809,6 +809,7 @@ int wcsfilecmp( const wchar_t *a, const wchar_t *b )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int secondary_diff=0;
|
||||
if( iswdigit( *a ) && iswdigit( *b ) )
|
||||
{
|
||||
|
||||
12
wildcard.c
12
wildcard.c
@@ -124,6 +124,14 @@ static int wildcard_match2( const wchar_t *str,
|
||||
while( *(str++) != 0 );
|
||||
return 0;
|
||||
}
|
||||
else if( *str == 0 )
|
||||
{
|
||||
/*
|
||||
End of string, but not end of wildcard, and the next wildcard
|
||||
element is not a '*', so this is not a match.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( *wc == ANY_CHAR )
|
||||
{
|
||||
@@ -343,7 +351,7 @@ void get_desc( wchar_t *fn, string_buffer_t *sb, int is_cmd )
|
||||
}
|
||||
else if( sz < 1024 )
|
||||
{
|
||||
sb_printf( sb, L"%dB", sz );
|
||||
sb_printf( sb, L"%lldB", sz );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -597,7 +605,7 @@ int wildcard_expand( const wchar_t *wc,
|
||||
/*
|
||||
The maximum length of a file element
|
||||
*/
|
||||
size_t ln=MAX_FILE_LENGTH;
|
||||
long ln=MAX_FILE_LENGTH;
|
||||
char * narrow_dir_string = wcs2str( dir_string );
|
||||
|
||||
if( narrow_dir_string )
|
||||
|
||||
30
wutil.c
30
wutil.c
@@ -137,16 +137,28 @@ struct wdirent *wreaddir(DIR *dir )
|
||||
|
||||
wchar_t *wgetcwd( wchar_t *buff, size_t sz )
|
||||
{
|
||||
char buffc[sz*MAX_UTF8_BYTES];
|
||||
char *res = getcwd( buffc, sz*MAX_UTF8_BYTES );
|
||||
if( !res )
|
||||
return 0;
|
||||
|
||||
if( (size_t)-1 == mbstowcs( buff, buffc, sizeof( wchar_t ) * sz ) )
|
||||
char *buffc = malloc( sz*MAX_UTF8_BYTES);
|
||||
char *res;
|
||||
wchar_t *ret = 0;
|
||||
|
||||
if( !buffc )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return buff;
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
res = getcwd( buffc, sz*MAX_UTF8_BYTES );
|
||||
if( res )
|
||||
{
|
||||
if( (size_t)-1 != mbstowcs( buff, buffc, sizeof( wchar_t ) * sz ) )
|
||||
{
|
||||
ret = buff;
|
||||
}
|
||||
}
|
||||
|
||||
free( buffc );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wchdir( const wchar_t * dir )
|
||||
|
||||
Reference in New Issue
Block a user