mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-23 21:31:14 -03:00
Compare commits
78 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc42309dd8 | ||
|
|
877b602d6b | ||
|
|
37eb6c340d | ||
|
|
7cd98a670b | ||
|
|
db0eccdc86 | ||
|
|
0f10a3a277 | ||
|
|
312c7ab7b2 | ||
|
|
2e35e1ea60 | ||
|
|
b9c88f4c83 | ||
|
|
5054492c6a | ||
|
|
5893154823 | ||
|
|
4a4e1788e5 | ||
|
|
3d56d7ee32 | ||
|
|
18d06cf10f | ||
|
|
452558624c | ||
|
|
b7ef6852c7 | ||
|
|
fef420d648 | ||
|
|
f2c4becde7 | ||
|
|
e0d6b5c438 | ||
|
|
265d016721 | ||
|
|
495460066c | ||
|
|
8df21a1cb1 | ||
|
|
ba177b48d5 | ||
|
|
29c488c6dc | ||
|
|
14ae10daf7 | ||
|
|
ecdc5bdbc7 | ||
|
|
64fee9865e | ||
|
|
89eb80f3a4 | ||
|
|
9853286bf9 | ||
|
|
7d645ccc53 | ||
|
|
820da6e7f7 | ||
|
|
3466f55ea0 | ||
|
|
b969a175d4 | ||
|
|
bb079f5446 | ||
|
|
250d20bfa8 | ||
|
|
58761f82e7 | ||
|
|
0ccc657aa6 | ||
|
|
7f01570caf | ||
|
|
0dadd83fdd | ||
|
|
3e3541a05a | ||
|
|
a824646d61 | ||
|
|
74fb5bd5e5 | ||
|
|
f2d6ae3220 | ||
|
|
487c275926 | ||
|
|
2f143303b7 | ||
|
|
78296d4fac | ||
|
|
fea22833cd | ||
|
|
b9b09babbe | ||
|
|
ba261cbb55 | ||
|
|
4eb3370edf | ||
|
|
f7a5ca5f1f | ||
|
|
f3c93c1690 | ||
|
|
e55bd063eb | ||
|
|
bdf4214b1f | ||
|
|
9fd20e63cf | ||
|
|
a47065f648 | ||
|
|
70351b0e4f | ||
|
|
12a0f6d72b | ||
|
|
d2c12e760c | ||
|
|
e0c2ce24fb | ||
|
|
1e7dd4f928 | ||
|
|
3259da8f4a | ||
|
|
619f076958 | ||
|
|
588bc1103a | ||
|
|
13e94c0617 | ||
|
|
efd01ae6c6 | ||
|
|
9017df15a8 | ||
|
|
5340d2a18a | ||
|
|
e5298a99f8 | ||
|
|
05736978bb | ||
|
|
e15c7fd7e0 | ||
|
|
509b3598f7 | ||
|
|
aa783fc657 | ||
|
|
84bbbe4252 | ||
|
|
90fbe5eb0b | ||
|
|
d5f4df15d4 | ||
|
|
fd78f67d35 | ||
|
|
28c29f569b |
134
Makefile.in
134
Makefile.in
@@ -28,14 +28,16 @@
|
||||
# hallucinations.
|
||||
#
|
||||
|
||||
# Compiler flags
|
||||
|
||||
# Programs
|
||||
CC := @CC@
|
||||
INSTALL:=@INSTALL@
|
||||
|
||||
# Compiler flags
|
||||
CFLAGS := @CFLAGS@ @INCLUDEDIR@ -Wall -std=gnu99 -fno-strict-aliasing
|
||||
CPPFLAGS=@CPPFLAGS@
|
||||
LDFLAGS:= -l@CURSESLIB@ @LIBS@ @LDFLAGS@ @LIBDIR@
|
||||
INSTALL:=@INSTALL@
|
||||
|
||||
# Installation directories
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
datadir = @datadir@
|
||||
@@ -47,6 +49,10 @@ fishfile = @fishfile@
|
||||
fishinputfile = @fishinputfile@
|
||||
docdir = @docdir@
|
||||
|
||||
#Init files to install
|
||||
INIT_DIR_INSTALL = init/fish_interactive.fish init/fish_function.fish init/fish_complete.fish
|
||||
|
||||
# Set to 1 if we have gettext
|
||||
HAVE_GETTEXT=@HAVE_GETTEXT@
|
||||
|
||||
# All objects used by fish, that are compiled from an ordinary .c file
|
||||
@@ -61,16 +67,27 @@ COMMON_OBJS := function.o builtin.o common.o complete.o env.o exec.o \
|
||||
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
|
||||
COMMON_OBJS_WITH_CODE := builtin_set.o builtin_commandline.o \
|
||||
builtin_ulimit.c builtin_complete.o
|
||||
|
||||
# All objects that the system needs to build fish
|
||||
FISH_OBJS := $(COMMON_OBJS) $(COMMON_OBJS_WITH_CODE) $(COMMON_OBJS_WITH_HEADER) main.o
|
||||
FISH_PAGER_OBJS := fish_pager.o common.o output.o util.o wutil.o tokenizer.o input_common.o env_universal.o env_universal_common.o translate.o
|
||||
FISH_TESTS_OBJS := $(COMMON_OBJS) $(COMMON_OBJS_WITH_CODE) $(COMMON_OBJS_WITH_HEADER) fish_tests.o
|
||||
FISH_OBJS := $(COMMON_OBJS) $(COMMON_OBJS_WITH_CODE) \
|
||||
$(COMMON_OBJS_WITH_HEADER) main.o
|
||||
|
||||
# All objects that the system needs to build fish_pager
|
||||
FISH_PAGER_OBJS := fish_pager.o common.o output.o util.o wutil.o \
|
||||
tokenizer.o input_common.o env_universal.o env_universal_common.o \
|
||||
translate.o
|
||||
|
||||
# All objects that the system needs to build fish_tests
|
||||
FISH_TESTS_OBJS := $(COMMON_OBJS) $(COMMON_OBJS_WITH_CODE) \
|
||||
$(COMMON_OBJS_WITH_HEADER) fish_tests.o
|
||||
|
||||
# All objects that the system needs to build fishd
|
||||
FISHD_OBJS := fishd.o env_universal_common.o common.o util.o wutil.o \
|
||||
doc_src/fishd.o
|
||||
|
||||
|
||||
#All objects that the system needs to build mimedb
|
||||
# All objects needed to build mimedb
|
||||
MIME_OBJS := mimedb.o xdgmimealias.o xdgmime.o xdgmimeglob.o \
|
||||
xdgmimeint.o xdgmimemagic.o xdgmimeparent.o wutil.o
|
||||
|
||||
@@ -79,7 +96,6 @@ MIME_OBJS := mimedb.o xdgmimealias.o xdgmime.o xdgmimeglob.o \
|
||||
# alphabetically, since this is the order in which they will be written
|
||||
# in the help file.
|
||||
#
|
||||
|
||||
BUILTIN_DOC_SRC := doc_src/source.txt doc_src/and.txt \
|
||||
doc_src/begin.txt doc_src/bg.txt doc_src/bind.txt \
|
||||
doc_src/block.txt doc_src/break.txt doc_src/builtin.txt \
|
||||
@@ -103,19 +119,21 @@ BUILTIN_DOC_HDR := $(BUILTIN_DOC_SRC:.txt=.doxygen)
|
||||
# alphabetically, since this is the order in which they will be written
|
||||
# in the help file.
|
||||
#
|
||||
|
||||
CMD_DOC_SRC := doc_src/count.txt doc_src/dirh.txt doc_src/dirs.txt \
|
||||
doc_src/fishd.txt doc_src/help.txt doc_src/mimedb.txt \
|
||||
doc_src/nextd.txt doc_src/open.txt doc_src/popd.txt \
|
||||
doc_src/prevd.txt doc_src/psub.txt doc_src/pushd.txt \
|
||||
doc_src/set_color.txt doc_src/trap.txt doc_src/type.txt \
|
||||
doc_src/umask.txt doc_src/vared.txt
|
||||
doc_src/fish_pager.txt doc_src/fishd.txt doc_src/help.txt \
|
||||
doc_src/mimedb.txt doc_src/nextd.txt doc_src/open.txt \
|
||||
doc_src/popd.txt doc_src/prevd.txt doc_src/psub.txt \
|
||||
doc_src/pushd.txt doc_src/set_color.txt doc_src/trap.txt \
|
||||
doc_src/type.txt doc_src/umask.txt doc_src/vared.txt
|
||||
|
||||
#
|
||||
# Files generated by running doxygen on the files in $(CMD_DOC_SRC)
|
||||
#
|
||||
CMD_DOC_HDR := $(CMD_DOC_SRC:.txt=.doxygen)
|
||||
|
||||
#
|
||||
# Files in the test directory
|
||||
#
|
||||
TEST_IN := $(wildcard tests/test*.in)
|
||||
|
||||
#
|
||||
@@ -134,7 +152,7 @@ MAIN_DIR_FILES := Doxyfile Doxyfile.user Makefile.in configure \
|
||||
$(COMMON_OBJS:.o=.h) $(COMMON_OBJS_WITH_CODE:.o=.c) \
|
||||
$(COMMON_OBJS:.o=.c) builtin_help.hdr fish.spec.in INSTALL README \
|
||||
user_doc.head.html xsel-0.9.6.tar ChangeLog config.sub \
|
||||
config.guess fish_tests.c main.c fish_pager.c fishd.c
|
||||
config.guess fish_tests.c main.c fish_pager.c fishd.c seq.in
|
||||
|
||||
# Files in ./init/
|
||||
INIT_DIR_FILES :=init/fish.in init/fish_complete.fish.in \
|
||||
@@ -148,13 +166,15 @@ TESTS_DIR_FILES := $(TEST_IN) $(TEST_IN:.in=.out) $(TEST_IN:.in=.err) \
|
||||
COMPLETIONS_DIR_FILES := $(wildcard init/completions/*.fish)
|
||||
|
||||
# Programs to build
|
||||
PROGRAMS:=fish set_color @XSEL@ mimedb count fish_pager fishd
|
||||
PROGRAMS:=fish set_color @XSEL@ @SEQ_FALLBACK@ mimedb count fish_pager fishd
|
||||
|
||||
# Manuals to install
|
||||
MANUALS:=doc_src/fish.1 @XSEL_MAN_PATH@ \
|
||||
doc_src/builtin_doc/man/man1/mimedb.1 \
|
||||
doc_src/builtin_doc/man/man1/set_color.1 \
|
||||
doc_src/builtin_doc/man/man1/count.1
|
||||
doc_src/builtin_doc/man/man1/count.1 \
|
||||
doc_src/builtin_doc/man/man1/fishd.1 \
|
||||
doc_src/builtin_doc/man/man1/fish_pager.1
|
||||
|
||||
#All translation message catalogs
|
||||
TRANSLATIONS_SRC := $(wildcard po/*.po)
|
||||
@@ -162,15 +182,19 @@ TRANSLATIONS := $(TRANSLATIONS_SRC:.po=.gmo)
|
||||
|
||||
#Make everything needed for installing fish
|
||||
all: $(PROGRAMS) user_doc
|
||||
@echo fish has now been built.
|
||||
@echo Use \'make install\' to install fish.
|
||||
.PHONY: all
|
||||
|
||||
debug:
|
||||
make fish CFLAGS="-O0 -Wno-unused -Werror -g @INCLUDEDIR@ -Wall -std=gnu99 -fno-strict-aliasing"
|
||||
.PHONY: debug
|
||||
|
||||
# User documentation, describing the features of the fish shell.
|
||||
user_doc: doc.h Doxyfile.user user_doc.head.html
|
||||
doxygen Doxyfile.user
|
||||
|
||||
#Source code documentation. Also includes user documentation.
|
||||
# Source code documentation. Also includes user documentation.
|
||||
doc: *.h *.c doc.h Doxyfile builtin_help.c
|
||||
doxygen;
|
||||
|
||||
@@ -184,6 +208,7 @@ doc/refman.pdf: doc
|
||||
|
||||
test: $(PROGRAMS) fish_tests
|
||||
./fish_tests; cd tests; ../fish <test.fish;
|
||||
.PHONY: test
|
||||
|
||||
xsel-0.9.6:
|
||||
tar -xf xsel-0.9.6.tar
|
||||
@@ -215,26 +240,30 @@ doc.h:$(BUILTIN_DOC_SRC) $(CMD_DOC_SRC) doc_src/doc.hdr
|
||||
echo "*/" >>$@
|
||||
|
||||
# Compile translation file
|
||||
%.gmo:%.po
|
||||
%.gmo:
|
||||
if test $(HAVE_GETTEXT) = 1; then \
|
||||
msgfmt $*.po -o $*.gmo; \
|
||||
fi
|
||||
|
||||
# Update existing po file or copy messages.pot
|
||||
%.po: messages.pot
|
||||
%.po:messages.pot
|
||||
if test $(HAVE_GETTEXT) = 1;then \
|
||||
if test -f $*.po; then \
|
||||
msgmerge -U --backup=existing --no-wrap $*.po messages.pot;\
|
||||
msgmerge -U --backup=existing $*.po messages.pot;\
|
||||
else \
|
||||
cp messages.pot $*.po;\
|
||||
fi; \
|
||||
fi
|
||||
|
||||
# Create a template translation object
|
||||
messages.pot: *.c *.h init/*.in init/*.fish init/completions/*.fish
|
||||
messages.pot: *.c *.h init/*.in init/*.fish init/completions/*.fish seq
|
||||
if test $(HAVE_GETTEXT) = 1;then \
|
||||
xgettext -k_ -kN_ -kcomplete_desc --no-wrap *.c *.h -o messages.pot; \
|
||||
xgettext -j -k_ -LShell --no-wrap init/*.in init/*.fish init/completions/*.fish -o messages.pot; \
|
||||
xgettext -k_ -kN_ -kcomplete_desc *.c *.h -o messages.pot; \
|
||||
if ! xgettext -j -k_ -LShell init/*.in init/*.fish init/completions/*.fish seq -o messages.pot; then \
|
||||
echo "Your xgettext version is too old to build the messages.pot file"\
|
||||
rm messages.pot\
|
||||
false;\
|
||||
fi; \
|
||||
fi
|
||||
|
||||
# Generate the internal help functions by making doxygen create
|
||||
@@ -272,6 +301,7 @@ messages.pot: *.c *.h init/*.in init/*.fish init/completions/*.fish
|
||||
builtin_help.c: $(BUILTIN_DOC_HDR) doc_src/count.doxygen gen_hdr2 gen_hdr.sh builtin_help.hdr $(CMD_DOC_HDR)
|
||||
cd doc_src; doxygen; cd ..;
|
||||
cp builtin_help.hdr builtin_help.c;
|
||||
chmod 755 gen_hdr.sh
|
||||
for i in $(BUILTIN_DOC_HDR) doc_src/count.doxygen ; do \
|
||||
echo ' hash_put( &tbl, L"'`basename $$i .doxygen`'",' >>$@; \
|
||||
./gen_hdr.sh $$i >>$@; \
|
||||
@@ -293,11 +323,16 @@ builtin_help.c: $(BUILTIN_DOC_HDR) doc_src/count.doxygen gen_hdr2 gen_hdr.sh bui
|
||||
echo "void print_help()" >>$@
|
||||
echo "{" >>$@
|
||||
echo ' printf( "%s",' >>$@
|
||||
chmod 755 gen_hdr.sh
|
||||
./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
|
||||
#
|
||||
|
||||
install: all install-translations
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(bindir)
|
||||
for i in $(PROGRAMS); do\
|
||||
@@ -306,7 +341,7 @@ install: all install-translations
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(sysconfdir)$(fishdir)
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(sysconfdir)$(fishdir)/completions
|
||||
$(INSTALL) -m 644 init/fish $(DESTDIR)$(sysconfdir)$(fishfile)
|
||||
for i in init/fish_interactive.fish init/fish_function.fish init/fish_complete.fish ; do \
|
||||
for i in $(INIT_DIR_INSTALL); do \
|
||||
$(INSTALL) -m 644 $$i $(DESTDIR)$(sysconfdir)$(fishdir); \
|
||||
done;
|
||||
for i in $(COMPLETIONS_DIR_FILES); do \
|
||||
@@ -323,8 +358,15 @@ install: all install-translations
|
||||
for i in $(MANUALS); do \
|
||||
$(INSTALL) -m 644 $$i $(DESTDIR)$(mandir)/man1/; \
|
||||
done;
|
||||
@echo If you want to use fish as the default shell, remember to first
|
||||
@echo add the line \'$(DESTDIR)$(bindir)/fish\' to the file \'/etc/shells\'.
|
||||
@echo fish is now installed on your system.
|
||||
@echo To run fish, type \'fish\' in your terminal.
|
||||
@echo
|
||||
@echo To use fish as your login shell:
|
||||
@echo \* add the line \'$(DESTDIR)$(bindir)/fish\' to the file \'/etc/shells\'.
|
||||
@echo \* use the command \'chsh -s $(DESTDIR)$(bindir)/fish\'.
|
||||
@echo
|
||||
@echo Have fun!
|
||||
.PHONY: install
|
||||
|
||||
uninstall: uninstall-translations
|
||||
for i in $(PROGRAMS); do \
|
||||
@@ -335,34 +377,40 @@ uninstall: uninstall-translations
|
||||
rm -f $(DESTDIR)$(sysconfdir)$(fishinputfile)
|
||||
rm -r $(DESTDIR)$(sysconfdir)$(fishdir)
|
||||
rm -r $(DESTDIR)$(docdir)
|
||||
for i in fish.1* @XSEL_MAN@ mimedb.1* set_color.1* count.1*; do \
|
||||
for i in fish.1* @XSEL_MAN@ mimedb.1* fishd.1* set_color.1* count.1*; do \
|
||||
rm $(DESTDIR)$(mandir)/man1/$$i; \
|
||||
done;
|
||||
.PHONY: uninstall
|
||||
|
||||
install-translations: $(TRANSLATIONS)
|
||||
if test $(HAVE_GETTEXT) = 1; then \
|
||||
for i in $(TRANSLATIONS); do \
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/locale/$$(basename $$i .gmo)/LC_MESSAGES; \
|
||||
$(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/locale/$$(basename $$i .gmo)/LC_MESSAGES/fish.mo; \
|
||||
echo $(DESTDIR)$(datadir)/locale/$$(basename $$i .gmo)/LC_MESSAGES/fish.mo;\
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/locale/`basename $$i .gmo`/LC_MESSAGES; \
|
||||
$(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/locale/`basename $$i .gmo`/LC_MESSAGES/fish.mo; \
|
||||
echo $(DESTDIR)$(datadir)/locale/`basename $$i .gmo`/LC_MESSAGES/fish.mo;\
|
||||
done; \
|
||||
fi
|
||||
.PHONY: install-translations
|
||||
|
||||
uninstall-translations:
|
||||
if test $(HAVE_GETTEXT) = 1; then \
|
||||
for i in $(TRANSLATIONS_SRC); do \
|
||||
rm -f $(DESTDIR)$(datadir)/locale/$$(basename $$i .po)/LC_MESSAGES/fish.mo; \
|
||||
rm -f $(DESTDIR)$(datadir)/locale/`basename $$i .po`/LC_MESSAGES/fish.mo; \
|
||||
done; \
|
||||
fi
|
||||
.PHONY: uninstall-translations
|
||||
|
||||
#
|
||||
# The build rules for all the commands
|
||||
#
|
||||
|
||||
# The fish shell
|
||||
fish: $(FISH_OBJS)
|
||||
$(CC) $(FISH_OBJS) $(LDFLAGS) -o $@
|
||||
|
||||
fish_pager: $(FISH_PAGER_OBJS)
|
||||
$(CC) $(FISH_PAGER_OBJS) $(LDFLAGS) -o $@
|
||||
|
||||
fishd: $(FISHD_OBJS)
|
||||
fishd: $(FISHD_OBJS)
|
||||
$(CC) $(FISHD_OBJS) $(LDFLAGS) -o $@
|
||||
|
||||
fish_tests: $(FISH_TESTS_OBJS)
|
||||
@@ -379,11 +427,16 @@ set_color: set_color.o doc_src/set_color.c
|
||||
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 $@
|
||||
|
||||
#
|
||||
# Update dependencies
|
||||
#
|
||||
depend:
|
||||
makedepend -fMakefile.in -Y *.c
|
||||
.PHONY: depend
|
||||
|
||||
# Copy all the source files into a new directory and use tar to create
|
||||
# an archive from it. Simplest way I could think of to make an archive
|
||||
@@ -391,7 +444,7 @@ depend:
|
||||
#
|
||||
# Uses install instead of mkdir so build won't fail if the directory
|
||||
# exists
|
||||
fish-@PACKAGE_VERSION@.tar: $(DOC_SRC_DIR_FILES) $(MAIN_DIR_FILES) $(INIT_DIR_FILES) $(TEST_DIR_FILES) $(COMPLETIONS_DIR_FILES) ChangeLog $(TRANSLATIONS_SRC)
|
||||
fish-@PACKAGE_VERSION@.tar: $(DOC_SRC_DIR_FILES) $(MAIN_DIR_FILES) $(INIT_DIR_FILES) $(TEST_DIR_FILES) $(COMPLETIONS_DIR_FILES) ChangeLog
|
||||
rm -rf fish-@PACKAGE_VERSION@
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@/doc_src
|
||||
@@ -422,11 +475,17 @@ rpm: fish-@PACKAGE_VERSION@.tar.bz2
|
||||
rpmbuild -ba --clean /usr/src/redhat/SPECS/fish.spec
|
||||
mv /usr/src/redhat/RPMS/*/fish*@PACKAGE_VERSION@*.rpm .
|
||||
mv /usr/src/redhat/SRPMS/fish*@PACKAGE_VERSION@*.src.rpm .
|
||||
.PHONY: rpm
|
||||
|
||||
#
|
||||
# Cleanup targets
|
||||
#
|
||||
|
||||
distclean: clean
|
||||
rm -f fish.spec doc_src/fish.1 doc_src/Doxyfile
|
||||
rm -f init/fish init/fish_interactive.fish init/fish_complete.fish
|
||||
rm -f config.status config.log config.h Makefile
|
||||
.PHONY: distclean
|
||||
|
||||
clean:
|
||||
rm -f *.o doc.h doc_src/*.doxygen doc_src/*.c builtin_help.c
|
||||
@@ -442,6 +501,7 @@ clean:
|
||||
rm -rf fish-@PACKAGE_VERSION@
|
||||
rm -rf xsel-0.9.6/
|
||||
rm -f $(TRANSLATIONS)
|
||||
.PHONY: clean
|
||||
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
||||
|
||||
424
builtin.c
424
builtin.c
@@ -276,16 +276,10 @@ static int builtin_block( wchar_t **argv )
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
|
||||
int scope=UNSET;
|
||||
|
||||
int erase = 0;
|
||||
|
||||
int argc=builtin_count_args( argv );
|
||||
|
||||
int type = (1<<EVENT_ANY);
|
||||
|
||||
int type = (1<<EVENT_ANY);
|
||||
|
||||
woptind=0;
|
||||
|
||||
@@ -646,6 +640,10 @@ static int builtin_exec( wchar_t **argv )
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
Print the definition of the given function to sb_out
|
||||
stringbuffer. Used by the functions builtin.
|
||||
*/
|
||||
static void functions_def( wchar_t *name )
|
||||
{
|
||||
const wchar_t *desc = function_get_desc( name );
|
||||
@@ -653,15 +651,15 @@ static void functions_def( wchar_t *name )
|
||||
|
||||
array_list_t ev;
|
||||
event_t search;
|
||||
|
||||
|
||||
int i;
|
||||
|
||||
|
||||
search.function_name = name;
|
||||
search.type = EVENT_ANY;
|
||||
|
||||
|
||||
al_init( &ev );
|
||||
event_get( &search, &ev );
|
||||
|
||||
|
||||
sb_append2( sb_out,
|
||||
L"function ",
|
||||
name,
|
||||
@@ -670,11 +668,11 @@ static void functions_def( wchar_t *name )
|
||||
if( desc && wcslen(desc) )
|
||||
{
|
||||
wchar_t *esc_desc = escape( desc, 1 );
|
||||
|
||||
|
||||
sb_append2( sb_out, L" --description ", esc_desc, (void *)0 );
|
||||
free( esc_desc );
|
||||
}
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( &ev); i++ )
|
||||
{
|
||||
event_t *next = (event_t *)al_get( &ev, i );
|
||||
@@ -685,7 +683,7 @@ static void functions_def( wchar_t *name )
|
||||
sb_printf( sb_out, L" --on-signal %ls", sig2wcs( next->param1.signal ) );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case EVENT_VARIABLE:
|
||||
{
|
||||
sb_printf( sb_out, L" --on-variable %ls", next->param1.variable );
|
||||
@@ -710,17 +708,17 @@ static void functions_def( wchar_t *name )
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
al_destroy( &ev );
|
||||
|
||||
|
||||
sb_append2( sb_out,
|
||||
L"\n\t",
|
||||
def,
|
||||
L"\nend\n\n",
|
||||
(void *)0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -740,7 +738,7 @@ static int builtin_functions( wchar_t **argv )
|
||||
int list=0;
|
||||
int show_hidden=0;
|
||||
int res = 0;
|
||||
|
||||
|
||||
woptind=0;
|
||||
|
||||
const static struct woption
|
||||
@@ -771,7 +769,7 @@ static int builtin_functions( wchar_t **argv )
|
||||
while( 1 )
|
||||
{
|
||||
int opt_index = 0;
|
||||
|
||||
|
||||
int opt = wgetopt_long( argc,
|
||||
argv,
|
||||
L"ed:na",
|
||||
@@ -779,7 +777,7 @@ static int builtin_functions( wchar_t **argv )
|
||||
&opt_index );
|
||||
if( opt == -1 )
|
||||
break;
|
||||
|
||||
|
||||
switch( opt )
|
||||
{
|
||||
case 0:
|
||||
@@ -816,10 +814,8 @@ static int builtin_functions( wchar_t **argv )
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Erase, desc and list are mutually exclusive
|
||||
@@ -829,13 +825,12 @@ static int builtin_functions( wchar_t **argv )
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: Invalid combination of options\n" ),
|
||||
argv[0] );
|
||||
|
||||
|
||||
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if( erase )
|
||||
{
|
||||
@@ -911,7 +906,7 @@ static int builtin_functions( wchar_t **argv )
|
||||
(void *)0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
free( names_arr );
|
||||
al_destroy( &names );
|
||||
return 0;
|
||||
@@ -933,16 +928,14 @@ static int builtin_functions( wchar_t **argv )
|
||||
for( i=0; i<al_get_count( &names ); i++ )
|
||||
{
|
||||
functions_def( names_arr[i] );
|
||||
|
||||
}
|
||||
free( names_arr );
|
||||
al_destroy( &names );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
{
|
||||
|
||||
for( i=woptind; i<argc; i++ )
|
||||
{
|
||||
if( !function_exists( argv[i] ) )
|
||||
@@ -952,23 +945,19 @@ static int builtin_functions( wchar_t **argv )
|
||||
functions_def( argv[i] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Test whether the specified string is a valid name for a keybinding
|
||||
*/
|
||||
static int wcsbindingname( wchar_t *str )
|
||||
{
|
||||
|
||||
|
||||
{
|
||||
while( *str )
|
||||
{
|
||||
if( (!iswalnum(*str)) && (*str != L'-' ) )
|
||||
@@ -1063,10 +1052,9 @@ static int builtin_function( wchar_t **argv )
|
||||
argv[0],
|
||||
long_options[opt_index].name );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
|
||||
res = 1;
|
||||
break;
|
||||
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
desc=woptarg;
|
||||
@@ -1960,258 +1948,7 @@ static int builtin_cd( wchar_t **argv )
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
The complete builtin. Used for specifying programmable
|
||||
tab-completions. Calls the functions in complete.c for any heavy
|
||||
lifting.
|
||||
*/
|
||||
static int builtin_complete( wchar_t **argv )
|
||||
{
|
||||
|
||||
int argc=0;
|
||||
int result_mode=SHARED, long_mode=0;
|
||||
int cmd_type=-1;
|
||||
int remove = 0;
|
||||
int authorative = 1;
|
||||
|
||||
wchar_t *cmd=0, short_opt=L'\0', *long_opt=L"", *comp=L"", *desc=L"", *condition=L"", *load=0;
|
||||
|
||||
argc = builtin_count_args( argv );
|
||||
|
||||
woptind=0;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
const static struct woption
|
||||
long_options[] =
|
||||
{
|
||||
{
|
||||
L"exclusive", no_argument, 0, 'x'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"no-files", no_argument, 0, 'f'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"require-parameter", no_argument, 0, 'r'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"path", required_argument, 0, 'p'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"command", required_argument, 0, 'c'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"short-option", required_argument, 0, 's'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"long-option", required_argument, 0, 'l' }
|
||||
,
|
||||
{
|
||||
L"old-option", required_argument, 0, 'o'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"description", required_argument, 0, 'd'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"arguments", required_argument, 0, 'a'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"erase", no_argument, 0, 'e'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"unauthorative", no_argument, 0, 'u'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"condition", required_argument, 0, 'n'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"load", required_argument, 0, 'y'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
int opt_index = 0;
|
||||
|
||||
int opt = wgetopt_long( argc,
|
||||
argv,
|
||||
L"a:c:p:s:l:o:d:frxeun:y:",
|
||||
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 'x':
|
||||
result_mode |= EXCLUSIVE;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
result_mode |= NO_FILES;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
result_mode |= NO_COMMON;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
cmd_type = PATH;
|
||||
cmd = expand_unescape( woptarg, 1);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
cmd_type = COMMAND;
|
||||
cmd = expand_unescape( woptarg, 1);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
desc = woptarg;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
authorative=0;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if( wcslen( woptarg ) > 1 )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: Parameter '%ls' is too long\n" ),
|
||||
argv[0],
|
||||
woptarg );
|
||||
|
||||
sb_append( sb_err,
|
||||
parser_current_line() );
|
||||
// builtin_print_help( argv[0], sb_err );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
short_opt = woptarg[0];
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
long_opt = woptarg;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
long_mode=1;
|
||||
long_opt = woptarg;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
comp = woptarg;
|
||||
break;
|
||||
|
||||
|
||||
case 'e':
|
||||
remove = 1;
|
||||
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
condition = woptarg;
|
||||
break;
|
||||
|
||||
case 'y':
|
||||
load = woptarg;
|
||||
break;
|
||||
|
||||
|
||||
case '?':
|
||||
// builtin_print_help( argv[0], sb_err );
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( woptind != argc )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: Too many arguments\n" ),
|
||||
argv[0] );
|
||||
sb_append( sb_err,
|
||||
parser_current_line() );
|
||||
// builtin_print_help( argv[0], sb_err );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( load )
|
||||
{
|
||||
complete_load( load, 1 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if( cmd == 0 )
|
||||
{
|
||||
/* No arguments specified, meaning we print the definitions of
|
||||
* all specified completions to stdout.*/
|
||||
complete_print( sb_out );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( remove )
|
||||
{
|
||||
/* Remove the specified completion */
|
||||
complete_remove( cmd,
|
||||
cmd_type,
|
||||
short_opt,
|
||||
long_opt );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Add the specified completion */
|
||||
complete_add( cmd,
|
||||
cmd_type,
|
||||
short_opt,
|
||||
long_opt,
|
||||
long_mode,
|
||||
result_mode,
|
||||
authorative,
|
||||
condition,
|
||||
comp,
|
||||
desc );
|
||||
}
|
||||
free( cmd );
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
The . (dot) builtin, sometimes called source. Evaluates the contents of a file.
|
||||
@@ -2321,14 +2058,20 @@ static int builtin_fg( wchar_t **argv )
|
||||
if( argv[1] == 0 )
|
||||
{
|
||||
/*
|
||||
Last constructed job in the job que by default
|
||||
Select last constructed job (I.e. first job in the job que) that is possible to put in the foreground
|
||||
*/
|
||||
for( j=first_job; ((j!=0) && (!j->constructed)); j=j->next )
|
||||
;
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: There are no jobs\n" ),
|
||||
argv[0] );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
for( j=first_job; j; j=j->next )
|
||||
{
|
||||
if( j->constructed && (!job_is_completed(j)) && (job_is_stopped(j) || !j->fg))
|
||||
break;
|
||||
}
|
||||
if( !j )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: There are no suitable jobs\n" ),
|
||||
argv[0] );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
}
|
||||
}
|
||||
else if( argv[2] != 0 )
|
||||
{
|
||||
@@ -2355,20 +2098,24 @@ static int builtin_fg( wchar_t **argv )
|
||||
}
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
|
||||
return 1;
|
||||
j=0;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
int pid = abs(wcstol( argv[1], 0, 10 ));
|
||||
j = job_get_from_pid( pid );
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: No suitable job: %d\n" ),
|
||||
argv[0],
|
||||
pid );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
if( !j )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: No suitable job: %d\n" ),
|
||||
argv[0],
|
||||
pid );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
}
|
||||
}
|
||||
|
||||
if( j != 0 )
|
||||
|
||||
if( j )
|
||||
{
|
||||
if( builtin_err_redirect )
|
||||
{
|
||||
@@ -2389,26 +2136,25 @@ static int builtin_fg( wchar_t **argv )
|
||||
j->job_id,
|
||||
j->command );
|
||||
}
|
||||
}
|
||||
|
||||
wchar_t *ft = tok_first( j->command );
|
||||
if( ft != 0 )
|
||||
env_set( L"_", ft, ENV_EXPORT );
|
||||
free(ft);
|
||||
reader_write_title();
|
||||
|
||||
make_first( j );
|
||||
j->fg=1;
|
||||
|
||||
wchar_t *ft = tok_first( j->command );
|
||||
if( ft != 0 )
|
||||
env_set( L"_", ft, ENV_EXPORT );
|
||||
free(ft);
|
||||
reader_write_title();
|
||||
|
||||
job_continue( j, job_is_stopped(j) );
|
||||
return 0;
|
||||
make_first( j );
|
||||
j->fg=1;
|
||||
|
||||
job_continue( j, job_is_stopped(j) );
|
||||
}
|
||||
return j != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Helper function for builtin_bg()
|
||||
*/
|
||||
static void send_to_bg( job_t *j, const wchar_t *name )
|
||||
static int send_to_bg( job_t *j, const wchar_t *name )
|
||||
{
|
||||
if( j == 0 )
|
||||
{
|
||||
@@ -2417,7 +2163,7 @@ static void send_to_bg( job_t *j, const wchar_t *name )
|
||||
L"bg",
|
||||
name );
|
||||
builtin_print_help( L"bg", sb_err );
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2429,6 +2175,7 @@ static void send_to_bg( job_t *j, const wchar_t *name )
|
||||
make_first( j );
|
||||
j->fg=0;
|
||||
job_continue( j, job_is_stopped(j) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -2437,20 +2184,38 @@ static void send_to_bg( job_t *j, const wchar_t *name )
|
||||
*/
|
||||
static int builtin_bg( wchar_t **argv )
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
if( argv[1] == 0 )
|
||||
{
|
||||
job_t *j;
|
||||
for( j=first_job; ((j!=0) && (!j->constructed) && (!job_is_stopped(j))); j=j->next )
|
||||
;
|
||||
send_to_bg( j, _(L"(default)" ) );
|
||||
return 0;
|
||||
for( j=first_job; j; j=j->next )
|
||||
{
|
||||
if( job_is_stopped(j) )
|
||||
break;
|
||||
}
|
||||
|
||||
if( !j )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: There are no suitable jobs\n" ),
|
||||
argv[0] );
|
||||
res = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = send_to_bg( j, _(L"(default)" ) );
|
||||
}
|
||||
}
|
||||
for( argv++; *argv != 0; argv++ )
|
||||
else
|
||||
{
|
||||
int pid = wcstol( *argv, 0, 10 );
|
||||
send_to_bg( job_get_from_pid( pid ), *argv);
|
||||
for( argv++; !res && *argv != 0; argv++ )
|
||||
{
|
||||
int pid = wcstol( *argv, 0, 10 );
|
||||
res |= send_to_bg( job_get_from_pid( pid ), *argv);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -2483,6 +2248,9 @@ static int cpu_use( job_t *j )
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
Print information about the specified job
|
||||
*/
|
||||
static void builtin_jobs_print( job_t *j, int mode, int header )
|
||||
{
|
||||
process_t *p;
|
||||
|
||||
13
builtin.h
13
builtin.h
@@ -47,8 +47,14 @@ enum
|
||||
*/
|
||||
#define BUILTIN_ERR_UNKNOWN _( L"%ls: Unknown option '%ls'\n" )
|
||||
|
||||
/**
|
||||
Error message for invalid character in variable name
|
||||
*/
|
||||
#define BUILTIN_ERR_VARCHAR _( L"%ls: Invalid character '%lc' in variable name. Only alphanumerical characters and underscores are valid in a variable name.\n" )
|
||||
|
||||
/**
|
||||
Error message for invalid (empty) variable name
|
||||
*/
|
||||
#define BUILTIN_ERR_VARNAME_ZERO _( L"%ls: Variable name can not be the empty string\n" )
|
||||
|
||||
/**
|
||||
@@ -146,6 +152,13 @@ int builtin_commandline(wchar_t **argv);
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
int builtin_complete(wchar_t **argv);
|
||||
|
||||
/**
|
||||
This function works like wperror, but it prints its result into
|
||||
the sb_err string_buffer_t instead of to stderr. Used by the builtin
|
||||
|
||||
@@ -13,6 +13,7 @@ Functions used for implementing the commandline builtin.
|
||||
|
||||
#include "config.h"
|
||||
#include "util.h"
|
||||
#include "wutil.h"
|
||||
#include "builtin.h"
|
||||
#include "common.h"
|
||||
#include "wgetopt.h"
|
||||
|
||||
485
builtin_complete.c
Normal file
485
builtin_complete.c
Normal file
@@ -0,0 +1,485 @@
|
||||
/** \file builtin_complete.c Functions defining the complete builtin
|
||||
|
||||
Functions used for implementing the complete builtin.
|
||||
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <termios.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "util.h"
|
||||
#include "wutil.h"
|
||||
#include "builtin.h"
|
||||
#include "common.h"
|
||||
#include "complete.h"
|
||||
#include "wgetopt.h"
|
||||
#include "parser.h"
|
||||
#include "translate.h"
|
||||
|
||||
/*
|
||||
builtin_complete_* are a set of rather silly looping functions that
|
||||
make sure that all the proper combinations of complete_add or
|
||||
complete_remove get called.
|
||||
*/
|
||||
|
||||
static void builtin_complete_add2( const wchar_t *cmd,
|
||||
int cmd_type,
|
||||
const wchar_t *short_opt,
|
||||
array_list_t *gnu_opt,
|
||||
array_list_t *old_opt,
|
||||
int result_mode,
|
||||
int authorative,
|
||||
const wchar_t *condition,
|
||||
const wchar_t *comp,
|
||||
const wchar_t *desc )
|
||||
{
|
||||
int i;
|
||||
const wchar_t *s;
|
||||
|
||||
for( s=short_opt; *s; s++ )
|
||||
{
|
||||
complete_add( cmd,
|
||||
cmd_type,
|
||||
*s,
|
||||
0,
|
||||
0,
|
||||
result_mode,
|
||||
authorative,
|
||||
condition,
|
||||
comp,
|
||||
desc );
|
||||
}
|
||||
|
||||
for( i=0; i<al_get_count( gnu_opt ); i++ )
|
||||
{
|
||||
complete_add( cmd,
|
||||
cmd_type,
|
||||
0,
|
||||
(wchar_t *)al_get(gnu_opt, i ),
|
||||
0,
|
||||
result_mode,
|
||||
authorative,
|
||||
condition,
|
||||
comp,
|
||||
desc );
|
||||
}
|
||||
|
||||
for( i=0; i<al_get_count( old_opt ); i++ )
|
||||
{
|
||||
complete_add( cmd,
|
||||
cmd_type,
|
||||
0,
|
||||
(wchar_t *)al_get(old_opt, i ),
|
||||
1,
|
||||
result_mode,
|
||||
authorative,
|
||||
condition,
|
||||
comp,
|
||||
desc );
|
||||
}
|
||||
|
||||
if( al_get_count( old_opt )+al_get_count( gnu_opt )+wcslen(short_opt) == 0 )
|
||||
{
|
||||
complete_add( cmd,
|
||||
cmd_type,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
result_mode,
|
||||
authorative,
|
||||
condition,
|
||||
comp,
|
||||
desc );
|
||||
}
|
||||
}
|
||||
|
||||
static void builtin_complete_add( array_list_t *cmd,
|
||||
array_list_t *path,
|
||||
const wchar_t *short_opt,
|
||||
array_list_t *gnu_opt,
|
||||
array_list_t *old_opt,
|
||||
int result_mode,
|
||||
int authorative,
|
||||
const wchar_t *condition,
|
||||
const wchar_t *comp,
|
||||
const wchar_t *desc )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i=0; i<al_get_count( cmd ); i++ )
|
||||
{
|
||||
builtin_complete_add2( al_get( cmd, i ),
|
||||
COMMAND,
|
||||
short_opt,
|
||||
gnu_opt,
|
||||
old_opt,
|
||||
result_mode,
|
||||
authorative,
|
||||
condition,
|
||||
comp,
|
||||
desc );
|
||||
}
|
||||
|
||||
for( i=0; i<al_get_count( path ); i++ )
|
||||
{
|
||||
builtin_complete_add2( al_get( path, i ),
|
||||
PATH,
|
||||
short_opt,
|
||||
gnu_opt,
|
||||
old_opt,
|
||||
result_mode,
|
||||
authorative,
|
||||
condition,
|
||||
comp,
|
||||
desc );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void builtin_complete_remove3( wchar_t *cmd,
|
||||
int cmd_type,
|
||||
wchar_t short_opt,
|
||||
array_list_t *long_opt )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i=0; i<al_get_count( long_opt ); i++ )
|
||||
{
|
||||
complete_remove( cmd,
|
||||
cmd_type,
|
||||
short_opt,
|
||||
(wchar_t *)al_get( long_opt, i ) );
|
||||
}
|
||||
}
|
||||
|
||||
static void builtin_complete_remove2( wchar_t *cmd,
|
||||
int cmd_type,
|
||||
const wchar_t *short_opt,
|
||||
array_list_t *gnu_opt,
|
||||
array_list_t *old_opt )
|
||||
{
|
||||
const wchar_t *s = (wchar_t *)short_opt;
|
||||
if( *s )
|
||||
{
|
||||
for( ; *s; s++ )
|
||||
{
|
||||
if( al_get_count( old_opt) + al_get_count( gnu_opt ) == 0 )
|
||||
{
|
||||
complete_remove(cmd,
|
||||
cmd_type,
|
||||
*s,
|
||||
0 );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
builtin_complete_remove3( cmd,
|
||||
cmd_type,
|
||||
*s,
|
||||
gnu_opt );
|
||||
builtin_complete_remove3( cmd,
|
||||
cmd_type,
|
||||
*s,
|
||||
old_opt );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
builtin_complete_remove3( cmd,
|
||||
cmd_type,
|
||||
0,
|
||||
gnu_opt );
|
||||
builtin_complete_remove3( cmd,
|
||||
cmd_type,
|
||||
0,
|
||||
old_opt );
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void builtin_complete_remove( array_list_t *cmd,
|
||||
array_list_t *path,
|
||||
const wchar_t *short_opt,
|
||||
array_list_t *gnu_opt,
|
||||
array_list_t *old_opt )
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
for( i=0; i<al_get_count( cmd ); i++ )
|
||||
{
|
||||
builtin_complete_remove2( (wchar_t *)al_get( cmd, i ),
|
||||
COMMAND,
|
||||
short_opt,
|
||||
gnu_opt,
|
||||
old_opt );
|
||||
}
|
||||
|
||||
for( i=0; i<al_get_count( path ); i++ )
|
||||
{
|
||||
builtin_complete_remove2( (wchar_t *)al_get( path, i ),
|
||||
PATH,
|
||||
short_opt,
|
||||
gnu_opt,
|
||||
old_opt );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int builtin_complete( wchar_t **argv )
|
||||
{
|
||||
int res=0;
|
||||
int argc=0;
|
||||
int result_mode=SHARED;
|
||||
int remove = 0;
|
||||
int authorative = 1;
|
||||
|
||||
string_buffer_t short_opt;
|
||||
array_list_t gnu_opt, old_opt;
|
||||
wchar_t *comp=L"", *desc=L"", *condition=L"", *load=0;
|
||||
|
||||
array_list_t cmd;
|
||||
array_list_t path;
|
||||
|
||||
al_init( &cmd );
|
||||
al_init( &path );
|
||||
sb_init( &short_opt );
|
||||
al_init( &gnu_opt );
|
||||
al_init( &old_opt );
|
||||
|
||||
argc = builtin_count_args( argv );
|
||||
|
||||
woptind=0;
|
||||
|
||||
while( res == 0 )
|
||||
{
|
||||
const static struct woption
|
||||
long_options[] =
|
||||
{
|
||||
{
|
||||
L"exclusive", no_argument, 0, 'x'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"no-files", no_argument, 0, 'f'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"require-parameter", no_argument, 0, 'r'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"path", required_argument, 0, 'p'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"command", required_argument, 0, 'c'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"short-option", required_argument, 0, 's'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"long-option", required_argument, 0, 'l' }
|
||||
,
|
||||
{
|
||||
L"old-option", required_argument, 0, 'o'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"description", required_argument, 0, 'd'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"arguments", required_argument, 0, 'a'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"erase", no_argument, 0, 'e'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"unauthorative", no_argument, 0, 'u'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"condition", required_argument, 0, 'n'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"load", required_argument, 0, 'y'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
int opt_index = 0;
|
||||
|
||||
int opt = wgetopt_long( argc,
|
||||
argv,
|
||||
L"a:c:p:s:l:o:d:frxeun:y:",
|
||||
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 );
|
||||
|
||||
|
||||
res = 1;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
result_mode |= EXCLUSIVE;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
result_mode |= NO_FILES;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
result_mode |= NO_COMMON;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
al_push( &cmd, unescape( woptarg, 1));
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
al_push( &cmd, unescape( woptarg, 1) );
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
desc = woptarg;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
authorative=0;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
sb_append( &short_opt, woptarg );
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
al_push( &gnu_opt, woptarg );
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
al_push( &old_opt, woptarg );
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
comp = woptarg;
|
||||
break;
|
||||
|
||||
|
||||
case 'e':
|
||||
remove = 1;
|
||||
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
condition = woptarg;
|
||||
break;
|
||||
|
||||
case 'y':
|
||||
load = woptarg;
|
||||
break;
|
||||
|
||||
|
||||
case '?':
|
||||
// builtin_print_help( argv[0], sb_err );
|
||||
|
||||
res = 1;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( res != 0 )
|
||||
{
|
||||
}
|
||||
else if( woptind != argc )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: Too many arguments\n" ),
|
||||
argv[0] );
|
||||
sb_append( sb_err,
|
||||
parser_current_line() );
|
||||
// builtin_print_help( argv[0], sb_err );
|
||||
|
||||
res = 1;
|
||||
}
|
||||
else if( load )
|
||||
{
|
||||
complete_load( load, 1 );
|
||||
}
|
||||
else if( (al_get_count( &cmd) == 0 ) && (al_get_count( &path) == 0 ) )
|
||||
{
|
||||
/* No arguments specified, meaning we print the definitions of
|
||||
* all specified completions to stdout.*/
|
||||
complete_print( sb_out );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( remove )
|
||||
{
|
||||
builtin_complete_remove( &cmd,
|
||||
&path,
|
||||
(wchar_t *)short_opt.buff,
|
||||
&gnu_opt,
|
||||
&old_opt );
|
||||
}
|
||||
else
|
||||
{
|
||||
builtin_complete_add( &cmd,
|
||||
&path,
|
||||
(wchar_t *)short_opt.buff,
|
||||
&gnu_opt,
|
||||
&old_opt,
|
||||
result_mode,
|
||||
authorative,
|
||||
condition,
|
||||
comp,
|
||||
desc );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
al_foreach( &cmd, (void (*)(const void *))&free );
|
||||
al_foreach( &path, (void (*)(const void *))&free );
|
||||
|
||||
al_destroy( &cmd );
|
||||
al_destroy( &path );
|
||||
sb_destroy( &short_opt );
|
||||
al_destroy( &gnu_opt );
|
||||
al_destroy( &old_opt );
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -13,6 +13,7 @@ Functions used for implementing the set builtin.
|
||||
|
||||
#include "config.h"
|
||||
#include "util.h"
|
||||
#include "wutil.h"
|
||||
#include "builtin.h"
|
||||
#include "env.h"
|
||||
#include "expand.h"
|
||||
|
||||
190
common.c
190
common.c
@@ -45,8 +45,11 @@ parts of fish.
|
||||
#include <termio.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_TERM_H
|
||||
#include <term.h>
|
||||
|
||||
#elif HAVE_NCURSES_TERM_H
|
||||
#include <ncurses/term.h>
|
||||
#endif
|
||||
|
||||
#include "util.h"
|
||||
#include "wutil.h"
|
||||
@@ -85,8 +88,6 @@ int error_max=1;
|
||||
|
||||
wchar_t ellipsis_char;
|
||||
|
||||
static int c1=0, c2=0, c3=0, c4=0, c5;
|
||||
|
||||
char *profile=0;
|
||||
|
||||
wchar_t *program_name;
|
||||
@@ -104,6 +105,9 @@ static struct winsize termsize;
|
||||
*/
|
||||
static int block_count=0;
|
||||
|
||||
/**
|
||||
String buffer used by the wsetlocale function
|
||||
*/
|
||||
static string_buffer_t *setlocale_buff=0;
|
||||
|
||||
|
||||
@@ -114,8 +118,6 @@ void common_destroy()
|
||||
sb_destroy( setlocale_buff );
|
||||
free( setlocale_buff );
|
||||
}
|
||||
|
||||
debug( 3, L"Calls: wcsdupcat %d, wcsdupcat2 %d, wcsndup %d, str2wcs %d, wcs2str %d", c1, c2, c3, c4, c5 );
|
||||
}
|
||||
|
||||
|
||||
@@ -253,8 +255,6 @@ void sort_list( array_list_t *comp )
|
||||
|
||||
wchar_t *str2wcs( const char *in )
|
||||
{
|
||||
c4++;
|
||||
|
||||
wchar_t *res;
|
||||
|
||||
res = malloc( sizeof(wchar_t)*(strlen(in)+1) );
|
||||
@@ -296,9 +296,8 @@ void error_reset()
|
||||
|
||||
char *wcs2str( const wchar_t *in )
|
||||
{
|
||||
c5++;
|
||||
|
||||
char *res = malloc( MAX_UTF8_BYTES*wcslen(in)+1 );
|
||||
|
||||
if( res == 0 )
|
||||
{
|
||||
die_mem();
|
||||
@@ -308,7 +307,7 @@ char *wcs2str( const wchar_t *in )
|
||||
in,
|
||||
MAX_UTF8_BYTES*wcslen(in)+1 );
|
||||
|
||||
// res = realloc( res, strlen( res )+1 );
|
||||
res = realloc( res, strlen( res )+1 );
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -337,15 +336,11 @@ char **wcsv2strv( const wchar_t **in )
|
||||
|
||||
wchar_t *wcsdupcat( const wchar_t *a, const wchar_t *b )
|
||||
{
|
||||
c1++;
|
||||
|
||||
return wcsdupcat2( a, b, 0 );
|
||||
}
|
||||
|
||||
wchar_t *wcsdupcat2( const wchar_t *a, ... )
|
||||
{
|
||||
c2++;
|
||||
|
||||
int len=wcslen(a);
|
||||
int pos;
|
||||
va_list va, va2;
|
||||
@@ -401,87 +396,6 @@ wchar_t **strv2wcsv( const char **in )
|
||||
}
|
||||
|
||||
|
||||
#ifndef HAVE_WCSNDUP
|
||||
wchar_t *wcsndup( const wchar_t *in, int c )
|
||||
{
|
||||
c3++;
|
||||
|
||||
wchar_t *res = malloc( sizeof(wchar_t)*(c+1) );
|
||||
if( res == 0 )
|
||||
{
|
||||
die_mem();
|
||||
}
|
||||
wcsncpy( res, in, c );
|
||||
res[c] = L'\0';
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
long convert_digit( wchar_t d, int base )
|
||||
{
|
||||
long res=-1;
|
||||
if( (d <= L'9') && (d >= L'0') )
|
||||
{
|
||||
res = d - L'0';
|
||||
}
|
||||
else if( (d <= L'z') && (d >= L'a') )
|
||||
{
|
||||
res = d + 10 - L'a';
|
||||
}
|
||||
else if( (d <= L'Z') && (d >= L'A') )
|
||||
{
|
||||
res = d + 10 - L'A';
|
||||
}
|
||||
if( res >= base )
|
||||
{
|
||||
res = -1;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
long wcstol(const wchar_t *nptr,
|
||||
wchar_t **endptr,
|
||||
int base)
|
||||
{
|
||||
long long res=0;
|
||||
int is_set=0;
|
||||
if( base > 36 )
|
||||
{
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
long nxt = convert_digit( *nptr, base );
|
||||
if( endptr != 0 )
|
||||
*endptr = (wchar_t *)nptr;
|
||||
if( nxt < 0 )
|
||||
{
|
||||
if( !is_set )
|
||||
{
|
||||
errno = EINVAL;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
res = (res*base)+nxt;
|
||||
is_set = 1;
|
||||
if( res > LONG_MAX )
|
||||
{
|
||||
errno = ERANGE;
|
||||
return LONG_MAX;
|
||||
}
|
||||
if( res < LONG_MIN )
|
||||
{
|
||||
errno = ERANGE;
|
||||
return LONG_MIN;
|
||||
}
|
||||
nptr++;
|
||||
}
|
||||
}
|
||||
|
||||
/*$OpenBSD: strlcat.c,v 1.11 2003/06/17 21:56:24 millert Exp $*/
|
||||
|
||||
/*
|
||||
@@ -583,75 +497,6 @@ wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz)
|
||||
/* count does not include NUL */
|
||||
}
|
||||
|
||||
#ifndef HAVE_WCSDUP
|
||||
wchar_t *wcsdup( const wchar_t *in )
|
||||
{
|
||||
size_t len=wcslen(in);
|
||||
wchar_t *out = malloc( sizeof( wchar_t)*(len+1));
|
||||
if( out == 0 )
|
||||
{
|
||||
die_mem();
|
||||
}
|
||||
|
||||
memcpy( out, in, sizeof( wchar_t)*(len+1));
|
||||
return out;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCSLEN
|
||||
size_t wcslen(const wchar_t *in)
|
||||
{
|
||||
const wchar_t *end=in;
|
||||
while( *end )
|
||||
end++;
|
||||
return end-in;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_WCSCASECMP
|
||||
int wcscasecmp( const wchar_t *a, const wchar_t *b )
|
||||
{
|
||||
if( *a == 0 )
|
||||
{
|
||||
return (*b==0)?0:-1;
|
||||
}
|
||||
else if( *b == 0 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
int diff = towlower(*a)-towlower(*b);
|
||||
if( diff != 0 )
|
||||
return diff;
|
||||
else
|
||||
return wcscasecmp( a+1,b+1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_WCSNCASECMP
|
||||
int wcsncasecmp( const wchar_t *a, const wchar_t *b, int count )
|
||||
{
|
||||
if( count == 0 )
|
||||
return 0;
|
||||
|
||||
if( *a == 0 )
|
||||
{
|
||||
return (*b==0)?0:-1;
|
||||
}
|
||||
else if( *b == 0 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
int diff = towlower(*a)-towlower(*b);
|
||||
if( diff != 0 )
|
||||
return diff;
|
||||
else
|
||||
return wcsncasecmp( a+1,b+1, count-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
int wcsvarname( wchar_t *str )
|
||||
{
|
||||
while( *str )
|
||||
@@ -667,23 +512,6 @@ int wcsvarname( wchar_t *str )
|
||||
|
||||
}
|
||||
|
||||
#if !HAVE_WCWIDTH
|
||||
/**
|
||||
Return the number of columns used by a character.
|
||||
|
||||
In locales without a native wcwidth, Unicode is probably so broken
|
||||
that it isn't worth trying to implement a real wcwidth. This
|
||||
wcwidth assumes any printing character takes up one column.
|
||||
*/
|
||||
int wcwidth( wchar_t c )
|
||||
{
|
||||
if( c < 32 )
|
||||
return 0;
|
||||
if ( c == 127 )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
The glibc version of wcswidth seems to hang on some strings. fish uses this replacement.
|
||||
|
||||
66
common.h
66
common.h
@@ -134,31 +134,6 @@ wchar_t *wcsdupcat( const wchar_t *a, const wchar_t *b );
|
||||
*/
|
||||
wchar_t *wcsdupcat2( const wchar_t *a, ... );
|
||||
|
||||
/**
|
||||
Returns a newly allocated wide character string wich is a copy of
|
||||
the string in, but of length c or shorter. The returned string is
|
||||
always null terminated, and the null is not included in the string
|
||||
length.
|
||||
*/
|
||||
wchar_t *wcsndup( const wchar_t *in, int c );
|
||||
|
||||
/**
|
||||
Converts from wide char to digit in the specified base. If d is not
|
||||
a valid digit in the specified base, return -1.
|
||||
*/
|
||||
long convert_digit( wchar_t d, int base );
|
||||
|
||||
|
||||
/**
|
||||
Convert a wide character string to a number in the specified
|
||||
base. This functions is the wide character string equivalent of
|
||||
strtol. For bases of 10 or lower, 0..9 are used to represent
|
||||
numbers. For bases below 36, a-z and A-Z are used to represent
|
||||
numbers higher than 9. Higher bases than 36 are not supported.
|
||||
*/
|
||||
long wcstol(const wchar_t *nptr,
|
||||
wchar_t **endptr,
|
||||
int base);
|
||||
|
||||
/**
|
||||
Appends src to string dst of size siz (unlike wcsncat, siz is the
|
||||
@@ -183,53 +158,12 @@ size_t wcslcat( wchar_t *dst, const wchar_t *src, size_t siz );
|
||||
*/
|
||||
size_t wcslcpy( wchar_t *dst, const wchar_t *src, size_t siz );
|
||||
|
||||
/**
|
||||
Create a duplicate string. Wide string version of strdup. Will
|
||||
automatically exit if out of memory.
|
||||
*/
|
||||
wchar_t *wcsdup(const wchar_t *in);
|
||||
|
||||
size_t wcslen(const wchar_t *in);
|
||||
|
||||
/**
|
||||
Case insensitive string compare function. Wide string version of
|
||||
strcasecmp.
|
||||
|
||||
This implementation of wcscasecmp does not take into account
|
||||
esoteric locales where uppercase and lowercase do not cleanly
|
||||
transform between each other. Hopefully this should be fine since
|
||||
fish only uses this function with one of the strings supplied by
|
||||
fish and guaranteed to be a sane, english word. Using wcscasecmp on
|
||||
a user-supplied string should be considered a bug.
|
||||
*/
|
||||
int wcscasecmp( const wchar_t *a, const wchar_t *b );
|
||||
|
||||
/**
|
||||
Case insensitive string compare function. Wide string version of
|
||||
strncasecmp.
|
||||
|
||||
This implementation of wcsncasecmp does not take into account
|
||||
esoteric locales where uppercase and lowercase do not cleanly
|
||||
transform between each other. Hopefully this should be fine since
|
||||
fish only uses this function with one of the strings supplied by
|
||||
fish and guaranteed to be a sane, english word. Using wcsncasecmp on
|
||||
a user-supplied string should be considered a bug.
|
||||
*/
|
||||
int wcsncasecmp( const wchar_t *a, const wchar_t *b, int count );
|
||||
|
||||
/**
|
||||
Test if the given string is a valid variable name
|
||||
*/
|
||||
|
||||
int wcsvarname( wchar_t *str );
|
||||
|
||||
/**
|
||||
The prototype for this function is missing in some libc
|
||||
implementations. Fish has a fallback implementation in case the
|
||||
implementation is missing altogether.
|
||||
*/
|
||||
int wcwidth( wchar_t c );
|
||||
|
||||
|
||||
/**
|
||||
A wcswidth workalike. Fish uses this since the regular wcswidth seems flaky.
|
||||
|
||||
59
complete.c
59
complete.c
@@ -209,6 +209,9 @@ static hash_table_t *condition_cache=0;
|
||||
*/
|
||||
static hash_table_t *loaded_completions=0;
|
||||
|
||||
/**
|
||||
String buffer used by complete_get_desc
|
||||
*/
|
||||
static string_buffer_t *get_desc_buff=0;
|
||||
|
||||
|
||||
@@ -435,9 +438,9 @@ void complete_add( const wchar_t *cmd,
|
||||
opt->result_mode = result_mode;
|
||||
opt->old_mode=old_mode;
|
||||
|
||||
opt->comp = intern(comp);
|
||||
opt->condition = intern(condition);
|
||||
opt->long_opt = intern( long_opt );
|
||||
opt->comp = intern(comp?comp:L"");
|
||||
opt->condition = intern(condition?condition:L"");
|
||||
opt->long_opt = intern( long_opt?long_opt:L"" );
|
||||
|
||||
if( desc && wcslen( desc ) )
|
||||
{
|
||||
@@ -895,6 +898,7 @@ static const wchar_t *complete_get_desc_suffix( const wchar_t *suff_orig )
|
||||
const wchar_t *complete_get_desc( const wchar_t *filename )
|
||||
{
|
||||
struct stat buf;
|
||||
|
||||
if( !get_desc_buff )
|
||||
{
|
||||
get_desc_buff = malloc(sizeof(string_buffer_t) );
|
||||
@@ -971,21 +975,21 @@ const wchar_t *complete_get_desc( const wchar_t *filename )
|
||||
if( wcslen((wchar_t *)get_desc_buff->buff) == 0 )
|
||||
{
|
||||
wchar_t *suffix = wcsrchr( filename, L'.' );
|
||||
if( suffix != 0 )
|
||||
if( suffix != 0 && !wcsrchr( suffix, L'/' ) )
|
||||
{
|
||||
if( !wcsrchr( suffix, L'/' ) )
|
||||
{
|
||||
sb_printf( get_desc_buff,
|
||||
L"%lc%ls",
|
||||
COMPLETE_SEP,
|
||||
complete_get_desc_suffix( suffix ) );
|
||||
}
|
||||
sb_printf( get_desc_buff,
|
||||
L"%lc%ls",
|
||||
COMPLETE_SEP,
|
||||
complete_get_desc_suffix( suffix ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
sb_printf( get_desc_buff,
|
||||
L"%lc%ls",
|
||||
COMPLETE_SEP,
|
||||
COMPLETE_FILE_DESC );
|
||||
COMPLETE_FILE_DESC );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return (wchar_t *)get_desc_buff->buff;
|
||||
@@ -1143,7 +1147,7 @@ static void complete_cmd_desc( const wchar_t *cmd, array_list_t *comp )
|
||||
val_begin++;
|
||||
}
|
||||
|
||||
if( !val_begin )
|
||||
if( !*val_begin )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -1212,6 +1216,17 @@ static void complete_cmd_desc( const wchar_t *cmd, array_list_t *comp )
|
||||
free( apropos_cmd );
|
||||
}
|
||||
|
||||
static const wchar_t *complete_function_desc( const wchar_t *fn )
|
||||
{
|
||||
const wchar_t *res = function_get_desc( fn );
|
||||
|
||||
if( !res )
|
||||
res = function_get_definition( fn );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Complete the specified command name. Search for executables in the
|
||||
path, executables defined using an absolute path, functions,
|
||||
@@ -1219,7 +1234,7 @@ static void complete_cmd_desc( const wchar_t *cmd, array_list_t *comp )
|
||||
|
||||
\param cmd the command string to find completions for
|
||||
|
||||
B\param comp the list to add all completions to
|
||||
\param comp the list to add all completions to
|
||||
*/
|
||||
static void complete_cmd( const wchar_t *cmd,
|
||||
array_list_t *comp )
|
||||
@@ -1291,7 +1306,7 @@ static void complete_cmd( const wchar_t *cmd,
|
||||
|
||||
al_init( &possible_comp );
|
||||
function_get_names( &possible_comp, cmd[0] == L'_' );
|
||||
copy_strings_with_prefix( comp, cmd, COMPLETE_FUNCTION_DESC, &function_get_desc, &possible_comp );
|
||||
copy_strings_with_prefix( comp, cmd, COMPLETE_FUNCTION_DESC, &complete_function_desc, &possible_comp );
|
||||
al_truncate( &possible_comp, 0 );
|
||||
|
||||
builtin_get_names( &possible_comp );
|
||||
@@ -1549,13 +1564,6 @@ void complete_load( wchar_t *cmd,
|
||||
wchar_t *esc = expand_escape( (wchar_t *)path.buff, 1 );
|
||||
wchar_t *src_cmd = wcsdupcat( L". ", esc );
|
||||
|
||||
/* if( tm )
|
||||
debug( 0, L"Reload %ls completions, old time was %d, new time is %d",
|
||||
cmd,
|
||||
tm?*tm:-1,
|
||||
buf.st_mtime);
|
||||
*/
|
||||
|
||||
if( !tm )
|
||||
{
|
||||
tm = malloc(sizeof(time_t));
|
||||
@@ -1568,7 +1576,6 @@ void complete_load( wchar_t *cmd,
|
||||
intern( cmd ),
|
||||
tm );
|
||||
|
||||
|
||||
free( esc );
|
||||
|
||||
complete_remove( cmd, COMMAND, 0, 0 );
|
||||
@@ -1591,8 +1598,6 @@ void complete_load( wchar_t *cmd,
|
||||
*/
|
||||
if( !tm )
|
||||
{
|
||||
// debug( 0, L"Insert null timestamp for command %ls", cmd );
|
||||
|
||||
tm = malloc(sizeof(time_t));
|
||||
if( !tm )
|
||||
die_mem();
|
||||
@@ -1645,7 +1650,7 @@ static int complete_param( wchar_t *cmd_orig,
|
||||
if( str[0] == L'-' )
|
||||
{
|
||||
/* Check if we are entering a combined option and argument
|
||||
* (like --color=auto or -I/usr/include) */
|
||||
(like --color=auto or -I/usr/include) */
|
||||
for( o = i->first_option; o; o=o->next )
|
||||
{
|
||||
wchar_t *arg;
|
||||
@@ -1663,7 +1668,7 @@ static int complete_param( wchar_t *cmd_orig,
|
||||
else if( popt[0] == L'-' )
|
||||
{
|
||||
/* Check if the previous option has any specified
|
||||
* arguments to match against */
|
||||
arguments to match against */
|
||||
int found_old = 0;
|
||||
|
||||
/*
|
||||
|
||||
60
configure.ac
60
configure.ac
@@ -1,8 +1,18 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(fish,1.19.0,fish-users@lists.sf.net)
|
||||
AC_INIT(fish,1.20.0,fish-users@lists.sf.net)
|
||||
|
||||
# Run autoheader automatically, it's quick, and saves people the hassle of remembering to run it manually
|
||||
autoheader
|
||||
# If needed, run autoheader automatically
|
||||
if test ! -f ./config.h.in -o config.h.in -ot configure.ac; then
|
||||
if which autoheader >/dev/null; then
|
||||
echo running autoheader...
|
||||
autoheader
|
||||
else
|
||||
echo Could not find the autoheader program in your path.
|
||||
echo This program is needed because the configure.ac file has been modified.
|
||||
echo Please install it and try again.
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Tell autoconf to create config.h header
|
||||
AC_CONFIG_HEADERS(config.h)
|
||||
@@ -12,7 +22,7 @@ AC_PROG_CC
|
||||
AC_PROG_CPP
|
||||
AC_PROG_INSTALL
|
||||
|
||||
# Check for doxygen, needed to build
|
||||
# Check for doxygen, which is needed to build
|
||||
AC_CHECK_PROG( has_doxygen, [doxygen], "true")
|
||||
|
||||
if ! test $has_doxygen = "true"; then
|
||||
@@ -22,6 +32,9 @@ if ! test $has_doxygen = "true"; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for seq program. If missing, install fallback shellscript implementation
|
||||
AC_CHECK_PROG( SEQ_FALLBACK, seq, [ ], [seq])
|
||||
|
||||
# Optionally drop xsel
|
||||
AC_ARG_WITH( xsel,
|
||||
AC_HELP_STRING([--without-xsel],
|
||||
@@ -49,7 +62,7 @@ fi
|
||||
AC_DEFINE_UNQUOTED([CPU],[L"$target_cpu"],[CPU type])
|
||||
|
||||
|
||||
# Set up install locations
|
||||
# Set up installation directories
|
||||
if [[ "$prefix" = NONE ]]; then
|
||||
AC_DEFINE_UNQUOTED( [PREFIX], L"/usr/local", [Installation directory])
|
||||
AC_SUBST( PREFIX, /usr/local)
|
||||
@@ -133,19 +146,43 @@ else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
|
||||
# Check for libraries
|
||||
AC_CHECK_LIB(socket, connect)
|
||||
AC_CHECK_LIB(rt, nanosleep)
|
||||
AC_CHECK_LIB(intl, gettext)
|
||||
|
||||
# Check for various header files
|
||||
AC_CHECK_HEADERS([getopt.h termio.h sys/resource.h])
|
||||
AC_CHECK_HEADERS([getopt.h termio.h sys/resource.h term.h ncurses/term.h libintl.h])
|
||||
|
||||
# Check for various function
|
||||
AC_CHECK_FUNCS(wcsdup wcsndup wcslen wcscasecmp wcsncasecmp gettext wprintf futimes wcwidth wcswidth getopt_long )
|
||||
AC_CHECK_HEADER([regex.h],
|
||||
[AC_DEFINE([HAVE_REGEX_H], [1], [Define to 1 if you have the <regex.h> header file.])],
|
||||
[AC_MSG_ERROR([Could not find the header regex.h, needed to build fish])])
|
||||
|
||||
# Check again for gettext library, so we can insert information
|
||||
|
||||
# Check for various functions, and insert results into config.h
|
||||
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 )
|
||||
|
||||
# Check again for gettext library, and insert results into the Makefile
|
||||
AC_CHECK_FUNC(gettext, AC_SUBST(HAVE_GETTEXT,1), AC_SUBST(HAVE_GETTEXT,0) )
|
||||
|
||||
# Check for _nl_msg_cat_cntr symbol
|
||||
AC_MSG_CHECKING([for _nl_msg_cat_cntr symbol])
|
||||
AC_TRY_LINK([#if HAVE_LIBINTL_H]
|
||||
[#include <libintl.h>]
|
||||
[#endif],
|
||||
[extern int _nl_msg_cat_cntr;]
|
||||
[int tmp = _nl_msg_cat_cntr;], have__nl_msg_cat_cntr=yes, have__nl_msg_cat_cntr=no)
|
||||
if test "$have__nl_msg_cat_cntr" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([HAVE__NL_MSG_CAT_CNTR], [1],
|
||||
[Define to 1 if the _nl_msg_cat_cntr symbol is exported.])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
# Check if we have ncurses, and use it rather than curses if possible.
|
||||
AC_CHECK_HEADERS([ncurses.h],[AC_SUBST(CURSESLIB,[ncurses]) AC_DEFINE(HAVE_NCURSES_H)],[AC_SUBST(CURSESLIB,[curses])])
|
||||
|
||||
@@ -154,7 +191,8 @@ AC_CHECK_HEADERS([ncurses.h],[AC_SUBST(CURSESLIB,[ncurses]) AC_DEFINE(HAVE_NCURS
|
||||
# does not properly support terminfo.
|
||||
AC_CHECK_FILE([/usr/pkg/include/ncurses.h],[AC_SUBST(CURSESLIB,[ncurses]) AC_DEFINE(HAVE_NCURSES_H)])
|
||||
|
||||
AC_CONFIG_FILES([Makefile fish.spec doc_src/fish.1 doc_src/Doxyfile init/fish init/fish_interactive.fish init/fish_complete.fish])
|
||||
AC_CONFIG_FILES([Makefile fish.spec doc_src/fish.1 doc_src/Doxyfile init/fish init/fish_interactive.fish init/fish_complete.fish seq])
|
||||
AC_OUTPUT
|
||||
|
||||
echo "Now run 'make' and 'make install'"
|
||||
echo "Now run 'make' and 'make install' to built and install fish."
|
||||
echo "Good luck!"
|
||||
|
||||
@@ -10,7 +10,7 @@ The \c and builtin is used to execute a command if the current exit status (as s
|
||||
|
||||
\subsection and-example Example
|
||||
|
||||
The following code runs the \c make command to build a program, and if it suceeds, it runs <tt>make install</tt>, which installs the program.
|
||||
The following code runs the \c make command to build a program, and if it succeeds, it runs <tt>make install</tt>, which installs the program.
|
||||
<pre>
|
||||
make; and make install
|
||||
</pre>
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
\subsection begin-description Description
|
||||
|
||||
The \c begin builtin is used to create a new block of code. The block
|
||||
is unconditionally erxecuted. Begin is equivalent to <tt>if
|
||||
is unconditionally executed. Begin is equivalent to <tt>if
|
||||
true</tt>. The begin command is used to group any number of commands
|
||||
into a block. The reason for this is usually either to introduce a new
|
||||
variable scope or to redirect the input ot output of this set of
|
||||
variable scope or to redirect the input to output of this set of
|
||||
commands as a group.
|
||||
|
||||
\subsection begin-example Example
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
The \c break builtin is used to halt a currently running loop, such as a <a href="#for">for</a> loop or a <a href="#while">while</a> loop. It is usually added inside of a conditional block such as an <a href="#if">if</a> statement or a <a href="#switch">switch</a> statement.
|
||||
|
||||
\subsection break-example Example
|
||||
The following code searches all .c files for smurfs, and halts at the first occurance.
|
||||
The following code searches all .c files for smurfs, and halts at the first occurrence.
|
||||
<p>
|
||||
<tt>for i in *.c;
|
||||
<br> if grep smurf $i;
|
||||
|
||||
@@ -23,7 +23,7 @@ switch $animal
|
||||
echo evil
|
||||
case wolf dog human moose dolphin whale
|
||||
echo mammal
|
||||
case duck goose albatros
|
||||
case duck goose albatross
|
||||
echo bird
|
||||
case shark trout stingray
|
||||
echo fish
|
||||
|
||||
@@ -25,14 +25,14 @@ or updated
|
||||
- \c -b or \c --current-buffer select the entire buffer (default)
|
||||
- \c -j or \c --current-job select the current job
|
||||
- \c -p or \c --current-process select the current process
|
||||
- \c -t or \c --current_token select the current token.
|
||||
- \c -t or \c --current_token select the current token.
|
||||
|
||||
The following switch changes the way \c commandline prints the current
|
||||
commandline
|
||||
|
||||
- \c -c or \c --cut-at-cursor only print selection up until the
|
||||
current cursor position
|
||||
- \c o or \c --tokenize tokenize the selection and print one string-type token per line
|
||||
- \c -o or \c --tokenize tokenize the selection and print one string-type token per line
|
||||
|
||||
Other switches
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
\section complete complete - edit command specific tab-completions.
|
||||
\section complete complete - edit command specific tab-completions.
|
||||
|
||||
\subsection complete-synopsis Synopsis
|
||||
<tt>complete (-c|--command|-p|--path) COMMAND [(-s|--short-option) SHORT_OPTION] [(-l|--long-option|-o|--old-option) LONG_OPTION [(-a||--arguments) OPTION_ARGUMENTS] [(-d|--description) DESCRIPTION] </tt>
|
||||
@@ -16,8 +16,8 @@ the fish manual.
|
||||
- <tt>DESCRIPTION</tt> is a description of what the option and/or option arguments do
|
||||
- <tt>-e</tt> or <tt>--erase</tt> implies that the specified completion should be deleted
|
||||
- <tt>-f</tt> or <tt>--no-files</tt> specifies that the option specified by this completion may not be followed by a filename
|
||||
- <tt>-n</tt> or <tt>--condition</tt> specides a shell command that must return 0 if the completion is to be used. This makes it possible to specify completions that should only be used in some cases.
|
||||
- <tt>-o</tt> or <tt>--old-option</tt> implies that the command uses old long style options with only one dash
|
||||
- <tt>-n</tt> or <tt>--condition</tt> specifies a shell command that must return 0 if the completion is to be used. This makes it possible to specify completions that should only be used in some cases.
|
||||
- <tt>-o</tt> or <tt>--old-option</tt> implies that the command uses old long style options with only one dash
|
||||
- <tt>-p</tt> or <tt>--path</tt> implies that the string COMMAND is the full path of the command
|
||||
- <tt>-r</tt> or <tt>--require-parameter</tt> specifies that the option specified by this completion always must have an option argument, i.e. may not be followed by another option
|
||||
- <tt>-u</tt> or <tt>--unauthorative</tt> implies that there may be more options than the ones specified, and that fish should not assume that options not listed are spelling errors
|
||||
@@ -30,13 +30,14 @@ that do not begin with a hyphen. Fish recognizes three styles of
|
||||
options, the same styles as the GNU version of the getopt
|
||||
library. These styles are:
|
||||
|
||||
- Short options, like '-a'. Short options are a single character long, are preceeded by a single hyphen and may ge grouped together (like '-la', which is equivalent to '-l -a'). Option arguments may be specified in the following parameter ('-w 32') or by appending the option with the value ('-w32').
|
||||
- Old style long options, like '-Wall'. Old style long options are more than one character long, are preceeded by a single hyphen and may not be grouped together. Option arguments are specified in the following parameter ('-ao null').
|
||||
- GNU style long options, like '--colors'. GNU style long options are more than one character long, are preceeded by two hyphens, and may not be grouped together. Option arguments may be specified in the following parameter ('--quoting-style shell') or by appending the option with a '=' and the value ('--quoting-style=shell'). GNU style long options may be abbrevated so long as the abbrevation is unique ('--h' is equivalent to '--help' if help is the only long option beginning with an 'h').
|
||||
- Short options, like '-a'. Short options are a single character long, are preceded by a single hyphen and may be grouped together (like '-la', which is equivalent to '-l -a'). Option arguments may be specified in the following parameter ('-w 32') or by appending the option with the value ('-w32').
|
||||
- Old style long options, like '-Wall'. Old style long options are more than one character long, are preceded by a single hyphen and may not be grouped together. Option arguments are specified in the following parameter ('-ao null').
|
||||
- GNU style long options, like '--colors'. GNU style long options are more than one character long, are preceded by two hyphens, and may not be grouped together. Option arguments may be specified in the following parameter ('--quoting-style shell') or by appending the option with a '=' and the value ('--quoting-style=shell'). GNU style long options may be abbreviated so long as the abbreviation is unique ('--h' is equivalent to '--help' if help is the only long option beginning with an 'h').
|
||||
|
||||
\c complete only allows one of old style long options and GNU style
|
||||
long options to be used on a specific command, but short options can
|
||||
always be specified.
|
||||
The options for specifying command name, command path, or command
|
||||
switches may all be used multiple times to specify multiple commands
|
||||
which have the same completion or multiple switches accepted by a
|
||||
command.
|
||||
|
||||
When erasing completions, it is possible to either erase all
|
||||
completions for a specific command by specifying <tt>complete -e -c
|
||||
@@ -70,5 +71,5 @@ This can be written as:
|
||||
"Don't check dependencies"</tt>
|
||||
|
||||
where \c __fish_contains_opt is a function that checks the commandline
|
||||
buffer for the presense of a specified set of options.
|
||||
buffer for the presence of a specified set of options.
|
||||
|
||||
|
||||
@@ -925,11 +925,15 @@ 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. Valid
|
||||
values are \c black, \c red, \c green, \c brown, \c yellow, \c blue,
|
||||
\c magenta, \c purple, \c cyan, \c white or \c normal. Setting one of
|
||||
the above variables to normal will mean that the text color will be
|
||||
set to the default foreground color for the terminal.
|
||||
fish_pager_color_description and \c
|
||||
fish_pager_color_progress. Usually, the value of these variables will
|
||||
be one of \c black, \c red, \c green, \c brown, \c yellow, \c blue, \c
|
||||
magenta, \c purple, \c cyan, \c white or \c normal, but they can be an
|
||||
array containing any color options for the set_color command.
|
||||
|
||||
Issuing <code>set fish_color_error black --background=red
|
||||
--bold</code> will make all commandline errors be written in a black,
|
||||
bold font, with a red background.
|
||||
|
||||
\subsection prompt Programmable prompt
|
||||
|
||||
@@ -1055,7 +1059,7 @@ msgid "%ls: No suitable job\n"
|
||||
msgstr "%ls: Inget jobb matchar\n"
|
||||
</pre>
|
||||
|
||||
%s, %ls, %d and other tokens beginning with a '%' are
|
||||
\%s, \%ls, %\d and other tokens beginning with a '\%' are
|
||||
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
|
||||
@@ -1072,18 +1076,19 @@ href='fish-users@lists.sf.net'>fish-users@lists.sf.net</a>.
|
||||
|
||||
- Complete vi-mode key bindings
|
||||
- next-history-complete
|
||||
- builtin wait command
|
||||
- More completions (for example xterm, vim,
|
||||
konsole, gnome-terminal, dcop, cdrecord, cron, xargs
|
||||
rlogin, telnet, rsync, arch, finger, nice, locate,
|
||||
bibtex, patch, aspell, xpdf,
|
||||
zip, compress, wine, xmms, dig, wine, batch, cron,
|
||||
compress, wine, xmms, dig, wine, batch, cron,
|
||||
g++, javac, java, gcj, lpr, doxygen, whois, find)
|
||||
- Undo support
|
||||
- Check keybinding commands for output - if non has happened, don't repaint to reduce flicker
|
||||
- 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
|
||||
|
||||
|
||||
\subsection todo-possible Possible features
|
||||
|
||||
@@ -1095,7 +1100,6 @@ g++, javac, java, gcj, lpr, doxygen, whois, find)
|
||||
- mouse support like zsh has with http://stchaz.free.fr/mouse.zsh
|
||||
installed would be awesome
|
||||
- suggest a completion on unique matches by writing it out in an understated color
|
||||
- Maybe some functions should only be available from key-bindings. That way one could implement a large part of all the key-binding functions as regular fish functions without worrying about cluttering up the function name space.
|
||||
- With a bit of tweakage, quite a few of the readline key-binding functions could be implemented in shellscript.
|
||||
- Highlight beginning/end of block when moving over a block command
|
||||
- Inclusion guards for the init files to make them evaluate only once, even if the user has installed fish both in /etc and in $HOME
|
||||
@@ -1108,18 +1112,18 @@ g++, javac, java, gcj, lpr, doxygen, whois, find)
|
||||
- Descriptions for variables using 'set -d'.
|
||||
- Parse errors should when possible honor IO redirections
|
||||
|
||||
|
||||
\subsection bugs Known bugs
|
||||
|
||||
- Completion for gcc -\#\#\# option doesn't work.
|
||||
- Many completions are made specifically for the GNU version of a POSIX command
|
||||
- Yanking weird characters from clipboard prints Unicode escapes
|
||||
- Suspending and then resuming pipelines containing a builtin seems to be broken.
|
||||
- Interactive input seems broken inside blocks. Is local echo and other terminal values not restored when in an interactive block?
|
||||
- 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
|
||||
report to <a href="mailto:axel@liljencrantz.se"> axel@liljencrantz.se
|
||||
</a>.
|
||||
|
||||
|
||||
\subsection issues Known issues
|
||||
|
||||
Older versions of Doxygen has bugs in the man-page generation which
|
||||
@@ -1134,6 +1138,7 @@ changes when upgrading from pre1.9.2 to 1.9.2 or later. You may also
|
||||
run into such problems when switching between using a package and
|
||||
personal builds.
|
||||
|
||||
|
||||
*/
|
||||
/** \page design Design document
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
\subsection exec-description Description
|
||||
|
||||
The \c exec builtin is used to replace the currently running shells
|
||||
process image with a new command. On sucessfull completion, exec never
|
||||
returns. exec can not be used inside a pipeline.
|
||||
process image with a new command. On successful completion, exec never
|
||||
returns. exec can not be used inside a pipeline.
|
||||
|
||||
\subsection exec-example Example
|
||||
|
||||
|
||||
@@ -2,50 +2,24 @@
|
||||
\section fishd fishd - Universal variable daemon
|
||||
|
||||
\subsection fishd-synopsis Synopsis
|
||||
<tt>fishd [SECTION]</tt>
|
||||
<tt>fishd [(-h|--help|-v|--version)]</tt>
|
||||
|
||||
\subsection fishd-description Description
|
||||
|
||||
The \c fishd daemon is used to load, save and distribute universal
|
||||
variable information. fish automtically connects to fishd via a socket
|
||||
variable information. fish automatically connects to fishd via a socket
|
||||
on startup. If no instance of fishd is running, fish spawns a new
|
||||
fishd instance. fishd will create a socket in /tmp, and wait for
|
||||
incoming connections from universal variable clents, such as fish,
|
||||
incoming connections from universal variable clients, such as fish,
|
||||
When no clients are connected, fishd will automatically shut down.
|
||||
|
||||
\subsection fishd-commands Commands
|
||||
|
||||
Fishd works by sending and recieving sommands. Each command is ended
|
||||
with a newline. These are the commands supported by fishd:
|
||||
|
||||
<pre>set KEY:VALUE
|
||||
set_export KEY:VALUE
|
||||
</pre>
|
||||
|
||||
These commands update the value of a variable. The only difference
|
||||
between the two is that <tt>set_export</tt>-variables should be
|
||||
exported to children of the process using them. The variable value may
|
||||
be escaped using C-style backslash escapes. In fact, this is required
|
||||
for newline characters, which would otherwise be interpreted as end of
|
||||
command.
|
||||
|
||||
<pre>erase KEY
|
||||
</pre>
|
||||
|
||||
Erase the variable with the specified name.
|
||||
|
||||
<pre>barrier
|
||||
barrier_reply
|
||||
</pre>
|
||||
|
||||
A \c barrier command will result in a barrier_reply beeing added to
|
||||
the end of the senders queue of unsent messages. These commands are
|
||||
used to synchronize clients, since once the reply for a barrier
|
||||
message returns, the sender can know that any updates available at the
|
||||
time the original barrier request was sent have been recieved.
|
||||
- <tt>-h</tt> or <tt>--help</tt> displays this help message and then exits
|
||||
- <tt>-v</tt> or <tt>--version</tt> displays the current fish version and then exits
|
||||
|
||||
\subsection fishd-files Files
|
||||
|
||||
~/.fishd.HOSTNAME permenent storage location for universal variale
|
||||
~/.fishd.HOSTNAME permanent storage location for universal variable
|
||||
data. The data is stored as a set of \c set and \c set_export commands
|
||||
such as would be parsed by fishd.
|
||||
such as would be parsed by fishd. If an instance of fishd is running
|
||||
(which is generally the case), manual modifications to ~/.fishd.HOSTNAME
|
||||
will be lost.
|
||||
|
||||
@@ -5,22 +5,22 @@
|
||||
|
||||
\subsection function-description Description
|
||||
|
||||
- \c -b or \c --key-binding specifies that the function is a key biding. Key binding functions work exactly like regular functions except that they can not be tab-completed, and may contain the '-' character.
|
||||
- \c -b or \c --key-binding specifies that the function is a key biding. Key binding functions work exactly like regular functions except that they can not be tab-completed, and may contain the '-' character.
|
||||
- <tt>-d DESCRIPTION</tt> or \c --description=DESCRIPTION is a description of what the function does, suitable as a completion description
|
||||
- <tt>-j PID</tt> or <tt> --on-job-exit PID</tt> tells fish to run this function when the job with group id PID exits
|
||||
- <tt>-p PID</tt> or <tt> --on-process-exit PID</tt> tells fish to run this function when the fish child process with process id PID exits
|
||||
- <tt>-s</tt> or <tt>--on-signal SIGSPEC</tt> tells fish to run this function when the signal SIGSPEC is delivered. SIGSPEC can be a singal number, or the signal name, such as SIGHUP (or just HUP)
|
||||
- <tt>-s</tt> or <tt>--on-signal SIGSPEC</tt> tells fish to run this function when the signal SIGSPEC is delivered. SIGSPEC can be a signal number, or the signal name, such as SIGHUP (or just HUP)
|
||||
- <tt>-v</tt> or <tt>--on-variable VARIABLE_NAME</tt> tells fish to run this function when the variable VARIABLE_NAME changes value
|
||||
|
||||
This builtin command is used to create a new function. A Function is a
|
||||
list of commands that will be executed when the name of the function
|
||||
is entered. The function
|
||||
is entered. The function
|
||||
|
||||
<pre>
|
||||
function hi
|
||||
echo hello
|
||||
end
|
||||
</pre>
|
||||
</pre>
|
||||
|
||||
will write <tt>hello</tt> whenever the user enters \c hi.
|
||||
|
||||
@@ -29,7 +29,7 @@ are inserted into the environment variable <a href="index.html#variables-arrays"
|
||||
|
||||
\subsection function-example Example
|
||||
|
||||
<pre>function ll
|
||||
<pre>function ll
|
||||
ls -l $argv
|
||||
end
|
||||
</pre>
|
||||
@@ -39,18 +39,18 @@ will run the \c ls command, using the \c -l option, while passing on any additio
|
||||
<pre>
|
||||
function mkdir -d "Create a directory and set CWD"
|
||||
mkdir $argv
|
||||
if test $status = 0
|
||||
if test $status = 0
|
||||
switch $argv[(count $argv)]
|
||||
case '-*'
|
||||
|
||||
|
||||
case '*'
|
||||
cd $argv[(count $argv)]
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
</pre>
|
||||
|
||||
will run the mkdir command, and if it is succesfull, change the
|
||||
will run the mkdir command, and if it is successful, change the
|
||||
current working directory to the one just created.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
\section help help - Display fish documantation
|
||||
\section help help - Display fish documentation
|
||||
|
||||
\subsection help-synopsis Synopsis
|
||||
<tt>help [SECTION]</tt>
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
|
||||
\subsection jobs-description Description
|
||||
The <tt>jobs</tt> builtin causes fish to print a list of the currently
|
||||
running jobs and their status.
|
||||
running jobs and their status.
|
||||
|
||||
jobs accepts the following switches:
|
||||
|
||||
- <tt>-c</tt> or <tt>--command</tt> print the command name for each process in jobs
|
||||
- <tt>-g</tt> or <tt>--group</tt> only print the group id of each job
|
||||
- <tt>-l</tt> or <tt>--last</tt> only the last job to be started is printed
|
||||
- <tt>-p</tt> or <tt>--process</tt> print the procces id for each process in all jobs
|
||||
- <tt>-p</tt> or <tt>--process</tt> print the process id for each process in all jobs
|
||||
|
||||
On systems that supports this feature, jobs will print the CPU usage
|
||||
of each job since the last command was executed. The CPU usage is
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
\subsection set-synopsis Synopsis
|
||||
<code>set [OPTIONS] [VARIABLE_NAME [VALUES...]]</code>
|
||||
|
||||
The <code>set</code> builtin causes fish to assign the variable <code>VARIABLE_NAME</code> the values <code>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
|
||||
- <code>-e</code> or <code>--erase</code> causes the specified environment variable to be erased
|
||||
- <code>-g</code> or <code>--global</code> causes the specified environment variable to be made global. If this option is not supplied, the specified variable will dissapear when the current block ends
|
||||
- <code>-g</code> or <code>--global</code> causes the specified environment variable to be made global. If this option is not supplied, the specified variable will disappear when the current block ends
|
||||
- <code>-l</code> or <code>--local</code> forces the specified environment variable to be made local to the current block, even if the variable already exists and is non-local
|
||||
- <code>-n</code> or <code>--names</code> List only the names of all defined variables
|
||||
- <code>-q</code> or <code>--query</code> test if the specified variable names are defined. Does not output anything, but the builtins exit status is the number of variables specified that were not defined.
|
||||
@@ -18,7 +18,7 @@ The <code>set</code> builtin causes fish to assign the variable <code>VARIABLE_N
|
||||
If set is called with no arguments, the names and values of all
|
||||
environment variables are printed. If some of the scope or export
|
||||
flags have been given, only the variables matching the specified scope
|
||||
are printed.
|
||||
are printed.
|
||||
|
||||
If the \c -e or \c --erase option is specified, the variable
|
||||
specified by the following arguments will be erased
|
||||
|
||||
@@ -20,3 +20,8 @@ purple, cyan, white and normal.
|
||||
Calling <tt>set_color normal</tt> will set the terminal color to
|
||||
whatever is the default color of the terminal.
|
||||
|
||||
Some terminals use the --bold escape sequence to switch to a brighter
|
||||
color set. On such terminals, <code>set_color white</code> will result
|
||||
in a grey font color, while <code>set_color --bold white</code> will
|
||||
result in a white font color.
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<tt>status [OPTION]</tt>
|
||||
|
||||
\subsection status-description Description
|
||||
- <tt>-c</tt> or <tt>--is-command-substitution</tt> returns 0 if fish is currently executing a command usbstitution
|
||||
- <tt>-c</tt> or <tt>--is-command-substitution</tt> returns 0 if fish is currently executing a command substitution
|
||||
- <tt>-b</tt> or <tt>--is-block</tt> returns 0 if fish is currently executing a block of code
|
||||
- <tt>-i</tt> or <tt>--is-interactive</tt> returns 0 if fish is interactive, i.e.connected to a keyboard
|
||||
- <tt>-l</tt> or <tt>--is-login</tt> returns 0 if fish is a login shell, i.e. if fish should perform login tasks such as setting up the PATH.
|
||||
- <tt>-l</tt> or <tt>--is-login</tt> returns 0 if fish is a login shell, i.e. if fish should perform login tasks such as setting up the PATH.
|
||||
|
||||
@@ -12,7 +12,7 @@ wildcarded values.
|
||||
|
||||
\subsection switch-example Example
|
||||
|
||||
If the variable \$animal contins the name of an animal, the
|
||||
If the variable \$animal contains the name of an animal, the
|
||||
following code would attempt to classify it:
|
||||
|
||||
<p>
|
||||
@@ -22,7 +22,7 @@ switch $animal
|
||||
echo evil
|
||||
case wolf dog human moose dolphin whale
|
||||
echo mammal
|
||||
case duck goose albatros
|
||||
case duck goose albatross
|
||||
echo bird
|
||||
case shark trout stingray
|
||||
echo fish
|
||||
@@ -32,6 +32,6 @@ end
|
||||
<p>
|
||||
|
||||
If the above code was run with \$animal set to \c whale, the output
|
||||
would be \c mammal.
|
||||
would be \c mammal.
|
||||
|
||||
</p>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
\section trap trap - perform an action when the shell recives a signal
|
||||
\section trap trap - perform an action when the shell receives a signal
|
||||
|
||||
\subsection trap-synopsis Synopsis
|
||||
<tt>trap [OPTIONS] [[ARG] SIGSPEC ... ]</tt>
|
||||
@@ -8,10 +8,10 @@
|
||||
|
||||
Trap is a shellscript wrapper around the fish event delivery
|
||||
framework. IT is defined for backwards compatibility reasons. For
|
||||
other uses, it is recomended to define a <a
|
||||
other uses, it is recommended to define a <a
|
||||
href='index.html#event'>event handler</a>.
|
||||
|
||||
- ARG is the command to be executed on signal delivary
|
||||
- ARG is the command to be executed on signal delivery
|
||||
- SIGSPEC is the name of the signal to trap
|
||||
- \c -h or \c --help Display help and exit
|
||||
- \c -l or \c --list-signals print a list of signal names
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
|
||||
\subsection type-description Description
|
||||
|
||||
With no options, indicate how each name would be interpreted if used as a command name.
|
||||
With no options, indicate how each name would be interpreted if used as a command name.
|
||||
|
||||
- \c -h or \c --help print this message
|
||||
- \c -a or \c --all print all of possible definitions of the specified names
|
||||
- \c -f or \c --no-functions supresses function and builtin lookup
|
||||
- \c -f or \c --no-functions suppresses function and builtin lookup
|
||||
- \c -t or \c --type print a string which is one of alias, keyword, function, builtin, or file if name is an alias, shell reserved word, function, builtin, or disk file, respectively
|
||||
- \c -p or \c --path either return the name of the disk file that would be executed if name were specified as a command name, or nothing if 'type -t name' would not return 'file'
|
||||
- \c -P or \c --force-path either return the name of the disk file that would be executed if name were specified as a command name, or nothing no file with the specified name could be found in the PATH
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
\section ulimit ulimit - Set or get the shells resurce usage limits
|
||||
\section ulimit ulimit - Set or get the shells resource usage limits
|
||||
|
||||
\subsection ulimit-synopsis Synopsis
|
||||
<tt>ulimit [OPTIONS] [LIMIT]</tt>
|
||||
@@ -38,7 +38,7 @@ except for -t, which is in seconds and -n and -u, which are unscaled
|
||||
values. The return status is 0 unless an invalid option or argument is
|
||||
supplied, or an error occurs while setting a new limit.
|
||||
|
||||
The fish implementation of ulimit should behave identically to the implementation in bash, except for these differences:
|
||||
The fish implementation of ulimit should behave identically to the implementation in bash, except for these differences:
|
||||
|
||||
- Fish ulimit supports GNU-style long options for all switches
|
||||
- Fish ulimit does not support the -p option for getting the pipe size. The bash implementation consists of a compile-time check that empirically guesses this number by writing to a pipe and waiting for SIGPIPE.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
\section umask umask - Set or get the shells resurce usage limits
|
||||
\section umask umask - Set or get the shells resource usage limits
|
||||
|
||||
\subsection umask-synopsis Synopsis
|
||||
<code>umask [OPTIONS] [MASK]</code>
|
||||
@@ -10,7 +10,7 @@ With no argument, the current file-creation mask is printed, if an
|
||||
argument is specified, it is the new file creation mask. The mask may
|
||||
be specified as an octal number, in which case it is interpreted as
|
||||
the rights that should be masked away, i.e. it is the inverse of the
|
||||
file permissions any new files will have.
|
||||
file permissions any new files will have.
|
||||
|
||||
If a symbolic mask is specified, the actual file permission bits, and
|
||||
not the inverse, should be specified. A symbolic mask is a comma
|
||||
@@ -19,7 +19,7 @@ separated list of rights. Each right consists of three parts:
|
||||
- The first part specifies to whom this set of right applies, and can
|
||||
be one of \c u, \c g, \c o or \c a, where \c u specifies the user who
|
||||
owns the file, \c g specifies the group owner of the file, \c o
|
||||
specifiec other users rights and \c a specifies all three should be
|
||||
specific other users rights and \c a specifies all three should be
|
||||
changed.
|
||||
- The second part of a right specifies the mode, and can be one of \c
|
||||
=, \c + or \c -, where \c = specifies that the rights should be set to
|
||||
@@ -27,7 +27,7 @@ the new value, \c + specifies that the specified right should be added
|
||||
to those previously specified and \c - specifies that the specified
|
||||
rights should be removed from those previously specified.
|
||||
- The third part of a right specifies what rights should be changed
|
||||
and can be any compination of \c r, \c w and \c x, representing
|
||||
and can be any combination of \c r, \c w and \c x, representing
|
||||
read, write and execute rights.
|
||||
|
||||
If the first and second parts are skipped, they are assumed to be \c a
|
||||
|
||||
259
env.c
259
env.c
@@ -25,7 +25,12 @@
|
||||
#include <termio.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_TERM_H
|
||||
#include <term.h>
|
||||
#elif HAVE_NCURSES_TERM_H
|
||||
#include <ncurses/term.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "util.h"
|
||||
@@ -143,19 +148,6 @@ static buffer_t export_buffer;
|
||||
*/
|
||||
static int has_changed = 1;
|
||||
|
||||
/**
|
||||
Free hash key and hash value
|
||||
*/
|
||||
static void clear_hash_entry( const void *key, const void *data )
|
||||
{
|
||||
var_entry_t *entry = (var_entry_t *)data;
|
||||
if( entry->export )
|
||||
has_changed = 1;
|
||||
|
||||
free( (void *)key );
|
||||
free( (void *)data );
|
||||
}
|
||||
|
||||
/**
|
||||
This stringbuffer is used to store the value of dynamically
|
||||
generated variables, such as history.
|
||||
@@ -173,6 +165,36 @@ static int get_names_show_exported;
|
||||
*/
|
||||
static int get_names_show_unexported;
|
||||
|
||||
/**
|
||||
List of all locale variable names
|
||||
*/
|
||||
static const wchar_t *locale_variable[] =
|
||||
{
|
||||
L"LANG",
|
||||
L"LC_ALL",
|
||||
L"LC_COLLATE",
|
||||
L"LC_CTYPE",
|
||||
L"LC_MESSAGES",
|
||||
L"LC_MONETARY",
|
||||
L"LC_NUMERIC",
|
||||
L"LC_TIME",
|
||||
(void *)0
|
||||
}
|
||||
;
|
||||
|
||||
/**
|
||||
Free hash key and hash value
|
||||
*/
|
||||
static void clear_hash_entry( const void *key, const void *data )
|
||||
{
|
||||
var_entry_t *entry = (var_entry_t *)data;
|
||||
if( entry->export )
|
||||
has_changed = 1;
|
||||
|
||||
free( (void *)key );
|
||||
free( (void *)data );
|
||||
}
|
||||
|
||||
/**
|
||||
When fishd isn't started, this function is provided to
|
||||
env_universal as a callback, it tries to start up fishd. It's
|
||||
@@ -184,7 +206,7 @@ static void start_fishd()
|
||||
{
|
||||
string_buffer_t cmd;
|
||||
struct passwd *pw;
|
||||
|
||||
|
||||
sb_init( &cmd );
|
||||
pw = getpwuid(getuid());
|
||||
|
||||
@@ -215,15 +237,6 @@ static mode_t get_umask()
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
List of all locale variable names
|
||||
*/
|
||||
static const wchar_t *locale_variable[] =
|
||||
{
|
||||
L"LANG", L"LC_ALL", L"LC_COLLATE", L"LC_CTYPE", L"LC_MESSAGES", L"LC_MONETARY", L"LC_NUMERIC", L"LC_TIME", (void *)0
|
||||
}
|
||||
;
|
||||
|
||||
/**
|
||||
Checks if the specified variable is a locale variable
|
||||
*/
|
||||
@@ -251,7 +264,14 @@ static void handle_locale()
|
||||
*/
|
||||
static const int cat[] =
|
||||
{
|
||||
0, LC_ALL, LC_COLLATE, LC_CTYPE, LC_MESSAGES, LC_MONETARY, LC_NUMERIC, LC_TIME
|
||||
0,
|
||||
LC_ALL,
|
||||
LC_COLLATE,
|
||||
LC_CTYPE,
|
||||
LC_MESSAGES,
|
||||
LC_MONETARY,
|
||||
LC_NUMERIC,
|
||||
LC_TIME
|
||||
}
|
||||
;
|
||||
|
||||
@@ -277,18 +297,23 @@ static void handle_locale()
|
||||
|
||||
if( wcscmp( wsetlocale( LC_MESSAGES, (void *)0 ), old ) != 0 )
|
||||
{
|
||||
/* Make change known to gettext. */
|
||||
|
||||
/* Try to make change known to gettext. */
|
||||
#ifdef HAVE__NL_MSG_CAT_CNTR
|
||||
{
|
||||
extern int _nl_msg_cat_cntr;
|
||||
extern int _nl_msg_cat_cntr;
|
||||
++_nl_msg_cat_cntr;
|
||||
}
|
||||
|
||||
}
|
||||
#elif HAVE_DCGETTEXT
|
||||
dcgettext("fish","Changing language to English",LC_MESSAGES);
|
||||
#endif
|
||||
|
||||
if( is_interactive )
|
||||
{
|
||||
complete_destroy();
|
||||
complete_init();
|
||||
|
||||
debug( 0, _(L"Changing language to english") );
|
||||
debug( 0, _(L"Changing language to English") );
|
||||
}
|
||||
}
|
||||
free( old );
|
||||
@@ -339,22 +364,99 @@ static void universal_callback( int type,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Make sure the PATH variable contains the essaential directories
|
||||
*/
|
||||
static void setup_path()
|
||||
{
|
||||
wchar_t *path;
|
||||
|
||||
int i, j;
|
||||
array_list_t l;
|
||||
|
||||
const wchar_t *path_el[] =
|
||||
{
|
||||
L"/bin",
|
||||
L"/usr/bin",
|
||||
PREFIX L"/bin",
|
||||
0
|
||||
}
|
||||
;
|
||||
|
||||
path = env_get( L"PATH" );
|
||||
if( !path )
|
||||
{
|
||||
env_set( L"PATH", 0, ENV_EXPORT | ENV_GLOBAL | ENV_USER );
|
||||
path=0;
|
||||
}
|
||||
|
||||
al_init( &l );
|
||||
|
||||
if( path )
|
||||
expand_variable_array( path, &l );
|
||||
|
||||
for( j=0; path_el[j]; j++ )
|
||||
{
|
||||
int has_el=0;
|
||||
|
||||
for( i=0; i<al_get_count( &l); i++ )
|
||||
{
|
||||
wchar_t * el = (wchar_t *)al_get( &l, i );
|
||||
size_t len = wcslen( el );
|
||||
while( (len > 0) && (el[len-1]==L'/') )
|
||||
len--;
|
||||
if( (wcslen( path_el[j] ) == len) && (wcsncmp( el, path_el[j], len)==0) )
|
||||
{
|
||||
has_el = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if( !has_el )
|
||||
{
|
||||
string_buffer_t b;
|
||||
|
||||
debug( 3, L"directory %ls was missing", path_el[j] );
|
||||
|
||||
sb_init( &b );
|
||||
if( path )
|
||||
{
|
||||
sb_append( &b, path );
|
||||
}
|
||||
|
||||
sb_append2( &b,
|
||||
ARRAY_SEP_STR,
|
||||
path_el[j],
|
||||
(void *)0 );
|
||||
|
||||
env_set( L"PATH", (wchar_t *)b.buff, ENV_GLOBAL | ENV_EXPORT );
|
||||
|
||||
sb_destroy( &b );
|
||||
|
||||
al_foreach( &l, (void (*)(const void *))&free );
|
||||
path = env_get( L"PATH" );
|
||||
al_truncate( &l, 0 );
|
||||
expand_variable_array( path, &l );
|
||||
}
|
||||
}
|
||||
|
||||
al_foreach( &l, (void (*)(const void *))&free );
|
||||
al_destroy( &l );
|
||||
}
|
||||
|
||||
void env_init()
|
||||
{
|
||||
char **p;
|
||||
struct passwd *pw;
|
||||
wchar_t *uname, *path;
|
||||
wchar_t *uname;
|
||||
|
||||
sb_init( &dyn_var );
|
||||
|
||||
b_init( &export_buffer );
|
||||
|
||||
|
||||
/*
|
||||
These variables can not be altered directly by the user
|
||||
*/
|
||||
hash_init( &env_read_only, &hash_wcs_func, &hash_wcs_cmp );
|
||||
|
||||
|
||||
hash_put( &env_read_only, L"status", L"" );
|
||||
hash_put( &env_read_only, L"history", L"" );
|
||||
hash_put( &env_read_only, L"_", L"" );
|
||||
@@ -387,6 +489,11 @@ void env_init()
|
||||
hash_init( &top->env, &hash_wcs_func, &hash_wcs_cmp );
|
||||
global_env = top;
|
||||
global = &top->env;
|
||||
|
||||
/*
|
||||
Now the environemnt variable handling is set up, the next step
|
||||
is to insert valid data
|
||||
*/
|
||||
|
||||
/*
|
||||
Import environment variables
|
||||
@@ -424,77 +531,14 @@ void env_init()
|
||||
free(key);
|
||||
}
|
||||
|
||||
path = env_get( L"PATH" );
|
||||
if( !path )
|
||||
{
|
||||
env_set( L"PATH", L"/bin" ARRAY_SEP_STR L"/usr/bin", ENV_EXPORT | ENV_GLOBAL );
|
||||
path = env_get( L"PATH" );
|
||||
}
|
||||
else
|
||||
{
|
||||
int i, j;
|
||||
array_list_t l;
|
||||
|
||||
al_init( &l );
|
||||
expand_variable_array( path, &l );
|
||||
/*
|
||||
Set up the PATH variable
|
||||
*/
|
||||
setup_path();
|
||||
|
||||
debug( 3, L"PATH is %ls", path );
|
||||
|
||||
|
||||
const wchar_t *path_el[] =
|
||||
{
|
||||
L"/bin",
|
||||
L"/usr/bin",
|
||||
PREFIX L"/bin",
|
||||
0
|
||||
}
|
||||
;
|
||||
|
||||
for( j=0; path_el[j]; j++ )
|
||||
{
|
||||
int has_el=0;
|
||||
|
||||
debug( 3, L"Check directory %ls", path_el[j] );
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( &l); i++ )
|
||||
{
|
||||
wchar_t * el = (wchar_t *)al_get( &l, i );
|
||||
size_t len = wcslen( el );
|
||||
while( (len > 0) && (el[len-1]==L'/') )
|
||||
len--;
|
||||
if( (wcslen( path_el[j] ) == len) && (wcsncmp( el, path_el[j], len)==0) )
|
||||
{
|
||||
has_el = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if( !has_el )
|
||||
{
|
||||
string_buffer_t b;
|
||||
debug( 3, L"directory %ls was missing", path_el[j] );
|
||||
sb_init( &b );
|
||||
sb_append2( &b, path,
|
||||
ARRAY_SEP_STR,
|
||||
path_el[j],
|
||||
(void *)0 );
|
||||
|
||||
env_set( L"PATH", (wchar_t *)b.buff, ENV_GLOBAL | ENV_EXPORT );
|
||||
sb_destroy( &b );
|
||||
path = env_get( L"PATH" );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
debug( 3, L"After: PATH is %ls", path );
|
||||
|
||||
al_foreach( &l, (void (*)(const void *))&free );
|
||||
al_destroy( &l );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Set up the USER variable
|
||||
*/
|
||||
pw = getpwuid( getuid() );
|
||||
if( pw )
|
||||
{
|
||||
@@ -609,7 +653,7 @@ void env_set( const wchar_t *key,
|
||||
/*
|
||||
Zero element arrays are internaly not coded as null but as this placeholder string
|
||||
*/
|
||||
if( !val && ( var_mode & ENV_USER ) )
|
||||
if( !val )
|
||||
{
|
||||
val = ENV_NULL;
|
||||
}
|
||||
@@ -696,7 +740,8 @@ void env_set( const wchar_t *key,
|
||||
else
|
||||
{
|
||||
/*
|
||||
New variable with unspecified scope. The default scope is the innermost scope that is shadowing
|
||||
New variable with unspecified scope. The default
|
||||
scope is the innermost scope that is shadowing
|
||||
*/
|
||||
node = top;
|
||||
while( node->next && !node->new_scope )
|
||||
@@ -765,8 +810,6 @@ void env_set( const wchar_t *key,
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Attempt to remove/free the specified key/value pair from the
|
||||
specified hash table.
|
||||
@@ -1038,7 +1081,9 @@ static void add_key_to_hash( const void *key,
|
||||
var_entry_t *e = (var_entry_t *)data;
|
||||
if( ( e->export && get_names_show_exported) ||
|
||||
( !e->export && get_names_show_unexported) )
|
||||
{
|
||||
hash_put( (hash_table_t *)aux, key, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,12 +11,19 @@
|
||||
#include <pwd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#if HAVE_NCURSES_H
|
||||
#include <ncurses.h>
|
||||
#else
|
||||
#include <curses.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_TERM_H
|
||||
#include <term.h>
|
||||
#elif HAVE_NCURSES_TERM_H
|
||||
#include <ncurses/term.h>
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
9
event.c
9
event.c
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "util.h"
|
||||
#include "wutil.h"
|
||||
#include "function.h"
|
||||
#include "proc.h"
|
||||
#include "parser.h"
|
||||
@@ -154,7 +155,9 @@ static event_t *event_copy( event_t *event, int copy_arguments )
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Test if specified event is blocked
|
||||
*/
|
||||
static int event_is_blocked( event_t *e )
|
||||
{
|
||||
block_t *block;
|
||||
@@ -325,7 +328,6 @@ static void event_fire_internal( event_t *event )
|
||||
array_list_t *fire=0;
|
||||
|
||||
int was_subshell = is_subshell;
|
||||
// int was_interactive = is_interactive;
|
||||
|
||||
/*
|
||||
First we free all events that have been removed
|
||||
@@ -402,7 +404,6 @@ static void event_fire_internal( event_t *event )
|
||||
they are marked as non-interactive and as a subshell
|
||||
*/
|
||||
is_subshell=1;
|
||||
// is_interactive=0;
|
||||
eval( (wchar_t *)b->buff, 0, TOP );
|
||||
|
||||
}
|
||||
@@ -411,7 +412,6 @@ static void event_fire_internal( event_t *event )
|
||||
Restore interactivity flags
|
||||
*/
|
||||
is_subshell = was_subshell;
|
||||
// is_interactive = was_interactive;
|
||||
|
||||
if( b )
|
||||
{
|
||||
@@ -531,7 +531,6 @@ void event_fire( event_t *event )
|
||||
sig_list[active_list].signal[sig_list[active_list].count++]=event->param1.signal;
|
||||
else
|
||||
sig_list[active_list].overflow=1;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
1
event.h
1
event.h
@@ -112,7 +112,6 @@ int event_get( event_t *criterion, array_list_t *out );
|
||||
dispatched.
|
||||
|
||||
\param event the specific event whose handlers should fire
|
||||
\param arguments the argument string to send to the event handler function
|
||||
*/
|
||||
void event_fire( event_t *event );
|
||||
|
||||
|
||||
38
exec.c
38
exec.c
@@ -385,15 +385,15 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
|
||||
IO redirections and other file descriptor actions are performed.
|
||||
|
||||
\param j the job to set up the IO for
|
||||
\param exit_on_error whether to call exit() on errors
|
||||
\param p the child process to set up
|
||||
|
||||
\return 1 on sucess, 0 on failiure
|
||||
*/
|
||||
static int setup_child_process( job_t *j, process_t *p )
|
||||
{
|
||||
int res;
|
||||
|
||||
if( is_interactive && p->type==EXTERNAL )
|
||||
|
||||
if( j->terminal )
|
||||
{
|
||||
pid_t pid;
|
||||
/*
|
||||
@@ -442,6 +442,7 @@ static int setup_child_process( job_t *j, process_t *p )
|
||||
*/
|
||||
static void launch_process( process_t *p )
|
||||
{
|
||||
// debug( 1, L"exec '%ls'", p->argv[0] );
|
||||
|
||||
execve (wcs2str(p->actual_cmd), wcsv2strv( (const wchar_t **) p->argv), env_export_arr( 0 ) );
|
||||
debug( 0,
|
||||
@@ -601,7 +602,7 @@ static void internal_exec_helper( const wchar_t *def,
|
||||
static int handle_new_child( job_t *j, process_t *p )
|
||||
{
|
||||
|
||||
if( is_interactive && p->type==EXTERNAL )
|
||||
if( j->terminal )
|
||||
{
|
||||
int new_pgid=0;
|
||||
|
||||
@@ -678,7 +679,7 @@ void exec( job_t *j )
|
||||
int exec_error=0;
|
||||
|
||||
|
||||
debug( 4, L"Exec job %ls with id %d", j->command, j->job_id );
|
||||
debug( 4, L"Exec job '%ls' with id %d", j->command, j->job_id );
|
||||
|
||||
if( j->first_process->type==INTERNAL_EXEC )
|
||||
{
|
||||
@@ -704,8 +705,7 @@ void exec( job_t *j )
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pipe_read.fd=0;
|
||||
pipe_write.fd=1;
|
||||
@@ -806,7 +806,7 @@ void exec( job_t *j )
|
||||
wchar_t **arg;
|
||||
int i;
|
||||
string_buffer_t sb;
|
||||
|
||||
|
||||
const wchar_t * def = function_get_definition( p->argv[0] );
|
||||
// fwprintf( stderr, L"run function %ls\n", argv[0] );
|
||||
if( def == 0 )
|
||||
@@ -814,14 +814,29 @@ void exec( job_t *j )
|
||||
debug( 0, _( L"Unknown function '%ls'" ), p->argv[0] );
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
These two lines must be called before the new block is pushed
|
||||
*/
|
||||
int lineno = parser_get_lineno();
|
||||
wchar_t *file = parser_current_filename()?wcsdup(parser_current_filename()):0;
|
||||
|
||||
parser_push_block( FUNCTION_CALL );
|
||||
|
||||
al_init( ¤t_block->param2.function_vars );
|
||||
current_block->param1.function_name = wcsdup( p->argv[0] );
|
||||
current_block->param3.function_lineno = lineno;
|
||||
current_block->param4.function_filename = file;
|
||||
|
||||
if( builtin_count_args(p->argv)>1 )
|
||||
{
|
||||
sb_init( &sb );
|
||||
|
||||
for( i=1, arg=p->argv+1; *arg; i++, arg++ )
|
||||
{
|
||||
al_push( ¤t_block->param2.function_vars,
|
||||
escape(*arg, 1) );
|
||||
|
||||
if( i != 1 )
|
||||
sb_append( &sb, ARRAY_SEP_STR );
|
||||
sb_append( &sb, *arg );
|
||||
@@ -830,6 +845,11 @@ void exec( job_t *j )
|
||||
env_set( L"argv", (wchar_t *)sb.buff, ENV_LOCAL );
|
||||
sb_destroy( &sb );
|
||||
}
|
||||
else
|
||||
{
|
||||
env_set( L"argv", 0, ENV_LOCAL );
|
||||
}
|
||||
|
||||
parser_forbid_function( p->argv[0] );
|
||||
|
||||
if( p->next )
|
||||
@@ -1014,6 +1034,7 @@ void exec( job_t *j )
|
||||
if( io_buffer->param2.out_buffer->used != 0 )
|
||||
{
|
||||
pid = fork();
|
||||
|
||||
if( pid == 0 )
|
||||
{
|
||||
/*
|
||||
@@ -1309,5 +1330,6 @@ int exec_subshell( const wchar_t *cmd,
|
||||
}
|
||||
|
||||
io_buffer_destroy( io_buffer );
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
109
expand.c
109
expand.c
@@ -38,39 +38,58 @@ parameter expansion.
|
||||
#include "exec.h"
|
||||
#include "tokenizer.h"
|
||||
#include "complete.h"
|
||||
#include "translate.h"
|
||||
|
||||
/**
|
||||
Description for child process
|
||||
*/
|
||||
#define COMPLETE_CHILD_PROCESS_DESC COMPLETE_SEP_STR L"Child process"
|
||||
#define COMPLETE_CHILD_PROCESS_DESC _( L"Child process")
|
||||
|
||||
/**
|
||||
Description for non-child process
|
||||
*/
|
||||
#define COMPLETE_PROCESS_DESC COMPLETE_SEP_STR L"Process"
|
||||
#define COMPLETE_PROCESS_DESC _( L"Process")
|
||||
|
||||
/**
|
||||
Description for long job
|
||||
*/
|
||||
#define COMPLETE_JOB_DESC COMPLETE_SEP_STR L"Job"
|
||||
#define COMPLETE_JOB_DESC _( L"Job")
|
||||
|
||||
/**
|
||||
Description for short job. The job command is concatenated
|
||||
*/
|
||||
#define COMPLETE_JOB_DESC_VAL COMPLETE_SEP_STR, L"Job: "
|
||||
#define COMPLETE_JOB_DESC_VAL _( L"Job: ")
|
||||
|
||||
/**
|
||||
Description for the shells own pid
|
||||
*/
|
||||
#define COMPLETE_SELF_DESC COMPLETE_SEP_STR L"Shell process"
|
||||
#define COMPLETE_SELF_DESC _( L"Shell process")
|
||||
|
||||
/**
|
||||
Description for the shells own pid
|
||||
*/
|
||||
#define COMPLETE_LAST_DESC COMPLETE_SEP_STR L"Last background job"
|
||||
#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'.")
|
||||
|
||||
#define COMPLETE_VAR_DESC L"Variable name is zero characters long."
|
||||
#define COMPLETE_VAR2_DESC L"Variable name is zero characters long. Did you mean{$VARIABLE}? To learn about variable expansion in fish, type 'help expand-variable'."
|
||||
|
||||
/**
|
||||
String in process expansion denoting ourself
|
||||
@@ -393,8 +412,10 @@ static int find_process( const wchar_t *proc,
|
||||
{
|
||||
al_push( out,
|
||||
wcsdupcat2( jid+wcslen(proc),
|
||||
COMPLETE_JOB_DESC_VAL, j->command,
|
||||
0 ) );
|
||||
COMPLETE_SEP_STR,
|
||||
COMPLETE_JOB_DESC_VAL,
|
||||
j->command,
|
||||
(void *)0 ) );
|
||||
|
||||
|
||||
}
|
||||
@@ -435,8 +456,10 @@ static int find_process( const wchar_t *proc,
|
||||
{
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
{
|
||||
wchar_t *res = wcsdupcat( j->command + wcslen(proc),
|
||||
COMPLETE_JOB_DESC );
|
||||
wchar_t *res = wcsdupcat2( j->command + wcslen(proc),
|
||||
COMPLETE_SEP_STR,
|
||||
COMPLETE_JOB_DESC,
|
||||
(void *)0 );
|
||||
// fwprintf( stderr, L"Woot %ls\n", res );
|
||||
|
||||
al_push( out, res );
|
||||
@@ -474,8 +497,10 @@ static int find_process( const wchar_t *proc,
|
||||
{
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
{
|
||||
wchar_t *res = wcsdupcat( p->actual_cmd + wcslen(proc),
|
||||
COMPLETE_CHILD_PROCESS_DESC );
|
||||
wchar_t *res = wcsdupcat2( p->actual_cmd + wcslen(proc),
|
||||
COMPLETE_SEP_STR,
|
||||
COMPLETE_CHILD_PROCESS_DESC,
|
||||
(void *)0);
|
||||
al_push( out, res );
|
||||
}
|
||||
else
|
||||
@@ -584,8 +609,10 @@ static int find_process( const wchar_t *proc,
|
||||
{
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
{
|
||||
wchar_t *res = wcsdupcat( cmd + wcslen(proc),
|
||||
COMPLETE_PROCESS_DESC );
|
||||
wchar_t *res = wcsdupcat2( cmd + wcslen(proc),
|
||||
COMPLETE_SEP_STR,
|
||||
COMPLETE_PROCESS_DESC,
|
||||
(void *)0);
|
||||
if( res )
|
||||
al_push( out, res );
|
||||
}
|
||||
@@ -627,12 +654,12 @@ static int expand_pid( wchar_t *in,
|
||||
{
|
||||
if( wcsncmp( in+1, SELF_STR, wcslen(in+1) )==0 )
|
||||
{
|
||||
wchar_t *res = wcsdupcat( SELF_STR+wcslen(in+1), COMPLETE_SELF_DESC );
|
||||
wchar_t *res = wcsdupcat2( SELF_STR+wcslen(in+1), COMPLETE_SEP_STR, COMPLETE_SELF_DESC, (void *)0 );
|
||||
al_push( out, res );
|
||||
}
|
||||
else if( wcsncmp( in+1, LAST_STR, wcslen(in+1) )==0 )
|
||||
{
|
||||
wchar_t *res = wcsdupcat( LAST_STR+wcslen(in+1), COMPLETE_LAST_DESC );
|
||||
wchar_t *res = wcsdupcat2( LAST_STR+wcslen(in+1), COMPLETE_SEP_STR, COMPLETE_LAST_DESC, (void *)0 );
|
||||
al_push( out, res );
|
||||
}
|
||||
}
|
||||
@@ -735,20 +762,44 @@ static int expand_variables( wchar_t *in, array_list_t *out )
|
||||
|
||||
if( var_len == 0 )
|
||||
{
|
||||
if( in[stop_pos] == BRACKET_BEGIN )
|
||||
switch( in[stop_pos] )
|
||||
{
|
||||
|
||||
error( SYNTAX_ERROR,
|
||||
-1, COMPLETE_VAR_DESC
|
||||
COMPLETE_VAR2_DESC );
|
||||
}
|
||||
else
|
||||
{
|
||||
error( SYNTAX_ERROR,
|
||||
-1,
|
||||
COMPLETE_VAR_DESC);
|
||||
case BRACKET_BEGIN:
|
||||
{
|
||||
error( SYNTAX_ERROR,
|
||||
-1,
|
||||
COMPLETE_VAR_BRACKET_DESC );
|
||||
break;
|
||||
}
|
||||
|
||||
case INTERNAL_SEPARATOR:
|
||||
{
|
||||
error( SYNTAX_ERROR,
|
||||
-1,
|
||||
COMPLETE_VAR_PARAN_DESC );
|
||||
break;
|
||||
}
|
||||
|
||||
case 0:
|
||||
{
|
||||
error( SYNTAX_ERROR,
|
||||
-1,
|
||||
COMPLETE_VAR_NULL_DESC,
|
||||
in[stop_pos] );
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
error( SYNTAX_ERROR,
|
||||
-1,
|
||||
COMPLETE_VAR_DESC,
|
||||
in[stop_pos] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
is_ok = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -52,6 +52,8 @@ fi
|
||||
%_mandir/man1/mimedb.1*
|
||||
%_mandir/man1/set_color.1*
|
||||
%_mandir/man1/count.1*
|
||||
%_mandir/man1/fishd.1*
|
||||
%_mandir/man1/fish_pager.1*
|
||||
%attr(0755,root,root) %_bindir/fish
|
||||
%attr(0755,root,root) %_bindir/fishd
|
||||
%attr(0755,root,root) %_bindir/fish_pager
|
||||
|
||||
@@ -27,7 +27,12 @@
|
||||
#include <termio.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_TERM_H
|
||||
#include <term.h>
|
||||
#elif HAVE_NCURSES_TERM_H
|
||||
#include <ncurses/term.h>
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
118
fishd.c
118
fishd.c
@@ -2,11 +2,45 @@
|
||||
|
||||
The universal variable server. fishd is automatically started by fish
|
||||
if a fishd server isn't already running. fishd reads any saved
|
||||
variables from ~/.fishd, and takes care of commonication between fish
|
||||
variables from ~/.fishd, and takes care of communication between fish
|
||||
instances. When no clients are running, fishd will automatically shut
|
||||
down and save.
|
||||
|
||||
\subsection fishd-commands Commands
|
||||
|
||||
Fishd works by sending and receiving commands. Each command is ended
|
||||
with a newline. These are the commands supported by fishd:
|
||||
|
||||
<pre>set KEY:VALUE
|
||||
set_export KEY:VALUE
|
||||
</pre>
|
||||
|
||||
These commands update the value of a variable. The only difference
|
||||
between the two is that <tt>set_export</tt>-variables should be
|
||||
exported to children of the process using them. The variable value may
|
||||
be escaped using C-style backslash escapes. In fact, this is required
|
||||
for newline characters, which would otherwise be interpreted as end of
|
||||
command.
|
||||
|
||||
<pre>erase KEY
|
||||
</pre>
|
||||
|
||||
Erase the variable with the specified name.
|
||||
|
||||
<pre>barrier
|
||||
barrier_reply
|
||||
</pre>
|
||||
|
||||
A \c barrier command will result in a barrier_reply being added to
|
||||
the end of the senders queue of unsent messages. These commands are
|
||||
used to synchronize clients, since once the reply for a barrier
|
||||
message returns, the sender can know that any updates available at the
|
||||
time the original barrier request was sent have been received.
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
@@ -19,6 +53,10 @@ down and save.
|
||||
#include <pwd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <signal.h>
|
||||
@@ -35,6 +73,15 @@ down and save.
|
||||
#define UNIX_PATH_MAX 100
|
||||
#endif
|
||||
|
||||
/**
|
||||
Fallback if MSG_DONTWAIT isn't defined. That's actually prerry bad,
|
||||
and may lead to strange fishd behaviour, but at least it should
|
||||
work most of the time.
|
||||
*/
|
||||
#ifndef MSG_DONTWAIT
|
||||
#define MSG_DONTWAIT 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
Small greeting to show that fishd is running
|
||||
*/
|
||||
@@ -75,6 +122,11 @@ static int sock;
|
||||
*/
|
||||
static int quit=0;
|
||||
|
||||
/**
|
||||
Dynamically generated function, made from the documentation in doc_src.
|
||||
*/
|
||||
void print_help();
|
||||
|
||||
/**
|
||||
Constructs the fish socket filename
|
||||
*/
|
||||
@@ -396,11 +448,9 @@ static void save()
|
||||
*/
|
||||
static void init()
|
||||
{
|
||||
program_name=L"fishd";
|
||||
|
||||
sock = get_socket();
|
||||
daemonize();
|
||||
wsetlocale( LC_ALL, L"" );
|
||||
env_universal_common_init( &broadcast );
|
||||
|
||||
load();
|
||||
@@ -419,8 +469,68 @@ int main( int argc, char ** argv )
|
||||
|
||||
fd_set read_fd, write_fd;
|
||||
|
||||
init();
|
||||
program_name=L"fishd";
|
||||
wsetlocale( LC_ALL, L"" );
|
||||
|
||||
/*
|
||||
Parse options
|
||||
*/
|
||||
while( 1 )
|
||||
{
|
||||
#ifdef HAVE_GETOPT_LONG
|
||||
static struct option
|
||||
long_options[] =
|
||||
{
|
||||
{
|
||||
"help", no_argument, 0, 'h'
|
||||
}
|
||||
,
|
||||
{
|
||||
"version", no_argument, 0, 'v'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
int opt_index = 0;
|
||||
|
||||
int opt = getopt_long( argc,
|
||||
argv,
|
||||
"hv",
|
||||
long_options,
|
||||
&opt_index );
|
||||
|
||||
#else
|
||||
int opt = getopt( argc,
|
||||
argv,
|
||||
"hv" );
|
||||
#endif
|
||||
if( opt == -1 )
|
||||
break;
|
||||
|
||||
switch( opt )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
print_help();
|
||||
exit(0);
|
||||
|
||||
case 'v':
|
||||
debug( 0, L"%ls, version %s\n", program_name, PACKAGE_VERSION );
|
||||
exit( 0 );
|
||||
|
||||
case '?':
|
||||
return 1;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
init();
|
||||
while(1)
|
||||
{
|
||||
connection_t *c;
|
||||
|
||||
50
function.c
50
function.c
@@ -9,6 +9,7 @@
|
||||
#include <signal.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "wutil.h"
|
||||
#include "util.h"
|
||||
#include "function.h"
|
||||
#include "proc.h"
|
||||
@@ -16,6 +17,7 @@
|
||||
#include "common.h"
|
||||
#include "intern.h"
|
||||
#include "event.h"
|
||||
#include "reader.h"
|
||||
|
||||
|
||||
/**
|
||||
@@ -27,6 +29,8 @@ typedef struct
|
||||
wchar_t *cmd;
|
||||
/** Function description */
|
||||
wchar_t *desc;
|
||||
const wchar_t *definition_file;
|
||||
int definition_offset;
|
||||
int is_binding;
|
||||
}
|
||||
function_data_t;
|
||||
@@ -61,6 +65,19 @@ void function_destroy()
|
||||
hash_destroy( &function );
|
||||
}
|
||||
|
||||
static int count_lineno( const wchar_t *str, int len )
|
||||
{
|
||||
int res = 0;
|
||||
int i;
|
||||
for( i=0; i<len; i++ )
|
||||
{
|
||||
if( str[i] == L'\n' )
|
||||
res++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void function_add( const wchar_t *name,
|
||||
const wchar_t *val,
|
||||
const wchar_t *desc,
|
||||
@@ -74,18 +91,22 @@ void function_add( const wchar_t *name,
|
||||
if( function_exists( name ) )
|
||||
function_remove( name );
|
||||
|
||||
|
||||
|
||||
function_data_t *d = malloc( sizeof( function_data_t ) );
|
||||
d->definition_offset = count_lineno( parser_get_buffer(), current_block->tok_pos );
|
||||
d->cmd = wcsdup( val );
|
||||
cmd_end = d->cmd + wcslen(d->cmd)-1;
|
||||
while( (cmd_end>d->cmd) && wcschr( L"\n\r\t ", *cmd_end ) )
|
||||
{
|
||||
*cmd_end--=0;
|
||||
*cmd_end-- = 0;
|
||||
}
|
||||
|
||||
d->desc = desc?wcsdup( desc ):0;
|
||||
d->is_binding = is_binding;
|
||||
d->definition_file = reader_current_filename()?intern(reader_current_filename()):0;
|
||||
hash_put( &function, intern(name), d );
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( events ); i++ )
|
||||
{
|
||||
event_add_handler( (event_t *)al_get( events, i ) );
|
||||
@@ -135,7 +156,7 @@ const wchar_t *function_get_desc( const wchar_t *argv )
|
||||
if( data == 0 )
|
||||
return 0;
|
||||
|
||||
return data->desc?data->desc:data->cmd;
|
||||
return data->desc;
|
||||
}
|
||||
|
||||
void function_set_desc( const wchar_t *name, const wchar_t *desc )
|
||||
@@ -171,3 +192,26 @@ void function_get_names( array_list_t *list, int get_hidden )
|
||||
|
||||
}
|
||||
|
||||
const wchar_t *function_get_definition_file( const wchar_t *argv )
|
||||
{
|
||||
function_data_t *data =
|
||||
(function_data_t *)hash_get( &function, argv );
|
||||
if( data == 0 )
|
||||
return 0;
|
||||
|
||||
return data->definition_file;
|
||||
}
|
||||
|
||||
|
||||
int function_get_definition_offset( const wchar_t *argv )
|
||||
{
|
||||
function_data_t *data =
|
||||
(function_data_t *)hash_get( &function, argv );
|
||||
if( data == 0 )
|
||||
return -1;
|
||||
|
||||
return data->definition_offset;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -69,4 +69,8 @@ int function_exists( const wchar_t *name );
|
||||
void function_get_names( array_list_t *list,
|
||||
int get_hidden );
|
||||
|
||||
const wchar_t *function_get_definition_file( const wchar_t *name );
|
||||
|
||||
int function_get_definition_offset( const wchar_t *name );
|
||||
|
||||
#endif
|
||||
|
||||
@@ -62,19 +62,19 @@ complete -c darcs -s h -l help -d (_ "Shows brief description of command and its
|
||||
complete -c darcs -l disable -d (_ "Disable this command")
|
||||
complete -c darcs -l repodir -d (_ "Specify the repository directory in which to run") -x -a '(__fish_complete_directory (commandline -ct))'
|
||||
complete -c darcs -s v -l verbose -d (_ "Verbose mode")
|
||||
complete -c darcs -l standard-verbosity -d (_ "Neither verbose nor quiet output")
|
||||
|
||||
#
|
||||
# Here follows a huge list of subcommand-specific completions
|
||||
# Here follows a huge list of subcommand-specific completions. These are incomplete.
|
||||
#
|
||||
|
||||
set -- record_opt -c darcs -n 'contains record (commandline -poc)'
|
||||
set -l record_opt -c darcs -n 'contains record (commandline -poc)'
|
||||
complete $record_opt -s m -l patch-name -d (_ "Name of patch") -x
|
||||
complete $record_opt -s A -l author -d (_ "Specify author id") -x
|
||||
complete $record_opt -l logfile -d (_ "Give patch name and comment in file") -r
|
||||
complete $record_opt -s a -l all -d (_ "Answer yes to all patches")
|
||||
complete $record_opt -s l -l look-for-adds -d (_ "In addition to modifications, look for files that are not boring, and thus are potentially pending addition")
|
||||
complete $record_opt -l delete-logfile -d (_ "Delete the logfile when done")
|
||||
complete $record_opt -l standard-verbosity -d (_ "Don't give verbose output")
|
||||
complete $record_opt -l no-test -d (_ "Don't run the test script")
|
||||
complete $record_opt -l test -d (_ "Run the test script")
|
||||
complete $record_opt -l leave-test-directory -d (_ "Don't remove the test directory")
|
||||
@@ -90,10 +90,9 @@ complete $record_opt -l skip-long-comment -d (_ "Don't give a long comment")
|
||||
complete $record_opt -l prompt-long-comment -d (_ "Prompt for whether to edit the long comment")
|
||||
complete $record_opt -l ignore-times -d (_ "Don't trust the file modification times")
|
||||
complete $record_opt -l dont-look-for-adds -d (_ "Don't look for any files or directories that could be added, and don't add them automatically")
|
||||
set -e record_opt
|
||||
|
||||
|
||||
set -- pull_opt -c darcs -n 'contains pull (commandline -poc)'
|
||||
set -l pull_opt -c darcs -n 'contains pull (commandline -poc)'
|
||||
complete $pull_opt -s p -l patches -d (_ "Select patches matching REGEXP") -x
|
||||
complete $pull_opt -s t -l tags -d (_ "Select tags matching REGEXP") -x
|
||||
complete $pull_opt -s a -l all -d (_ "Answer yes to all patches")
|
||||
@@ -108,26 +107,23 @@ complete $pull_opt -l test -d (_ "Run the test script")
|
||||
complete $pull_opt -l no-test -d (_ "Don't run the test script")
|
||||
complete $pull_opt -l dry-run -d (_ "Don't actually take the action")
|
||||
complete $pull_opt -l no-summary -d (_ "Don't summarize changes")
|
||||
complete $pull_opt -l standard-verbosity -d (_ "Neither verbose nor quiet output")
|
||||
complete $pull_opt -l ignore-times -d (_ "Don't trust the file modification times")
|
||||
complete $pull_opt -l no-deps -d (_ "Don't automatically fulfill dependencies")
|
||||
complete $pull_opt -l set-default -d (_ "Set default repository [DEFAULT]")
|
||||
complete $pull_opt -l no-set-default -d (_ "Don't set default repository")
|
||||
complete $pull_opt -l set-scripts-executable -d (_ "Make scripts executable")
|
||||
complete $pull_opt -l dont-set-scripts-executable -d (_ "Don't make scripts executable")
|
||||
set -e pull_opt
|
||||
|
||||
|
||||
set -- apply_opt -c darcs -n 'contains apply (commandline -poc)'
|
||||
set -l apply_opt -c darcs -n 'contains apply (commandline -poc)'
|
||||
complete $apply_opt -s a -l all -d (_ "Answer yes to all patches")
|
||||
complete $apply_opt -l verify -d (_ "Verify that the patch was signed by a key in PUBRING") -r
|
||||
complete $apply_opt -l verify-ssl -d (_ "Verify using openSSL with authorized keys from file 'KEYS'") -r
|
||||
complete $apply_opt -l verify-ssl -d (_ "Verify using openSSL with authorized keys from specified file") -r
|
||||
complete $apply_opt -l sendmail-command -d (_ "Specify sendmail command") -r
|
||||
complete $apply_opt -l reply -d (_ "Reply to email-based patch using FROM address") -x
|
||||
complete $apply_opt -l cc -d (_ "Mail results to additional EMAIL(s). Requires --reply") -x
|
||||
complete $apply_opt -l external-merge -d (_ "Use external tool to merge conflicts") -r
|
||||
complete $apply_opt -l no-verify -d (_ "Don't verify patch signature")
|
||||
complete $apply_opt -l standard-verbosity -d (_ "Don't give verbose output")
|
||||
complete $apply_opt -l ignore-times -d (_ "Don't trust the file modification times")
|
||||
complete $apply_opt -l compress -d (_ "Create compressed patches")
|
||||
complete $apply_opt -l dont-compress -d (_ "Don't create compressed patches")
|
||||
@@ -142,27 +138,25 @@ complete $apply_opt -l leave-test-directory -d (_ "Don't remove the test directo
|
||||
complete $apply_opt -l remove-test-directory -d (_ "Remove the test directory")
|
||||
complete $apply_opt -l set-scripts-executable -d (_ "Make scripts executable")
|
||||
complete $apply_opt -l dont-set-scripts-executable -d (_ "Don't make scripts executable")
|
||||
set -e apply_opt
|
||||
|
||||
set -- check_opt -c darcs -n 'contains check (commandline -poc)'
|
||||
|
||||
set -l check_opt -c darcs -n 'contains check (commandline -poc)'
|
||||
complete $check_opt -s v -l verbose -d (_ "Verbose mode")
|
||||
complete $check_opt -s q -l quiet -d (_ "Suppress informational output")
|
||||
complete $check_opt -l complete -d (_ "Check the entire repository")
|
||||
complete $check_opt -l partial -d (_ "Check patches since latest checkpoint")
|
||||
complete $check_opt -l standard-verbosity -d (_ "Neither verbose nor quiet output")
|
||||
complete $check_opt -l no-test -d (_ "Don't run the test script")
|
||||
complete $check_opt -l test -d (_ "Run the test script")
|
||||
complete $check_opt -l leave-test-directory -d (_ "Don't remove the test directory")
|
||||
complete $check_opt -l remove-test-directory -d (_ "Remove the test directory")
|
||||
set -e check_opt
|
||||
|
||||
set -- mv_opt -c darcs -n 'contains mv (commandline -poc)'
|
||||
|
||||
set -l mv_opt -c darcs -n 'contains mv (commandline -poc)'
|
||||
complete $mv_opt -s v -l verbose -d (_ "Verbose mode")
|
||||
complete $mv_opt -l case-ok -d (_ "Don't refuse to add files differing only in case")
|
||||
complete $mv_opt -l standard-verbosity -d (_ "Don't give verbose output")
|
||||
set -e mv_opt
|
||||
|
||||
set -- send_opt -c darcs -n 'contains send (commandline -poc)'
|
||||
|
||||
set -l send_opt -c darcs -n 'contains send (commandline -poc)'
|
||||
complete $send_opt -s v -l verbose -d (_ "Verbose mode")
|
||||
complete $send_opt -s q -l quiet -d (_ "Suppress informational output")
|
||||
complete $send_opt -xs p -l patches -d (_ "Select patches matching REGEXP")
|
||||
@@ -172,7 +166,6 @@ complete $send_opt -xs A -l author -d (_ "Specify author id")
|
||||
complete $send_opt -rs o -l output -d (_ "Specify output filename")
|
||||
complete $send_opt -s u -l unified -d (_ "Output patch in a darcs-specific format similar to diff -u")
|
||||
complete $send_opt -s s -l summary -d (_ "Summarize changes")
|
||||
complete $send_opt -l standard-verbosity -d (_ "Neither verbose nor quiet output")
|
||||
complete $send_opt -xl matches -d (_ "Select patches matching PATTERN")
|
||||
complete $send_opt -l interactive -d (_ "Prompt user interactively")
|
||||
complete $send_opt -xl from -d (_ "Specify email address")
|
||||
@@ -189,10 +182,55 @@ complete $send_opt -l edit-description -d (_ "Edit the patch bundle description"
|
||||
complete $send_opt -l set-default -d (_ "Set default repository [DEFAULT]")
|
||||
complete $send_opt -l no-set-default -d (_ "Don't set default repository")
|
||||
complete $send_opt -rl sendmail-command -d (_ "Specify sendmail command")
|
||||
set -e send_opt
|
||||
|
||||
set -- init_opt -c darcs -n 'contains initialize (commandline -poc)'
|
||||
|
||||
set -l init_opt -c darcs -n 'contains initialize (commandline -poc)'
|
||||
complete $init_opt -l plain-pristine-tree -d (_ "Use a plain pristine tree [DEFAULT]")
|
||||
complete $init_opt -l no-pristine-tree -d (_ "Use no pristine tree")
|
||||
set -e init_opt
|
||||
|
||||
|
||||
set -l annotate_opt -c darcs -n 'contains annotate (commandline -poc)'
|
||||
complete $annotate_opt -s s -l summary -d (_ "Summarize changes")
|
||||
complete $annotate_opt -l no-summary -d (_ "Don't summarize changes")
|
||||
complete $annotate_opt -s u -l unified -d (_ "Output patch in a darcs-specific format similar to diff -u")
|
||||
complete $annotate_opt -l human-readable -d (_ "Give human readable output")
|
||||
complete $annotate_opt -l xml-output -d (_ "Generate XML formatted output")
|
||||
complete $annotate_opt -l match -x -d (_ "Select patch matching PATTERN")
|
||||
complete $annotate_opt -s p -l patch -x -d (_ "Select patch matching REGEXP")
|
||||
complete $annotate_opt -s t -l tag -x -d (_ "Select tag matching REGEXP")
|
||||
complete $annotate_opt -l creator-hash -x -d (_ "Specify hash of creator patch (see docs)")
|
||||
|
||||
|
||||
set -l changes_opt -c darcs -n 'contains changes (commandline -poc)'
|
||||
complete $changes_opt -l to-match -x -d (_ "Select changes up to a patch matching PATTERN")
|
||||
complete $changes_opt -l to-patch -x -d (_ "Select changes up to a patch matching REGEXP")
|
||||
complete $changes_opt -l to-tag -x -d (_ "Select changes up to a tag matching REGEXP")
|
||||
complete $changes_opt -l from-match -x -d (_ "Select changes starting with a patch matching PATTERN")
|
||||
complete $changes_opt -l from-patch -x -d (_ "Select changes starting with a patch matching REGEXP")
|
||||
complete $changes_opt -l from-tag -x -d (_ "Select changes starting with a tag matching REGEXP")
|
||||
complete $changes_opt -l last -x -d (_ "Select the last NUMBER patches")
|
||||
complete $changes_opt -l matches -x -d (_ "Select patches matching PATTERN")
|
||||
complete $changes_opt -s p -l patches -x -d (_ "Select patches matching REGEXP")
|
||||
complete $changes_opt -s t -l tags -x -d (_ "Select tags matching REGEXP")
|
||||
complete $changes_opt -l context -d (_ "Give output suitable for get --context")
|
||||
complete $changes_opt -l xml-output -d (_ "Generate XML formatted output")
|
||||
complete $changes_opt -l human-readable -d (_ "Give human-readable output")
|
||||
complete $changes_opt -s s -l summary -d (_ "Summarize changes")
|
||||
complete $changes_opt -l no-summary -d (_ "Don't summarize changes")
|
||||
complete $changes_opt -s q -l quiet -d (_ "Suppress informational output")
|
||||
complete $changes_opt -l reverse -d (_ "Show changes in reverse order")
|
||||
complete $changes_opt -l repo -x -d (_ "Specify the repository URL")
|
||||
|
||||
|
||||
set -l add_opt -c darcs -n 'contains add (commandline -poc)'
|
||||
complete $add_opt -l boring -d (_ "Don't skip boring files")
|
||||
complete $add_opt -l case-ok -d (_ "Don't refuse to add files differing only in case")
|
||||
complete $add_opt -s r -l recursive -d (_ "Add contents of subdirectories")
|
||||
complete $add_opt -l not-recursive -d (_ "Don't add contents of subdirectories")
|
||||
complete $add_opt -l date-trick -d (_ "Add files with date appended to avoid conflict. [EXPERIMENTAL]")
|
||||
complete $add_opt -l no-date-trick -d (_ "Don't use experimental date appending trick. [DEFAULT]")
|
||||
complete $add_opt -s q -l quiet -d (_ "Suppress informational output")
|
||||
complete $add_opt -l dry-run -d (_ "Don't actually take the action")
|
||||
complete $add_opt -s q -l quiet -d (_ "Suppress informational output")
|
||||
|
||||
|
||||
|
||||
68
init/completions/emerge.fish
Normal file
68
init/completions/emerge.fish
Normal file
@@ -0,0 +1,68 @@
|
||||
#Completions for emerge
|
||||
|
||||
function __fish_emerge_use_package -d (_ 'Test if emerge command should have packages as potential completion')
|
||||
for i in (commandline -opc)
|
||||
if contains -- $i -a --ask -p --pretend --oneshot -O --nodeps -f --fetchonly
|
||||
return 0
|
||||
end
|
||||
end
|
||||
return 1
|
||||
end
|
||||
|
||||
function __fish_emerge_manipulate_package -d (_ 'Tests if emerge command should have package as potential completion for removal')
|
||||
for i in (commandline -opc)
|
||||
if contains -- $i -u --update -C --unmerge -P --prune
|
||||
return 0
|
||||
end
|
||||
end
|
||||
return 1
|
||||
end
|
||||
|
||||
function __fish_emerge_print_installed_pkgs -d (_ 'Prints completions for installed packages on the system from /var/db/pkg')
|
||||
if test -d /var/db/pkg
|
||||
find /var/db/pkg/ -type d | cut -d'/' -f6 | sort | uniq | sed 's/-[0-9]\{1,\}\..*$//'
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
complete -f -c emerge -n '__fish_emerge_use_package' -a '(__fish_print_packages)' -d (_ 'Package')
|
||||
complete -f -c emerge -n '__fish_emerge_manipulate_package' -a '(__fish_emerge_print_installed_pkgs)' -d (_ 'Package')
|
||||
complete -c emerge -s h -l help -d (_ "Display help and exit")
|
||||
complete -c emerge -s c -l clean -d (_ "Cleans the system by removing outdated packages")
|
||||
complete -c emerge -l depclean -d (_ "Cleans the system by removing packages that are not associated with explicitly merged packages")
|
||||
complete -c emerge -l info -d (_ "Displays important portage variables that will be exported to ebuild.sh when performing merges")
|
||||
complete -c emerge -l metadata -d (_ "Causes portage to process all the metacache files as is normally done on the tail end of an rsync update using emerge --sync")
|
||||
complete -c emerge -s P -l prune -d (_ "Removes all but the most recently installed version of a package from your system")
|
||||
complete -c emerge -l regen -d (_ "Causes portage to check and update the dependency cache of all ebuilds in the portage tree")
|
||||
complete -c emerge -s s -l search -d (_ "Searches for matches of the supplied string in the current local portage tree")
|
||||
complete -c emerge -s C -l unmerge -d (_ "Removes all matching packages completely from your system")
|
||||
complete -c emerge -s a -l ask -d (_ "Before performing the merge, display what ebuilds and tbz2s will be installed, in the same format as when using --pretend")
|
||||
complete -c emerge -s b -l buildpkg -d (_ "Tell emerge to build binary packages for all ebuilds processed in addition to actually merging the packages")
|
||||
complete -c emerge -s B -l buildpkgonly -d (_ "Creates a binary package, but does not merge it to the system")
|
||||
complete -c emerge -s l -l changelog -d (_ "When pretending, also display the ChangeLog entries for packages that will be upgraded")
|
||||
complete -c emerge -l columns -d (_ "Display the pretend output in a tabular form")
|
||||
complete -c emerge -s d -l debug -d (_ "Tell emerge to run the ebuild command in --debug mode")
|
||||
complete -c emerge -s d -l deep -d (_ "When used in conjunction with --update, this flag forces emerge to consider the entire dependency tree of packages, instead of checking only the immediate dependencies of the packages")
|
||||
complete -c emerge -s e -l emptytree -d (_ "Virtually tweaks the tree of installed packages to contain nothing")
|
||||
complete -c emerge -s f -l fetchonly -d (_ "Instead of doing any package building, just perform fetches for all packages (main package as well as all dependencies)")
|
||||
complete -c emerge -l fetch-all-uri -d (_ "Same as --fetchonly except that all package files, including those not required to build the package, will be processed")
|
||||
complete -c emerge -s g -l getbinpkg -d (_ "Using the server and location defined in PORTAGE_BINHOST, portage will download the information from each binary file there and it will use that information to help build the dependency list")
|
||||
complete -c emerge -s G -l getbinpkgonly -d (_ "This option is identical to -g, except it will not use ANY information from the local machine")
|
||||
complete -c emerge -l newuse -d (_ "Tells emerge to include installed packages where USE flags have changed since installation")
|
||||
complete -c emerge -l noconfmem -d (_ "Merge files in CONFIG_PROTECT to the live fs instead of silently dropping them")
|
||||
complete -c emerge -s O -l nodeps -d (_ "Merge specified packages, but don't merge any dependencies")
|
||||
complete -c emerge -s n -l noreplace -d (_ "Skip the packages specified on the command-line that have already been installed")
|
||||
complete -c emerge -l nospinner -d (_ "Disables the spinner regardless of terminal type")
|
||||
complete -c emerge -l oneshot -d (_ "Emerge as normal, but don't add packages to the world profile")
|
||||
complete -c emerge -s o -l onlydeps -d (_ "Only merge (or pretend to merge) the dependencies of the specified packages, not the packages themselves")
|
||||
complete -c emerge -s p -l pretend -d (_ "Do not merge, display what ebuilds and tbz2s would have been installed")
|
||||
complete -c emerge -s q -l quiet -d (_ "Reduced output from portage's displays")
|
||||
complete -c emerge -l resume -d (_ "Resumes the last merge operation")
|
||||
complete -c emerge -s S -l searchdesc -d (_ "Matches the search string against the description field as well the package's name")
|
||||
complete -c emerge -l skipfirst -d (_ "Remove the first package in the resume list so that a merge may continue in the presence of an uncorrectable or inconsequential error")
|
||||
complete -c emerge -s t -l tree -d (_ "Shows the dependency tree using indentation for dependencies")
|
||||
complete -c emerge -s u -l update -d (_ "Updates packages to the best version available")
|
||||
complete -c emerge -s k -l usepkg -d (_ "Tell emerge to use binary packages (from $PKGDIR) if they are available, thus possibly avoiding some time-consuming compiles")
|
||||
complete -c emerge -s K -l usepkgonly -d (_ "Like --usepkg, except this only allows the use of binary packages, and it will abort the emerge if the package is not available at the time of dependency calculation")
|
||||
complete -c emerge -s v -l verbose -d (_ "Increased or expanded display of content in portage's displays")
|
||||
complete -c emerge -s V -l version -d (_ "Displays the currently installed version of portage along with other information useful for quick reference on a system")
|
||||
@@ -5,3 +5,4 @@ complete -c function -s j -l on-job-exit -d (_ "Make the function a job exit eve
|
||||
complete -c function -s p -l on-process-exit -d (_ "Make the function a process exit event handler") -x
|
||||
complete -c function -s s -l on-signal -d (_ "Make the function a signal event handler") -x
|
||||
complete -c function -s v -l on-variable -d (_ "Make the function a variable update event handler") -x
|
||||
complete -c function -s b -l key-binding -d (_ "Allow dash (-) in function name")
|
||||
|
||||
17
init/completions/fusermount.fish
Normal file
17
init/completions/fusermount.fish
Normal file
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# Completions for fusermount
|
||||
#
|
||||
# Find mount points, borrowed from umount.fish
|
||||
#
|
||||
complete -c fusermount -d (_ "Mount point") -x -a '
|
||||
(
|
||||
cat /etc/mtab | grep "^sshfs" | cut -d " " -f 1-2|tr " " \n|sed -e "s/[0-9\.]*:\//\//"|grep "^/"
|
||||
)
|
||||
'
|
||||
|
||||
complete -c fusermount -s h -d (_ "Display help and exit")
|
||||
complete -c fusermount -s v -d (_ "Display version and exit")
|
||||
complete -c fusermount -s o -x -d (_ "Mount options")
|
||||
complete -c fusermount -s u -d (_ "Unmount")
|
||||
complete -c fusermount -s q -d (_ "Quiet")
|
||||
complete -c fusermount -s z -d (_ "Lazy unmount")
|
||||
@@ -7,7 +7,7 @@ if kill -L ^/dev/null >/dev/null
|
||||
|
||||
complete -c kill -s L -d "List codes and names of available signals"
|
||||
|
||||
set -- signals (kill -L | sed -e 's/\([0-9][0-9]*\) *([A-Z,0-9][A-Z,0-9]*\)/\1 \2\n/g;s/ +/ /g' | sed -e 's/^ //' | grep -E '^[^ ]+')
|
||||
set -- signals (kill -L | sed -e 's/\([0-9][0-9]*\) *\([A-Z,0-9][A-Z,0-9]*\)/\1 \2\n/g;s/ +/ /g' | sed -e 's/^ //' | grep -E '^[^ ]+')
|
||||
for i in $signals
|
||||
set -- number (echo $i | cut -d " " -f 1)
|
||||
set -- name (echo $i | cut -d " " -f 2)
|
||||
|
||||
@@ -7,100 +7,99 @@
|
||||
set -l is_gnu
|
||||
ls --version >/dev/null ^/dev/null; and set is_gnu --is-gnu
|
||||
|
||||
for i in ls ll la
|
||||
set -l cmds -c ls -c ll -c la
|
||||
|
||||
# Shared ls switches
|
||||
# Shared ls switches
|
||||
|
||||
__fish_gnu_complete -c $i -s a -l all -d (_ "Show hidden") $is_gnu
|
||||
__fish_gnu_complete -c $i -s A -l almost-all -d (_ "Show hidden except . and ..") $is_gnu
|
||||
__fish_gnu_complete -c $i -s F -l classify -d (_ "Append filetype indicator") $is_gnu
|
||||
__fish_gnu_complete -c $i -s H -l dereference-command-line -d (_ "Follow symlinks") $is_gnu
|
||||
__fish_gnu_complete -c $i -s L -l dereference -d (_ "Follow symlinks") $is_gnu
|
||||
__fish_gnu_complete -c $i -s R -l recursive -d (_ "List subdirectory recursively") $is_gnu
|
||||
__fish_gnu_complete -c $i -s b -l escape -d (_ "Octal escapes for non graphic characters") $is_gnu
|
||||
__fish_gnu_complete -c $i -s d -l directory -d (_ "List directories, not their content") $is_gnu
|
||||
__fish_gnu_complete -c $i -s h -l human-readable -d (_ "Human readable sizes") $is_gnu
|
||||
__fish_gnu_complete -c $i -s i -l inode -d (_ "Print inode number of files") $is_gnu
|
||||
__fish_gnu_complete -c $i -s n -l numeric-uid-gid -d (_ "Long format, numeric IDs") $is_gnu
|
||||
__fish_gnu_complete -c $i -s p -l file-type -d (_ "Append filetype indicator") $is_gnu
|
||||
__fish_gnu_complete -c $i -s q -l hide-control-chars -d (_ "Replace non-graphic characters with '?'") $is_gnu
|
||||
__fish_gnu_complete -c $i -s r -l reverse -d (_ "Reverse sort order") $is_gnu
|
||||
__fish_gnu_complete -c $i -s s -l size -d (_ "Print size of files") $is_gnu
|
||||
__fish_gnu_complete $cmds -s a -l all -d (_ "Show hidden") $is_gnu
|
||||
__fish_gnu_complete $cmds -s A -l almost-all -d (_ "Show hidden except . and ..") $is_gnu
|
||||
__fish_gnu_complete $cmds -s F -l classify -d (_ "Append filetype indicator") $is_gnu
|
||||
__fish_gnu_complete $cmds -s H -l dereference-command-line -d (_ "Follow symlinks") $is_gnu
|
||||
__fish_gnu_complete $cmds -s L -l dereference -d (_ "Follow symlinks") $is_gnu
|
||||
__fish_gnu_complete $cmds -s R -l recursive -d (_ "List subdirectory recursively") $is_gnu
|
||||
__fish_gnu_complete $cmds -s b -l escape -d (_ "Octal escapes for non graphic characters") $is_gnu
|
||||
__fish_gnu_complete $cmds -s d -l directory -d (_ "List directories, not their content") $is_gnu
|
||||
__fish_gnu_complete $cmds -s h -l human-readable -d (_ "Human readable sizes") $is_gnu
|
||||
__fish_gnu_complete $cmds -s i -l inode -d (_ "Print inode number of files") $is_gnu
|
||||
__fish_gnu_complete $cmds -s n -l numeric-uid-gid -d (_ "Long format, numeric IDs") $is_gnu
|
||||
__fish_gnu_complete $cmds -s p -l file-type -d (_ "Append filetype indicator") $is_gnu
|
||||
__fish_gnu_complete $cmds -s q -l hide-control-chars -d (_ "Replace non-graphic characters with '?'") $is_gnu
|
||||
__fish_gnu_complete $cmds -s r -l reverse -d (_ "Reverse sort order") $is_gnu
|
||||
__fish_gnu_complete $cmds -s s -l size -d (_ "Print size of files") $is_gnu
|
||||
|
||||
complete -c $i -s C -d (_ "List by columns")
|
||||
complete -c $i -s S -d (_ "Sort by size")
|
||||
complete -c $i -s c -d (_ "Show and sort by ctime")
|
||||
complete -c $i -s f -d (_ "Don't sort")
|
||||
complete -c $i -s g -d (_ "Long format without owner")
|
||||
complete -c $i -s k -d (_ "Set blocksize to 1kB")
|
||||
complete -c $i -s l -d (_ "Long format")
|
||||
complete -c $i -s m -d (_ "Comma separated format")
|
||||
complete -c $i -s t -d (_ "Sort by modification time")
|
||||
complete -c $i -s u -d (_ "Show access time")
|
||||
complete -c $i -s x -d (_ "List entries by lines")
|
||||
complete -c $i -s 1 -d (_ "List one file per line")
|
||||
complete $cmds -s C -d (_ "List by columns")
|
||||
complete $cmds -s S -d (_ "Sort by size")
|
||||
complete $cmds -s c -d (_ "Show and sort by ctime")
|
||||
complete $cmds -s f -d (_ "Don't sort")
|
||||
complete $cmds -s g -d (_ "Long format without owner")
|
||||
complete $cmds -s k -d (_ "Set blocksize to 1kB")
|
||||
complete $cmds -s l -d (_ "Long format")
|
||||
complete $cmds -s m -d (_ "Comma separated format")
|
||||
complete $cmds -s t -d (_ "Sort by modification time")
|
||||
complete $cmds -s u -d (_ "Show access time")
|
||||
complete $cmds -s x -d (_ "List entries by lines")
|
||||
complete $cmds -s 1 -d (_ "List one file per line")
|
||||
|
||||
if test -n "$is_gnu"
|
||||
if test -n "$is_gnu"
|
||||
|
||||
# GNU specific features
|
||||
# GNU specific features
|
||||
|
||||
complete -c $i -l author -d (_ "Print author")
|
||||
complete -c $i -l blocksize -x -d (_ "Set block size")
|
||||
complete -c $i -s B -l ignore-backups -d (_ "Ignore files ending with ~")
|
||||
complete -c $i -l color -f -a "never always auto" -d (_ "Use colors")
|
||||
complete -c $i -s D -l dired -d (_ "Generate dired output")
|
||||
complete -c $i -l format -x -a "across commas horizontal long single-column verbose vertical" -d (_ "List format")
|
||||
complete -c $i -l full-time -d (_ "Long format, full-iso time")
|
||||
complete -c $i -s G -l no-group -d (_ "Don't print group information")
|
||||
complete -c $i -l si -d (_ "Human readable sizes, powers of 1000")
|
||||
complete -c $i -l dereference-command-line-symlink-to-dir #-d (_ "Follow directory symlinks from command line")
|
||||
complete -c $i -l indicator-style -x -a "none classify file-type" -d (_ "Append filetype indicator")
|
||||
complete -c $i -s I -l ignore -r -d (_ "Skip entries matching pattern")
|
||||
complete -c $i -s N -l literal -d (_ "Print raw entry names")
|
||||
complete -c $i -s o -d (_ "Long format without groups")
|
||||
complete -c $i -l show-control-chars -d (_ "Non graphic as-is")
|
||||
complete -c $i -s Q -l quote-name -d (_ "Enclose entry in quotes")
|
||||
complete -c $i -l quoting-style -x -a "literal locale shell shell-always c escape" -d (_ "Select quoting style")
|
||||
complete -c $i -l sort -x -d (_ "Sort criteria") -a "
|
||||
extension\t'Sort by file extension'
|
||||
none\tDon't\ sort
|
||||
size\t'Sort by size'
|
||||
time\t'Sort by modification time'
|
||||
version\t'Sort by version'
|
||||
status\t'Sort by file status modification time'
|
||||
atime\t'Sort by access time'
|
||||
access\t'Sort by access time'
|
||||
use\t'Sort by access time'
|
||||
"
|
||||
complete -c $i -l time -x -d (_ "Show time type") -a "
|
||||
time\t'Sort by modification time'
|
||||
access\t'Sort by access time'
|
||||
use\t'Sort by use time'
|
||||
ctime\t'Sort by file status modification time'
|
||||
status\t'Sort by status time'
|
||||
"
|
||||
complete -c $i -l time-style -x -a "full-iso long-iso iso locale" -d (_ "Select time style")
|
||||
complete -c $i -s T -l tabsize -x -a "1 2 3 4 5 6 7 8 9 10 11 12" -d (_ "Assume tab stops at each COLS")
|
||||
complete -c $i -s U -d (_ "Do not sort")
|
||||
complete -c $i -s v -d (_ "Sort by version")
|
||||
complete -c $i -s w -l width -x -d (_ "Assume screen width")
|
||||
complete -c $i -s X -d (_ "Sort by extension")
|
||||
complete -c $i -l help -d (_ "Display help and exit")
|
||||
complete -c $i -l version -d (_ "Display version and exit")
|
||||
complete $cmds -l author -d (_ "Print author")
|
||||
complete $cmds -l blocksize -x -d (_ "Set block size")
|
||||
complete $cmds -s B -l ignore-backups -d (_ "Ignore files ending with ~")
|
||||
complete $cmds -l color -f -a "never always auto" -d (_ "Use colors")
|
||||
complete $cmds -s D -l dired -d (_ "Generate dired output")
|
||||
complete $cmds -l format -x -a "across commas horizontal long single-column verbose vertical" -d (_ "List format")
|
||||
complete $cmds -l full-time -d (_ "Long format, full-iso time")
|
||||
complete $cmds -s G -l no-group -d (_ "Don't print group information")
|
||||
complete $cmds -l si -d (_ "Human readable sizes, powers of 1000")
|
||||
complete $cmds -l dereference-command-line-symlink-to-dir #-d (_ "Follow directory symlinks from command line")
|
||||
complete $cmds -l indicator-style -x -a "none classify file-type" -d (_ "Append filetype indicator")
|
||||
complete $cmds -s I -l ignore -r -d (_ "Skip entries matching pattern")
|
||||
complete $cmds -s N -l literal -d (_ "Print raw entry names")
|
||||
complete $cmds -s o -d (_ "Long format without groups")
|
||||
complete $cmds -l show-control-chars -d (_ "Non graphic as-is")
|
||||
complete $cmds -s Q -l quote-name -d (_ "Enclose entry in quotes")
|
||||
complete $cmds -l quoting-style -x -a "literal locale shell shell-always c escape" -d (_ "Select quoting style")
|
||||
complete $cmds -l sort -x -d (_ "Sort criteria") -a "
|
||||
extension\t'Sort by file extension'
|
||||
none\tDon't\ sort
|
||||
size\t'Sort by size'
|
||||
time\t'Sort by modification time'
|
||||
version\t'Sort by version'
|
||||
status\t'Sort by file status modification time'
|
||||
atime\t'Sort by access time'
|
||||
access\t'Sort by access time'
|
||||
use\t'Sort by access time'
|
||||
"
|
||||
complete $cmds -l time -x -d (_ "Show time type") -a "
|
||||
time\t'Sort by modification time'
|
||||
access\t'Sort by access time'
|
||||
use\t'Sort by use time'
|
||||
ctime\t'Sort by file status modification time'
|
||||
status\t'Sort by status time'
|
||||
"
|
||||
complete $cmds -l time-style -x -a "full-iso long-iso iso locale" -d (_ "Select time style")
|
||||
complete $cmds -s T -l tabsize -x -a "1 2 3 4 5 6 7 8 9 10 11 12" -d (_ "Assume tab stops at each COLS")
|
||||
complete $cmds -s U -d (_ "Do not sort")
|
||||
complete $cmds -s v -d (_ "Sort by version")
|
||||
complete $cmds -s w -l width -x -d (_ "Assume screen width")
|
||||
complete $cmds -s X -d (_ "Sort by extension")
|
||||
complete $cmds -l help -d (_ "Display help and exit")
|
||||
complete $cmds -l version -d (_ "Display version and exit")
|
||||
|
||||
else
|
||||
else
|
||||
|
||||
# If not a GNU system, assume we have standard BSD ls features instead
|
||||
# If not a GNU system, assume we have standard BSD ls features instead
|
||||
|
||||
complete -c $i -s B -d (_ "Octal escapes for non graphic characters")
|
||||
complete -c $i -s G -d (_ "Use colors")
|
||||
complete -c $i -s I -d (_ "Prevent -A from being automatically set for root")
|
||||
complete -c $i -s P -d (_ "Don't follow symlinks")
|
||||
complete -c $i -s T -d (_ "Show modification time")
|
||||
complete -c $i -s W -d (_ "Show whiteouts when scanning directories")
|
||||
complete -c $i -s Z -d (_ "Display each file's MAC label")
|
||||
complete -c $i -s o -d (_ "Include the file flags in a long (-l) output")
|
||||
complete -c $i -s w -d (_ "Print raw entry names")
|
||||
complete $cmds -s B -d (_ "Octal escapes for non graphic characters")
|
||||
complete $cmds -s G -d (_ "Use colors")
|
||||
complete $cmds -s I -d (_ "Prevent -A from being automatically set for root")
|
||||
complete $cmds -s P -d (_ "Don't follow symlinks")
|
||||
complete $cmds -s T -d (_ "Show modification time")
|
||||
complete $cmds -s W -d (_ "Show whiteouts when scanning directories")
|
||||
complete $cmds -s Z -d (_ "Display each file's MAC label")
|
||||
complete $cmds -s o -d (_ "Include the file flags in a long (-l) output")
|
||||
complete $cmds -s w -d (_ "Print raw entry names")
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -48,7 +48,7 @@ complete -c mplayer -o idx -d (_ "Build index if unavailable")
|
||||
complete -c mplayer -o loadidx -d (_ "Load index from file") -r
|
||||
complete -c mplayer -o ni -d (_ "Force non-interleaved AVI parser")
|
||||
complete -c mplayer -o saveidx -d (_ "Rebuild index and save to file") -r
|
||||
complete -c mplayer -o ss -d (_ "Seek to give time position") -x
|
||||
complete -c mplayer -o ss -d (_ "Seek to given time position") -x
|
||||
complete -c mplayer -o tv -d (_ "TV capture mode")
|
||||
complete -c mplayer -o slang -d (_ "Subtitle language") -x -a $mplayer_lang
|
||||
complete -c mplayer -o sub -d (_ "Subtitle file") -r
|
||||
|
||||
@@ -10,7 +10,7 @@ complete -c pine -s o -d (_ "Open folder read-only")
|
||||
complete -c pine -s p -d (_ "Set configuration file") -r
|
||||
complete -c pine -s P -d (_ "Set global configuration file")
|
||||
complete -c pine -s r -d (_ "Restricted mode")
|
||||
complete -c pine -s z -d (_ "Enable suspention support")
|
||||
complete -c pine -s z -d (_ "Enable suspension support")
|
||||
complete -c pine -o conf -d (_ "Produce a sample global configuration file")
|
||||
complete -c pine -o pinerc -d (_ "Produce sample configuration file") -r
|
||||
complete -c pine -o sort -d (_ "Set mail sort order") -a "
|
||||
|
||||
@@ -124,7 +124,7 @@ complete $rpm_mode -s i -l install -d (_ 'Install new package')
|
||||
complete $rpm_mode -s U -l upgrade -d (_ 'Upgrade existing package')
|
||||
complete $rpm_mode -s F -l freshen -d (_ 'Upgrade package if already installed')
|
||||
complete $rpm_mode -s q -l query -d (_ 'Query installed packages')
|
||||
complete $rpm_mode -s V -l verify -d (_ 'Verify package integrety')
|
||||
complete $rpm_mode -s V -l verify -d (_ 'Verify package integrity')
|
||||
complete $rpm_mode -s e -l erase -d (_ 'Erase package')
|
||||
set -e rpm_mode
|
||||
|
||||
|
||||
@@ -58,20 +58,25 @@ end
|
||||
# Completions
|
||||
#
|
||||
|
||||
complete -c set -s e -l erase -d (_ "Erase variable")
|
||||
complete -c set -s x -l export -d (_ "Export variable to subprocess")
|
||||
complete -c set -s u -l unexport -d (_ "Do not export variable to subprocess")
|
||||
complete -c set -s g -l global -d (_ "Make variable scope global")
|
||||
complete -c set -s l -l local -d (_ "Make variable scope local")
|
||||
complete -c set -s U -l universal -d (_ "Make variable scope universal, i.e. share variable with all the users fish processes on this computer")
|
||||
complete -c set -s q -l query -d (_ "Test if variable is defined")
|
||||
complete -c set -s h -l help -d (_ "Display help and exit")
|
||||
# Regular switches, set only accepts these before the variable name,
|
||||
# so we need to test using __fish_is_first_token
|
||||
|
||||
# Complete using preexisting variables
|
||||
complete -c set -n '__fish_is_first_token' -s e -l erase -d (_ "Erase variable")
|
||||
complete -c set -n '__fish_is_first_token' -s x -l export -d (_ "Export variable to subprocess")
|
||||
complete -c set -n '__fish_is_first_token' -s u -l unexport -d (_ "Do not export variable to subprocess")
|
||||
complete -c set -n '__fish_is_first_token' -s g -l global -d (_ "Make variable scope global")
|
||||
complete -c set -n '__fish_is_first_token' -s l -l local -d (_ "Make variable scope local")
|
||||
complete -c set -n '__fish_is_first_token' -s U -l universal -d (_ "Make variable scope universal, i.e. share variable with all the users fish processes on this computer")
|
||||
complete -c set -n '__fish_is_first_token' -s q -l query -d (_ "Test if variable is defined")
|
||||
complete -c set -n '__fish_is_first_token' -s h -l help -d (_ "Display help and exit")
|
||||
|
||||
# Complete using preexisting variable names
|
||||
complete -c set -n '__fish_is_first_token' -x -a "(set|sed -e 's/ /\tVariable: /')"
|
||||
|
||||
# Color completions
|
||||
complete -c set -n '__fish_set_is_color' -x -a '(set_color --print-colors)' -d (_ Color)
|
||||
complete -c set -n '__fish_set_is_color' -s b -l background -x -a '(set_color --print-colors)' -d (_ "Change background color")
|
||||
complete -c set -n '__fish_set_is_color' -s o -l bold -d (_ 'Make font bold')
|
||||
|
||||
# Locale completions
|
||||
complete -c set -n '__fish_is_first_token' -x -a '$__fish_locale_vars' -d 'Locale variable'
|
||||
|
||||
33
init/completions/sshfs.fish
Normal file
33
init/completions/sshfs.fish
Normal file
@@ -0,0 +1,33 @@
|
||||
#
|
||||
# Completions for sshfs
|
||||
#
|
||||
# Host combinations, borrowed from ssh.fish
|
||||
#
|
||||
complete -x -c sshfs -d Hostname -a "
|
||||
|
||||
(__fish_print_hostnames):
|
||||
|
||||
(
|
||||
#Prepend any username specified in the completion to the hostname
|
||||
echo (commandline -ct)|sed -ne 's/\(.*@\).*/\1/p'
|
||||
)(__fish_print_hostnames):
|
||||
|
||||
(__fish_print_users)@
|
||||
"
|
||||
#
|
||||
# Mount Points, for neatness, I am only mounting under ~/mnt/
|
||||
#
|
||||
complete -c sshfs -d (_ "Mount point") -x -a '(find ~/mnt -type d)'
|
||||
#
|
||||
# Command options
|
||||
#
|
||||
complete -c sshfs -s V -d (_ "Display version and exit")
|
||||
complete -c sshfs -s p -x -d (_ "Port")
|
||||
complete -c sshfs -s C -d (_ "Compression")
|
||||
complete -c sshfs -s o -x -d (_ "Mount options")
|
||||
complete -c sshfs -s d -d (_ "Enable debug")
|
||||
complete -c sshfs -s f -d (_ "Foreground operation")
|
||||
complete -c sshfs -s s -d (_ "Disable multi-threaded operation")
|
||||
complete -c sshfs -s r -d (_ "Mount options")
|
||||
complete -c sshfs -s h -d (_ "Display help and exit")
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
complete -x -c su -a "(__fish_complete_users)"
|
||||
complete -c su -s l -l login -d (_ "Make login shell")
|
||||
complete -r -c su -s c -l command -d (_ "Pass command to shell")
|
||||
complete -r -c su -s c -l command -d (_ "Pass command to shell") -xa "(__fish_complete_command)"
|
||||
complete -c su -s f -l fast -d (_ "Pass -f to the shell")
|
||||
complete -c su -s m -l preserve_environment -d (_ "Preserve environment")
|
||||
complete -c su -s p -d (_ "Preserve environment")
|
||||
|
||||
10
init/completions/sudo.fish
Normal file
10
init/completions/sudo.fish
Normal file
@@ -0,0 +1,10 @@
|
||||
#
|
||||
# Completion for sudo
|
||||
#
|
||||
# Generate a list of commands
|
||||
#
|
||||
|
||||
complete -c sudo -d (_ "Command to run") -x -a "(__fish_complete_commands)"
|
||||
|
||||
complete -c sudo -s h -d (_ "Display help and exit")
|
||||
complete -c sudo -s v -d (_ "Validate")
|
||||
@@ -19,7 +19,7 @@ complete -c tar -l force-local -d (_ "Archive is local")
|
||||
complete -c tar -s F -l info-script -d (_ "Run script at end of tape")
|
||||
complete -c tar -s G -l incremental -d (_ "Use old incremental GNU format")
|
||||
complete -c tar -s g -l listed-incremental -d (_ "Use new incremental GNU format")
|
||||
complete -c tar -s h -l dereference -d (_ "Derefrerence symlinks")
|
||||
complete -c tar -s h -l dereference -d (_ "Dereference symlinks")
|
||||
complete -c tar -s i -l ignore-zeros -d (_ "Ignore zero block in archive")
|
||||
complete -c tar -s j -l bzip -d (_ "Filter through bzip2")
|
||||
complete -c tar -l ignore-failed-read -d (_ "Don't exit on unreadable files")
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
for i in {,e}tex {,e}latex pdf{,e}latex pdf{,e}tex omega
|
||||
complete -c $i -o help -d (_ "Display help and exit")
|
||||
complete -c $i -o version -d (_ "Display version and exit")
|
||||
complete -c $i -x -a "(
|
||||
__fish_complete_suffix (commandline -ct) .tex '(La)TeX file'
|
||||
)"
|
||||
end
|
||||
set -l cmds -c etex -c tex -c elatex -c latex -c pdflatex -c pdfelatex -c pdftex -c pdfetex -c omega
|
||||
complete $cmds -o help -d (_ "Display help and exit")
|
||||
complete $cmds -o version -d (_ "Display version and exit")
|
||||
complete $cmds -x -a "(
|
||||
__fish_complete_suffix (commandline -ct) .tex '(La)TeX file'
|
||||
)"
|
||||
|
||||
|
||||
11
init/completions/time.fish
Normal file
11
init/completions/time.fish
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
complete -c time -a "(__fish_complete_command)" -d (_ "Command")
|
||||
|
||||
complete -c time -s f -l format -d (_ "Specify output format") -x
|
||||
complete -c time -s p -l portable -d (_ "Use the portable output format")
|
||||
complete -c time -s o -l output -d (_ "Do not send the results to stderr, but overwrite the specified file") -r
|
||||
complete -c time -s a -l append -d (_ "(Used together with -o) Do not overwrite but append")
|
||||
complete -c time -s v -l verbose -d (_ "Verbose mode")
|
||||
complete -c time -l help -d (_ "Display help and exit")
|
||||
complete -c time -s V -l version -d (_ "Display version and exit")
|
||||
|
||||
@@ -5,3 +5,8 @@ complete -c type -s f -l no-functions -d (_ "Supress function and builtin lookup
|
||||
complete -c type -s t -l type -d (_ "Print command type")
|
||||
complete -c type -s p -l path -d (_ "Print path to command, or nothing if name is not a command")
|
||||
complete -c type -s P -l force-path -d (_ "Print path to command")
|
||||
|
||||
complete -c type -a "(builtin -n)" -d (_ "Builtin")
|
||||
complete -c type -a "(functions -n)" -d (_ "Function")
|
||||
complete -c type -a "(__fish_complete_command)" -d (_ "Command")
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ complete -c uname -s r -l kernel-release -d (_ "Print kernel release")
|
||||
complete -c uname -s v -l kernel-version -d (_ "Print kernel version")
|
||||
complete -c uname -s m -l machine -d (_ "Print machine name")
|
||||
complete -c uname -s p -l processor -d (_ "Print processor")
|
||||
complete -c uname -s i -l hardware-platform -d (_ "Print harware platform")
|
||||
complete -c uname -s i -l hardware-platform -d (_ "Print hardware platform")
|
||||
complete -c uname -s o -l operating-system -d (_ "Print operating system")
|
||||
complete -c uname -l help -d (_ "Display help and exit")
|
||||
complete -c uname -l verion -d (_ "Display version and exit")
|
||||
|
||||
@@ -82,7 +82,7 @@ complete -c wget -l no-http-keep-alive -d (_ "Turn off keep-alive for http downl
|
||||
complete -c wget -l no-remove-listing -d (_ "Don't remove the temporary .listing files generated")
|
||||
complete -c wget -l no-glob -d (_ "Turn off FTP globbing")
|
||||
complete -c wget -l passive-ftp -d (_ "Use the passive FTP retrieval scheme")
|
||||
complete -c wget -l retr-symlinks -d (_ "Traverse symlinks and retrive pointed-to files")
|
||||
complete -c wget -l retr-symlinks -d (_ "Traverse symlinks and retrieve pointed-to files")
|
||||
|
||||
# Recursive options
|
||||
|
||||
|
||||
22
init/fish.in
22
init/fish.in
@@ -17,6 +17,7 @@ set -g IFS \ \t\n
|
||||
|
||||
set -l path_list /bin /usr/bin /usr/X11R6/bin @PREFIX@/bin
|
||||
|
||||
# Root should also have the sbin directories in the path
|
||||
set -l uid (id -u 2>/dev/null)
|
||||
if test "$uid" = 0
|
||||
set path_list $path_list /sbin /usr/sbin /usr/local/sbin
|
||||
@@ -31,10 +32,9 @@ for i in $path_list
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Set some value for LANG if nothing was set before
|
||||
# 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
|
||||
#
|
||||
|
||||
if status --is-login
|
||||
@@ -71,8 +71,20 @@ for i in DISPLAY
|
||||
end
|
||||
end
|
||||
|
||||
function _ -d "Alias for the gettext command"
|
||||
gettext fish $argv
|
||||
#
|
||||
# Alias for gettext (or a fallback if gettext isn't installed) This
|
||||
# needs to be defined here and not in fish_function.fish, since it is
|
||||
# used by other init files.
|
||||
#
|
||||
|
||||
if test 1 = "@HAVE_GETTEXT@"; and which gettext >/dev/null ^/dev/null
|
||||
function _ -d "Alias for the gettext command"
|
||||
gettext fish $argv
|
||||
end
|
||||
else
|
||||
function _ -d "Alias for the gettext command"
|
||||
printf "%s" $argv
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
@@ -232,6 +232,15 @@ function __fish_print_packages
|
||||
# Remove package version information from output and pipe into cache file
|
||||
rpm -qa >$cache_file |sed -e 's/-[^-]*-[^-]*$//' | sed -e 's/$/\t'$package'/' &
|
||||
end
|
||||
|
||||
# This completes the package name from the portage tree.
|
||||
# True for installing new packages. Function for printing
|
||||
# installed on the system packages is in completions/emerge.fish
|
||||
if which emerge >/dev/null ^/dev/null
|
||||
emerge -s \^(commandline -tc) |grep "^*" |cut -d\ -f3 |cut -d/ -f2
|
||||
return
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ function contains -d "Test if a key is contained in a set of values"
|
||||
return $status
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# help should use 'open' to find a suitable browser, but only
|
||||
# if there is a mime database _and_ DISPLAY is set, since the
|
||||
@@ -81,20 +82,22 @@ end
|
||||
function help -d "Show help for the fish shell"
|
||||
|
||||
# Declare variables to set correct scope
|
||||
|
||||
set fish_browser
|
||||
set fish_browser_bg
|
||||
|
||||
set -l h syntax completion editor job-control todo bugs history killring help
|
||||
set h $h color prompt title variables builtin-overview changes expand
|
||||
set h $h expand-variable expand-home expand-brace expand-wildcard
|
||||
set -l help_topics $h expand-command-substitution expand-process
|
||||
|
||||
#
|
||||
# Find a suitable browser for viewing the help pages. This is needed
|
||||
# by the help function defined below.
|
||||
#
|
||||
|
||||
set graphical_browsers htmlview x-www-browser firefox galeon mozilla konqueror epiphany opera netscape
|
||||
set text_browsers htmlview www-browser links elinks lynx w3m
|
||||
|
||||
if test $BROWSER
|
||||
|
||||
# User has manualy set a preferred browser, so we respect that
|
||||
set fish_browser $BROWSER
|
||||
|
||||
@@ -102,9 +105,7 @@ function help -d "Show help for the fish shell"
|
||||
if contains -- $BROWSER $graphical_browsers
|
||||
set fish_browser_bg 1
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
# Check for a text-based browser.
|
||||
for i in $text_browsers
|
||||
if which $i 2>/dev/null >/dev/null
|
||||
@@ -113,8 +114,8 @@ function help -d "Show help for the fish shell"
|
||||
end
|
||||
end
|
||||
|
||||
# If we are in a graphical environment, we check if there is a
|
||||
# graphical browser to use instead.
|
||||
# If we are in a graphical environment, check if there is a graphical
|
||||
# browser to use instead.
|
||||
if test (echo $DISPLAY) -a \( "$XAUTHORITY" = "$HOME/.Xauthority" -o "$XAUTHORITY" = "" \)
|
||||
for i in $graphical_browsers
|
||||
if which $i 2>/dev/null >/dev/null
|
||||
@@ -132,46 +133,29 @@ function help -d "Show help for the fish shell"
|
||||
return 1
|
||||
end
|
||||
|
||||
if count $argv >/dev/null
|
||||
set fish_help_item $argv[1]
|
||||
end
|
||||
set fish_help_page ""
|
||||
set fish_help_item $argv[1]
|
||||
|
||||
if test "$fish_help_item" = .
|
||||
set fish_help_page "builtins.html\#source"
|
||||
end
|
||||
|
||||
if test "$fish_help_item" = difference
|
||||
set fish_help_page difference.html
|
||||
end
|
||||
|
||||
if test "$fish_help_item" = globbing
|
||||
set fish_help_page "index.html\#expand"
|
||||
end
|
||||
|
||||
if contains -- $fish_help_item (builtin -n)
|
||||
set fish_help_page "builtins.html\#"$fish_help_item
|
||||
end
|
||||
|
||||
if contains -- $fish_help_item count dirh dirs help mimedb nextd open popd prevd pushd set_color tokenize psub umask type
|
||||
set fish_help_page "commands.html\#"$fish_help_item
|
||||
end
|
||||
|
||||
set idx_subj syntax completion editor job-control todo bugs history
|
||||
set idx_subj $idx_subj killring help color prompt title variables
|
||||
set idx_subj $idx_subj builtin-overview changes
|
||||
set idx_subj $idx_subj expand expand-variable expand-home expand-brace expand-wildcard expand-command-substitution expand-process
|
||||
|
||||
if contains -- $fish_help_item $idx_subj
|
||||
set fish_help_page "index.html\#"$fish_help_item
|
||||
end
|
||||
|
||||
if not test $fish_help_page
|
||||
if which $fish_help_item >/dev/null ^/dev/null
|
||||
man $fish_help_item
|
||||
return
|
||||
end
|
||||
set fish_help_page "index.html"
|
||||
switch "$fish_help_item"
|
||||
case ""
|
||||
set fish_help_page index.html
|
||||
case "."
|
||||
set fish_help_page "builtins.html\#source"
|
||||
case difference
|
||||
set fish_help_page difference.html
|
||||
case globbing
|
||||
set fish_help_page "index.html\#expand"
|
||||
case (builtin -n)
|
||||
set fish_help_page "builtins.html\#"$fish_help_item
|
||||
case count dirh dirs help mimedb nextd open popd prevd pushd set_color tokenize psub umask type
|
||||
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
|
||||
man $fish_help_item
|
||||
return
|
||||
end
|
||||
set fish_help_page "index.html"
|
||||
end
|
||||
|
||||
if test $fish_browser_bg
|
||||
@@ -179,16 +163,24 @@ function help -d "Show help for the fish shell"
|
||||
else
|
||||
eval $fish_browser file://$__fish_help_dir/$fish_help_page
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
#
|
||||
# Make ls use colors if we are on a system that supports this
|
||||
#
|
||||
if ls --help 1>/dev/null 2>/dev/null
|
||||
|
||||
if ls --version 1>/dev/null 2>/dev/null
|
||||
# This is GNU ls
|
||||
function ls -d "List contents of directory"
|
||||
command ls --color=auto --indicator-style=classify $argv
|
||||
end
|
||||
else
|
||||
# BSD, OS X and a few more support colors through the -G switch instead
|
||||
if ls / -G 1>/dev/null 2>/dev/null
|
||||
function ls -d "List contents of directory"
|
||||
command ls -G $argv
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
@@ -218,10 +210,11 @@ end
|
||||
|
||||
function prompt_pwd -d "Print the current working directory, shortend to fit the prompt"
|
||||
set -l wd (pwd)
|
||||
printf "%s" $wd|sed -e 's-/\([^/]\)\([^/]*\)-/\1-g'
|
||||
set -l res (echo $wd|sed -e 's-/\([^/]\)\([^/]*\)-/\1-g')
|
||||
if test $wd != '~'
|
||||
printf "%s\n" $wd|sed -e 's-.*/[^/]\([^/]*$\)-\1-'
|
||||
set res $res(echo $wd|sed -e 's-.*/[^/]\([^/]*$\)-\1-')
|
||||
end
|
||||
echo $res
|
||||
end
|
||||
|
||||
#
|
||||
@@ -707,16 +700,18 @@ end
|
||||
|
||||
function type -d "Print the type of a command"
|
||||
|
||||
# Initialize
|
||||
set status 1
|
||||
set mode normal
|
||||
set selection all
|
||||
|
||||
|
||||
# Get options
|
||||
#
|
||||
set -- shortopt -o tpPafh
|
||||
if getopt -T >/dev/null
|
||||
set longopt
|
||||
else
|
||||
set longopt -- -l type,path,force-path,all,no-functions,help
|
||||
set -- longopt -l type,path,force-path,all,no-functions,help
|
||||
end
|
||||
|
||||
if not getopt -n type -Q $shortopt $longopt -- $argv
|
||||
@@ -725,7 +720,7 @@ function type -d "Print the type of a command"
|
||||
|
||||
set -- tmp (getopt $shortopt $longopt -- $argv)
|
||||
|
||||
eval set opt -- $tmp
|
||||
eval set -- opt $tmp
|
||||
|
||||
for i in $opt
|
||||
switch $i
|
||||
@@ -755,6 +750,7 @@ function type -d "Print the type of a command"
|
||||
end
|
||||
end
|
||||
|
||||
# Check all possible types for the remaining arguments
|
||||
for i in $argv
|
||||
|
||||
switch $i
|
||||
@@ -776,7 +772,7 @@ function type -d "Print the type of a command"
|
||||
functions $i
|
||||
|
||||
case type
|
||||
printf (_ function)
|
||||
printf (_ 'function\n')
|
||||
|
||||
case path
|
||||
echo
|
||||
@@ -815,7 +811,7 @@ function type -d "Print the type of a command"
|
||||
printf (_ '%s is %s\n') $i (which $i)
|
||||
|
||||
case type
|
||||
printf (_ file)
|
||||
printf (_ 'file\n')
|
||||
|
||||
case path
|
||||
which $i
|
||||
@@ -947,15 +943,15 @@ function __fish_umask_print_symbolic
|
||||
set val (echo $umask|cut -c $i)
|
||||
|
||||
if contains $val 0 1 2 3
|
||||
set res {$res}r
|
||||
set res {$res}r
|
||||
end
|
||||
|
||||
if contains $val 0 1 4 5
|
||||
set res {$res}w
|
||||
set res {$res}w
|
||||
end
|
||||
|
||||
if contains $val 0 2 4 6
|
||||
set res {$res}x
|
||||
set res {$res}x
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -40,7 +40,7 @@ end
|
||||
# @SYSCONFDIR@/fish_inputrc.
|
||||
#
|
||||
|
||||
for i in ~/.fish_inputrc @SYSCONFDIR@/fish_inputrc ~/etc/fish_inputrc /etc/fish_inputrc ~/.inputrc /etc/inputrc
|
||||
for i in ~/.fish_inputrc @SYSCONFDIR@/fish_inputrc ~/.inputrc /etc/inputrc
|
||||
if test -f $i
|
||||
set -xg INPUTRC $i
|
||||
break
|
||||
@@ -119,5 +119,9 @@ if command ls --color=auto --help 1>/dev/null 2>/dev/null
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Remove temporary functions
|
||||
#
|
||||
|
||||
functions -e set_default_color
|
||||
functions -e set_exported_default
|
||||
|
||||
38
input.c
38
input.c
@@ -32,7 +32,12 @@ implementation in fish is as of yet incomplete.
|
||||
#include <termio.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_TERM_H
|
||||
#include <term.h>
|
||||
#elif HAVE_NCURSES_TERM_H
|
||||
#include <ncurses/term.h>
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
#include <dirent.h>
|
||||
#include <wctype.h>
|
||||
@@ -191,7 +196,18 @@ const wchar_t code_arr[] =
|
||||
*/
|
||||
static hash_table_t all_mappings;
|
||||
|
||||
static array_list_t *current_mode_mappings, *current_application_mappings, *global_mappings;
|
||||
/**
|
||||
Mappings for the current input mode
|
||||
*/
|
||||
static array_list_t *current_mode_mappings;
|
||||
/**
|
||||
Mappings for the current application
|
||||
*/
|
||||
static array_list_t *current_application_mappings;
|
||||
/**
|
||||
Global mappings
|
||||
*/
|
||||
static array_list_t *global_mappings;
|
||||
|
||||
/**
|
||||
Number of nested conditional statement levels that are not evaluated
|
||||
@@ -1292,12 +1308,32 @@ static int interrupt_handler()
|
||||
Fire any pending events
|
||||
*/
|
||||
event_fire( 0 );
|
||||
|
||||
/*
|
||||
Reap stray processes, including printing exit status messages
|
||||
*/
|
||||
if( job_reap( 1 ) )
|
||||
repaint();
|
||||
|
||||
/*
|
||||
Check if we should exit
|
||||
*/
|
||||
if( exit_status() )
|
||||
{
|
||||
return R_EXIT;
|
||||
}
|
||||
|
||||
/*
|
||||
Tell the reader an event occured
|
||||
*/
|
||||
if( reader_interupted() )
|
||||
{
|
||||
/*
|
||||
Return 3, i.e. the character read by a Control-C.
|
||||
*/
|
||||
return 3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
6
input.h
6
input.h
@@ -77,8 +77,8 @@ wint_t input_readch();
|
||||
/**
|
||||
Push a character or a readline function onto the stack of unread
|
||||
characters that input_readch will return before actually reading from fd
|
||||
0.
|
||||
*/
|
||||
0.
|
||||
*/
|
||||
void input_unreadch( wint_t ch );
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ void input_unreadch( wint_t ch );
|
||||
\param mode the name of the mapping mode to add this mapping to
|
||||
\param s the sequence
|
||||
\param d a description of the sequence
|
||||
\param c am input function that will be run whenever the key sequence occurs
|
||||
\param cmd an input function that will be run whenever the key sequence occurs
|
||||
*/
|
||||
void add_mapping( const wchar_t *mode, const wchar_t *s, const wchar_t * d, const wchar_t *cmd );
|
||||
|
||||
|
||||
@@ -9,9 +9,12 @@ Implementation file for the low level input library
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <wchar.h>
|
||||
|
||||
|
||||
#include "util.h"
|
||||
#include "common.h"
|
||||
#include "wutil.h"
|
||||
|
||||
@@ -8,7 +8,7 @@ Header file for the low level input library
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
/*
|
||||
/**
|
||||
Use unencoded private-use keycodes for internal characters
|
||||
*/
|
||||
#define INPUT_COMMON_RESERVED 0xe000
|
||||
@@ -24,8 +24,14 @@ enum
|
||||
}
|
||||
;
|
||||
|
||||
/**
|
||||
Init the library
|
||||
*/
|
||||
void input_common_init( int (*ih)() );
|
||||
|
||||
/**
|
||||
Free memory used by the library
|
||||
*/
|
||||
void input_common_destroy();
|
||||
|
||||
/**
|
||||
@@ -39,6 +45,11 @@ void input_common_destroy();
|
||||
*/
|
||||
wchar_t input_common_readch( int timed );
|
||||
|
||||
/**
|
||||
Push a character or a readline function onto the stack of unread
|
||||
characters that input_readch will return before actually reading from fd
|
||||
0.
|
||||
*/
|
||||
void input_common_unreadch( wint_t ch );
|
||||
|
||||
#endif
|
||||
|
||||
12
intern.c
12
intern.c
@@ -11,11 +11,19 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "wutil.h"
|
||||
#include "common.h"
|
||||
#include "intern.h"
|
||||
|
||||
hash_table_t *intern_table=0;
|
||||
hash_table_t *intern_static_table=0;
|
||||
/**
|
||||
Table of interned strings
|
||||
*/
|
||||
static hash_table_t *intern_table=0;
|
||||
|
||||
/**
|
||||
Table of static interned strings
|
||||
*/
|
||||
static hash_table_t *intern_static_table=0;
|
||||
|
||||
/**
|
||||
Load static strings that are universally common. Currently only loads the empty string.
|
||||
|
||||
4
io.c
4
io.c
@@ -25,7 +25,11 @@ Utilities for io redirection.
|
||||
#include <termio.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_TERM_H
|
||||
#include <term.h>
|
||||
#elif HAVE_NCURSES_TERM_H
|
||||
#include <ncurses/term.h>
|
||||
#endif
|
||||
|
||||
#include "util.h"
|
||||
#include "wutil.h"
|
||||
|
||||
14
main.c
14
main.c
@@ -184,7 +184,7 @@ int main( int argc, char **argv )
|
||||
|
||||
case 'v':
|
||||
fwprintf( stderr,
|
||||
L"%s, version %s\n",
|
||||
_(L"%s, version %s\n"),
|
||||
PACKAGE_NAME,
|
||||
PACKAGE_VERSION );
|
||||
exit( 0 );
|
||||
@@ -222,8 +222,6 @@ int main( int argc, char **argv )
|
||||
complete_init();
|
||||
reader_init();
|
||||
|
||||
reader_push_current_filename( L"(internal)" );
|
||||
|
||||
if( read_init() )
|
||||
{
|
||||
if( cmd != 0 )
|
||||
@@ -237,9 +235,7 @@ int main( int argc, char **argv )
|
||||
{
|
||||
if( my_optind == argc )
|
||||
{
|
||||
reader_push_current_filename( L"(stdin)" );
|
||||
res = reader_read( 0 );
|
||||
reader_pop_current_filename();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -278,8 +274,8 @@ int main( int argc, char **argv )
|
||||
if( res )
|
||||
{
|
||||
debug( 1,
|
||||
L"Error while reading file %ls\n",
|
||||
reader_current_filename() );
|
||||
_(L"Error while reading file %ls\n"),
|
||||
reader_current_filename()?reader_current_filename(): _(L"Standard input") );
|
||||
}
|
||||
free(reader_pop_current_filename());
|
||||
}
|
||||
@@ -287,9 +283,7 @@ int main( int argc, char **argv )
|
||||
}
|
||||
|
||||
proc_fire_event( L"PROCESS_EXIT", EVENT_EXIT, getpid(), res );
|
||||
|
||||
reader_pop_current_filename();
|
||||
|
||||
|
||||
proc_destroy();
|
||||
env_destroy();
|
||||
builtin_destroy();
|
||||
|
||||
201
mimedb.c
201
mimedb.c
@@ -30,11 +30,18 @@ license. Read the source code of the library for more information.
|
||||
#include <fcntl.h>
|
||||
#include <libgen.h>
|
||||
#include <errno.h>
|
||||
#include <regex.h>
|
||||
#include <locale.h>
|
||||
|
||||
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_LIBINTL_H
|
||||
#include <libintl.h>
|
||||
#endif
|
||||
|
||||
#include "xdgmime.h"
|
||||
#include "util.h"
|
||||
|
||||
@@ -53,20 +60,30 @@ license. Read the source code of the library for more information.
|
||||
#define MIME_SUFFIX ".xml"
|
||||
|
||||
/**
|
||||
Start tag for comment
|
||||
Start tag for langauge-specific comment
|
||||
*/
|
||||
#define START_TAG "<comment>"
|
||||
#define START_TAG "<comment *(| +xml:lang *= *(\"%s\"|'%s') *)>"
|
||||
|
||||
/**
|
||||
End tab for comment
|
||||
*/
|
||||
#define STOP_TAG "</comment>"
|
||||
#define STOP_TAG "</comment *>"
|
||||
|
||||
/**
|
||||
File contains cached list of mime actions
|
||||
*/
|
||||
#define DESKTOP_DEFAULT "applications/defaults.list"
|
||||
|
||||
/**
|
||||
Size for temporary string buffer used to make a regex for language
|
||||
specific descriptions
|
||||
*/
|
||||
#define BUFF_SIZE 1024
|
||||
|
||||
/**
|
||||
Program name
|
||||
*/
|
||||
#define MIMEDB "mimedb"
|
||||
|
||||
/**
|
||||
All types of input and output possible
|
||||
@@ -82,6 +99,15 @@ enum
|
||||
}
|
||||
;
|
||||
|
||||
/**
|
||||
Regular expression variable used to find start tag of description
|
||||
*/
|
||||
static regex_t *start_re=0;
|
||||
/**
|
||||
Regular expression variable used to find end tag of description
|
||||
*/
|
||||
static regex_t *stop_re=0;
|
||||
|
||||
/**
|
||||
Error flag. Non-zero if something bad happened.
|
||||
*/
|
||||
@@ -101,6 +127,15 @@ static int launch_len=0;
|
||||
*/
|
||||
static int launch_pos=0;
|
||||
|
||||
#if HAVE_GETTEXT
|
||||
/**
|
||||
gettext alias
|
||||
*/
|
||||
#define _(string) gettext(string)
|
||||
#else
|
||||
#define _(string) (string)
|
||||
#endif
|
||||
|
||||
/**
|
||||
Dynamically generated function, made from the documentation in doc_src.
|
||||
*/
|
||||
@@ -115,7 +150,7 @@ void *my_malloc( size_t s )
|
||||
if( !s )
|
||||
{
|
||||
error=1;
|
||||
fprintf( stderr, "mimedb: Out of memory\n" );
|
||||
fprintf( stderr, _("%s: Out of memory\n"), MIMEDB );
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -129,7 +164,7 @@ char *my_strdup( char *s )
|
||||
if( !s )
|
||||
{
|
||||
error=1;
|
||||
fprintf( stderr, "mimedb: Out of memory\n" );
|
||||
fprintf( stderr, _("%s: Out of memory\n"), MIMEDB );
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -364,11 +399,56 @@ static char *munge( char *in )
|
||||
}
|
||||
in++;
|
||||
}
|
||||
fprintf( stderr, "mimedb: Unknown error in munge()\n" );
|
||||
fprintf( stderr, _( "%s: Unknown error in munge()\n"), MIMEDB );
|
||||
error=1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Return a regular expression that matches all strings specifying the current locale
|
||||
*/
|
||||
static char *get_lang_re()
|
||||
{
|
||||
|
||||
static char buff[BUFF_SIZE];
|
||||
const char *lang = setlocale( LC_MESSAGES, 0 );
|
||||
int close=0;
|
||||
char *out=buff;
|
||||
|
||||
if( (1+strlen(lang)*4) >= BUFF_SIZE )
|
||||
{
|
||||
fprintf( stderr, _( "%s: Locale string too long\n"), MIMEDB );
|
||||
error = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for( ; *lang; lang++ )
|
||||
{
|
||||
switch( *lang )
|
||||
{
|
||||
case '@':
|
||||
case '.':
|
||||
case '_':
|
||||
if( close )
|
||||
*out++ = ')';
|
||||
|
||||
close=1;
|
||||
*out++ = '(';
|
||||
*out++ = '|';
|
||||
*out++ = *lang;
|
||||
break;
|
||||
|
||||
default:
|
||||
*out++ = *lang;
|
||||
}
|
||||
}
|
||||
|
||||
if( close )
|
||||
*out++ = ')';
|
||||
*out++=0;
|
||||
return buff;
|
||||
}
|
||||
|
||||
/**
|
||||
Get description for a specified mimetype.
|
||||
*/
|
||||
@@ -380,8 +460,36 @@ static char *get_description( const char *mimetype )
|
||||
int fd;
|
||||
struct stat st;
|
||||
char *contents;
|
||||
char *start, *stop;
|
||||
char *start=0, *stop=0;
|
||||
|
||||
if( !start_re )
|
||||
{
|
||||
char *lang;
|
||||
char buff[BUFF_SIZE];
|
||||
|
||||
lang = get_lang_re();
|
||||
if( !lang )
|
||||
return 0;
|
||||
|
||||
snprintf( buff, BUFF_SIZE, START_TAG, lang, lang );
|
||||
|
||||
start_re = my_malloc( sizeof(regex_t));
|
||||
stop_re = my_malloc( sizeof(regex_t));
|
||||
|
||||
if( regcomp( start_re, buff, REG_EXTENDED ) ||
|
||||
regcomp( stop_re, STOP_TAG, REG_EXTENDED ) )
|
||||
{
|
||||
fprintf( stderr, _( "%s: Could not compile regular expressions\n"), MIMEDB );
|
||||
error=1;
|
||||
|
||||
free( start_re );
|
||||
free( stop_re );
|
||||
start_re = stop_re = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
fn_part = my_malloc( strlen(MIME_DIR) + strlen( mimetype) + strlen(MIME_SUFFIX) + 1 );
|
||||
|
||||
if( !fn_part )
|
||||
@@ -436,15 +544,40 @@ static char *get_description( const char *mimetype )
|
||||
free( fn );
|
||||
|
||||
contents[st.st_size]=0;
|
||||
|
||||
start = strstr( contents, START_TAG );
|
||||
if( start )
|
||||
regmatch_t match[1];
|
||||
int w = -1;
|
||||
|
||||
start=contents;
|
||||
|
||||
/*
|
||||
On multiple matches, use the longest match, should be a pretty
|
||||
good heuristic for best match...
|
||||
*/
|
||||
while( !regexec(start_re, start, 1, match, 0) )
|
||||
{
|
||||
start += strlen(START_TAG);
|
||||
stop = strstr( start, STOP_TAG );
|
||||
if( stop )
|
||||
int new_w = match[0].rm_eo - match[0].rm_so;
|
||||
|
||||
if( new_w > w )
|
||||
{
|
||||
/*
|
||||
New match is for a longer match then the previous
|
||||
match, so we use the new match
|
||||
*/
|
||||
w=new_w;
|
||||
start += match[0].rm_eo;
|
||||
}
|
||||
}
|
||||
|
||||
if( w != -1 )
|
||||
{
|
||||
if( !regexec(stop_re, start, 1, match, 0) )
|
||||
{
|
||||
/*
|
||||
We've found the beginning and the end of a suitable description
|
||||
*/
|
||||
char *res;
|
||||
|
||||
stop = start + match[0].rm_so;
|
||||
*stop = '\0';
|
||||
res = munge( start );
|
||||
free( contents );
|
||||
@@ -452,7 +585,7 @@ static char *get_description( const char *mimetype )
|
||||
}
|
||||
}
|
||||
free( contents );
|
||||
fprintf( stderr, "mimedb: No description for type %s\n", mimetype );
|
||||
fprintf( stderr, _( "%s: No description for type %s\n"), MIMEDB, mimetype );
|
||||
error=1;
|
||||
return 0;
|
||||
|
||||
@@ -516,7 +649,7 @@ static char *get_action( const char *mimetype )
|
||||
|
||||
if( !launcher )
|
||||
{
|
||||
fprintf( stderr, "Could not parse launcher string %s\n", launcher_str );
|
||||
fprintf( stderr, _("%s: Could not parse launcher string '%s'\n"), MIMEDB, launcher_str );
|
||||
error=1;
|
||||
return 0;
|
||||
}
|
||||
@@ -549,7 +682,7 @@ static char *get_action( const char *mimetype )
|
||||
if( !launcher_command_str )
|
||||
{
|
||||
fprintf( stderr,
|
||||
"mimedb: Default launcher %s does not specify how to start\n",
|
||||
_( "%s: Default launcher '%s' does not specify how to start\n"), MIMEDB,
|
||||
launcher_filename );
|
||||
free( launcher_filename );
|
||||
return 0;
|
||||
@@ -929,7 +1062,7 @@ static void launch( char *filter, array_list_t *files, int fileno )
|
||||
}
|
||||
|
||||
default:
|
||||
fprintf( stderr, "Unsupported switch %c in launch string %s\n", *filter, filter_org );
|
||||
fprintf( stderr, _("%s: Unsupported switch '%c' in launch string '%s'\n"), MIMEDB, *filter, filter_org );
|
||||
launch_len=0;
|
||||
break;
|
||||
|
||||
@@ -950,7 +1083,7 @@ static void launch( char *filter, array_list_t *files, int fileno )
|
||||
case -1:
|
||||
{
|
||||
launch_len = 0;
|
||||
fprintf( stderr, "mimedb: Out of memory\n" );
|
||||
fprintf( stderr, _( "%s: Out of memory\n"), MIMEDB );
|
||||
return;
|
||||
}
|
||||
case 0:
|
||||
@@ -995,6 +1128,17 @@ static void clear_entry( const void *key, const void *val )
|
||||
free( l );
|
||||
}
|
||||
|
||||
/**
|
||||
Do locale specific init
|
||||
*/
|
||||
static void locale_init()
|
||||
{
|
||||
setlocale( LC_ALL, "" );
|
||||
#if HAVE_GETTEXT
|
||||
bindtextdomain( PACKAGE_NAME, LOCALEDIR );
|
||||
textdomain( PACKAGE_NAME );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -1011,8 +1155,9 @@ int main (int argc, char *argv[])
|
||||
int i;
|
||||
|
||||
hash_table_t launch_hash;
|
||||
|
||||
|
||||
locale_init();
|
||||
|
||||
/*
|
||||
Parse options
|
||||
*/
|
||||
@@ -1118,7 +1263,7 @@ int main (int argc, char *argv[])
|
||||
exit(0);
|
||||
|
||||
case 'v':
|
||||
printf( "mimedb, version %s\n", PACKAGE_VERSION );
|
||||
printf( _("%s, version %s\n"), MIMEDB, PACKAGE_VERSION );
|
||||
exit( 0 );
|
||||
|
||||
case '?':
|
||||
@@ -1129,7 +1274,7 @@ int main (int argc, char *argv[])
|
||||
|
||||
if( ( output_type == LAUNCH )&&(input_type==MIMETYPE))
|
||||
{
|
||||
fprintf( stderr, "Can not launch a mimetype\n" );
|
||||
fprintf( stderr, _("%s: Can not launch a mimetype\n"), MIMEDB );
|
||||
print_help();
|
||||
exit(1);
|
||||
}
|
||||
@@ -1161,7 +1306,7 @@ int main (int argc, char *argv[])
|
||||
mimetype = xdg_mime_unalias_mime_type (mimetype);
|
||||
if( !mimetype )
|
||||
{
|
||||
fprintf( stderr, "mimedb: Could not parse mimetype from argument %s\n", argv[i] );
|
||||
fprintf( stderr, _( "%s: Could not parse mimetype from argument '%s'\n"), MIMEDB, argv[i] );
|
||||
error=1;
|
||||
return 1;
|
||||
}
|
||||
@@ -1227,7 +1372,7 @@ int main (int argc, char *argv[])
|
||||
/*
|
||||
Perform the actual launching
|
||||
*/
|
||||
if( output_type == LAUNCH )
|
||||
if( output_type == LAUNCH && !error )
|
||||
{
|
||||
int i;
|
||||
array_list_t mimes;
|
||||
@@ -1239,7 +1384,7 @@ int main (int argc, char *argv[])
|
||||
array_list_t *files = (array_list_t *)hash_get( &launch_hash, mimetype );
|
||||
if( !files )
|
||||
{
|
||||
fprintf( stderr, "mimedb: Unknown error\n" );
|
||||
fprintf( stderr, _( "%s: Unknown error\n"), MIMEDB );
|
||||
error=1;
|
||||
break;
|
||||
}
|
||||
@@ -1260,6 +1405,14 @@ int main (int argc, char *argv[])
|
||||
if( launch_buff )
|
||||
free( launch_buff );
|
||||
|
||||
if( start_re )
|
||||
{
|
||||
regfree( start_re );
|
||||
regfree( stop_re );
|
||||
free( start_re );
|
||||
free( stop_re );
|
||||
}
|
||||
|
||||
xdg_mime_shutdown();
|
||||
|
||||
return error;
|
||||
|
||||
5
output.c
5
output.c
@@ -26,7 +26,12 @@
|
||||
#include <termio.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_TERM_H
|
||||
#include <term.h>
|
||||
#elif HAVE_NCURSES_TERM_H
|
||||
#include <ncurses/term.h>
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
|
||||
243
parser.c
243
parser.c
@@ -311,8 +311,10 @@ typedef struct
|
||||
wchar_t *cmd;
|
||||
} profile_element_t;
|
||||
|
||||
|
||||
int block_count( block_t *b )
|
||||
/**
|
||||
Return the current number of block nestings
|
||||
*/
|
||||
static int block_count( block_t *b )
|
||||
{
|
||||
|
||||
if( b==0)
|
||||
@@ -396,6 +398,16 @@ void parser_pop_block()
|
||||
break;
|
||||
}
|
||||
|
||||
case FUNCTION_CALL:
|
||||
{
|
||||
free( current_block->param1.function_name );
|
||||
free( current_block->param4.function_filename );
|
||||
al_foreach( ¤t_block->param2.function_vars,
|
||||
(void (*)(const void *))&free );
|
||||
al_destroy( ¤t_block->param2.function_vars );
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for( eb=current_block->first_event_block; eb; eb=eb_next )
|
||||
@@ -449,8 +461,12 @@ const wchar_t *parser_get_block_desc( int block )
|
||||
|
||||
}
|
||||
|
||||
|
||||
int parser_skip_arguments( const wchar_t *cmd )
|
||||
/**
|
||||
Check if the specified bcommand is one of the builtins that cannot
|
||||
have arguments, any followin argument is interpreted as a new
|
||||
command
|
||||
*/
|
||||
static int parser_skip_arguments( const wchar_t *cmd )
|
||||
{
|
||||
|
||||
return contains_str( cmd,
|
||||
@@ -459,7 +475,6 @@ int parser_skip_arguments( const wchar_t *cmd )
|
||||
(void *)0 );
|
||||
}
|
||||
|
||||
|
||||
int parser_is_subcommand( const wchar_t *cmd )
|
||||
{
|
||||
|
||||
@@ -506,7 +521,10 @@ int parser_is_reserved( wchar_t *word)
|
||||
(void *)0 );
|
||||
}
|
||||
|
||||
int parser_is_pipe_forbidden( wchar_t *word )
|
||||
/**
|
||||
Returns 1 if the specified command is a builtin that may not be used in a pipeline
|
||||
*/
|
||||
static int parser_is_pipe_forbidden( wchar_t *word )
|
||||
{
|
||||
return contains_str( word,
|
||||
L"exec",
|
||||
@@ -817,9 +835,12 @@ void parser_init()
|
||||
al_init( &forbidden_function );
|
||||
}
|
||||
|
||||
void print_profile( array_list_t *p,
|
||||
int pos,
|
||||
FILE *out )
|
||||
/**
|
||||
Print profiling information to the specified stream
|
||||
*/
|
||||
static void print_profile( array_list_t *p,
|
||||
int pos,
|
||||
FILE *out )
|
||||
{
|
||||
profile_element_t *me, *prev;
|
||||
int i;
|
||||
@@ -888,6 +909,14 @@ void parser_destroy()
|
||||
}
|
||||
|
||||
al_destroy( &forbidden_function );
|
||||
|
||||
if( lineinfo )
|
||||
{
|
||||
sb_destroy( lineinfo );
|
||||
free(lineinfo );
|
||||
lineinfo = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -984,17 +1013,140 @@ int eval_args( const wchar_t *line, array_list_t *args )
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void parser_stack_trace( block_t *b, string_buffer_t *buff)
|
||||
{
|
||||
if( !b )
|
||||
return;
|
||||
|
||||
if( b->type == FUNCTION_CALL )
|
||||
{
|
||||
int i;
|
||||
|
||||
sb_printf( buff, _(L"in function '%ls',\n"), b->param1.function_name );
|
||||
|
||||
const wchar_t *file = b->param4.function_filename;
|
||||
|
||||
if( file )
|
||||
sb_printf( buff,
|
||||
_(L"\tcalled on line %d of file '%ls',\n"),
|
||||
b->param3.function_lineno,
|
||||
file );
|
||||
else
|
||||
sb_printf( buff,
|
||||
_(L"\tcalled on standard input,\n") );
|
||||
|
||||
if( al_get_count( &b->param2.function_vars ) )
|
||||
{
|
||||
string_buffer_t tmp;
|
||||
sb_init( &tmp );
|
||||
|
||||
for( i=0; i<al_get_count( &b->param2.function_vars ); i++ )
|
||||
{
|
||||
sb_append2( &tmp, i?L" ":L"", (wchar_t *)al_get( &b->param2.function_vars, i ), (void *)0 );
|
||||
}
|
||||
sb_printf( buff, _(L"\twith parameter list '%ls'\n"), (wchar_t *)tmp.buff );
|
||||
|
||||
sb_destroy( &tmp );
|
||||
}
|
||||
sb_printf( buff,
|
||||
L"\n" );
|
||||
}
|
||||
parser_stack_trace( b->outer, buff );
|
||||
}
|
||||
|
||||
static const wchar_t *is_function()
|
||||
{
|
||||
block_t *b = current_block;
|
||||
while( 1 )
|
||||
{
|
||||
if( !b )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if( b->type == FUNCTION_CALL )
|
||||
{
|
||||
return b->param1.function_name;
|
||||
}
|
||||
b=b->outer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int parser_get_lineno()
|
||||
{
|
||||
int i;
|
||||
const wchar_t *whole_str = tok_string( current_tokenizer );
|
||||
const wchar_t *function_name;
|
||||
|
||||
int lineno = 1;
|
||||
|
||||
for( i=0; i<current_tokenizer_pos; i++ )
|
||||
{
|
||||
if( whole_str[i] == L'\n' )
|
||||
{
|
||||
lineno++;
|
||||
}
|
||||
}
|
||||
|
||||
if( (function_name = is_function()) )
|
||||
{
|
||||
lineno += function_get_definition_offset( function_name );
|
||||
}
|
||||
|
||||
return lineno;
|
||||
}
|
||||
|
||||
const wchar_t *parser_current_filename()
|
||||
{
|
||||
block_t *b = current_block;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
if( !b )
|
||||
{
|
||||
return reader_current_filename();
|
||||
}
|
||||
if( b->type == FUNCTION_CALL )
|
||||
{
|
||||
return function_get_definition_file(b->param1.function_name );
|
||||
}
|
||||
b=b->outer;
|
||||
}
|
||||
}
|
||||
|
||||
static int printed_width( const wchar_t *str, int len )
|
||||
{
|
||||
int res=0;
|
||||
int i;
|
||||
for( i=0; i<len; i++ )
|
||||
{
|
||||
if( str[i] == L'\t' )
|
||||
{
|
||||
res=(res+8)&~7;
|
||||
}
|
||||
else
|
||||
{
|
||||
res += wcwidth( str[i] );
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
wchar_t *parser_current_line()
|
||||
{
|
||||
int lineno=1;
|
||||
|
||||
wchar_t *file = reader_current_filename();
|
||||
const wchar_t *file = parser_current_filename();
|
||||
wchar_t *whole_str = tok_string( current_tokenizer );
|
||||
wchar_t *line = whole_str;
|
||||
wchar_t *line_end;
|
||||
int i;
|
||||
int offset;
|
||||
int current_line_pos=current_tokenizer_pos;
|
||||
int current_line_width;
|
||||
const wchar_t *function_name=0;
|
||||
int current_line_start=0;
|
||||
|
||||
|
||||
if( !line )
|
||||
return L"";
|
||||
@@ -1004,7 +1156,7 @@ wchar_t *parser_current_line()
|
||||
lineinfo = malloc( sizeof(string_buffer_t) );
|
||||
sb_init( lineinfo );
|
||||
}
|
||||
sb_clear( lineinfo );
|
||||
sb_clear( lineinfo );
|
||||
|
||||
/*
|
||||
Calculate line number, line offset, etc.
|
||||
@@ -1014,11 +1166,18 @@ wchar_t *parser_current_line()
|
||||
if( whole_str[i] == L'\n' )
|
||||
{
|
||||
lineno++;
|
||||
current_line_pos = current_tokenizer_pos-i-1;
|
||||
current_line_start=i+1;
|
||||
line = &whole_str[i+1];
|
||||
}
|
||||
}
|
||||
|
||||
current_line_width=printed_width(whole_str+current_line_start, current_tokenizer_pos-current_line_start );
|
||||
|
||||
if( (function_name = is_function()) )
|
||||
{
|
||||
lineno += function_get_definition_offset( function_name );
|
||||
}
|
||||
|
||||
/*
|
||||
Copy current line from whole string
|
||||
*/
|
||||
@@ -1028,34 +1187,55 @@ wchar_t *parser_current_line()
|
||||
|
||||
line = wcsndup( line, line_end-line );
|
||||
|
||||
debug( 4, L"Current pos %d, line pos %d, file_length %d, is_interactive %d\n", current_tokenizer_pos, current_line_pos, wcslen(whole_str), is_interactive);
|
||||
|
||||
if( !is_interactive )
|
||||
/**
|
||||
If we are not going to print a stack trace, at least print the line number and filename
|
||||
*/
|
||||
if( !is_interactive || is_function() )
|
||||
{
|
||||
sb_printf( lineinfo,
|
||||
_(L"%ls (line %d): "),
|
||||
file,
|
||||
lineno );
|
||||
offset = my_wcswidth( (wchar_t *)lineinfo->buff );
|
||||
int prev_width = my_wcswidth( (wchar_t *)lineinfo->buff );
|
||||
if( file )
|
||||
sb_printf( lineinfo,
|
||||
_(L"%ls (line %d): "),
|
||||
file,
|
||||
lineno );
|
||||
else
|
||||
sb_printf( lineinfo,
|
||||
L"%ls: ",
|
||||
_(L"Standard input"),
|
||||
lineno );
|
||||
offset = my_wcswidth( (wchar_t *)lineinfo->buff ) - prev_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset=0;
|
||||
}
|
||||
|
||||
// debug( 1, L"Current pos %d, line pos %d, file_length %d, is_interactive %d, offset %d\n", current_tokenizer_pos, current_line_pos, wcslen(whole_str), is_interactive, offset);
|
||||
/*
|
||||
Skip printing character position if we are in interactive mode
|
||||
and the error was on the first character of the line
|
||||
and the error was on the first character of the line.
|
||||
*/
|
||||
if( !is_interactive || (current_line_pos!=0) )
|
||||
if( !is_interactive || is_function() || (current_line_width!=0) )
|
||||
{
|
||||
sb_printf( lineinfo,
|
||||
L"%ls\n%*c^\n",
|
||||
line,
|
||||
offset+current_line_pos,
|
||||
L' ' );
|
||||
// Workaround since it seems impossible to print 0 copies of a character using printf
|
||||
if( offset+current_line_width )
|
||||
{
|
||||
sb_printf( lineinfo,
|
||||
L"%ls\n%*lc^\n",
|
||||
line,
|
||||
offset+current_line_width,
|
||||
L' ' );
|
||||
}
|
||||
else
|
||||
{
|
||||
sb_printf( lineinfo,
|
||||
L"%ls\n^\n",
|
||||
line );
|
||||
}
|
||||
}
|
||||
|
||||
free( line );
|
||||
parser_stack_trace( current_block, lineinfo );
|
||||
|
||||
return (wchar_t *)lineinfo->buff;
|
||||
}
|
||||
@@ -1162,6 +1342,7 @@ static void parse_job_main_loop( process_t *p,
|
||||
|
||||
case TOK_BACKGROUND:
|
||||
j->fg = 0;
|
||||
j->terminal=0;
|
||||
case TOK_END:
|
||||
{
|
||||
p->argv = list_to_char_arr( args );
|
||||
@@ -1981,10 +2162,10 @@ static void eval_job( tokenizer *tok )
|
||||
j->fg=1;
|
||||
j->constructed=0;
|
||||
j->skip_notification = is_subshell || is_block || is_event || (!is_interactive);
|
||||
|
||||
current_block->job = j;
|
||||
|
||||
j->terminal = is_interactive && !is_subshell;
|
||||
|
||||
current_block->job = j;
|
||||
|
||||
if( is_interactive )
|
||||
{
|
||||
if( tcgetattr (0, &j->tmodes) )
|
||||
|
||||
31
parser.h
31
parser.h
@@ -11,6 +11,9 @@
|
||||
#include "util.h"
|
||||
#include "parser.h"
|
||||
|
||||
/**
|
||||
event_block_t represents a block on events of the specified type
|
||||
*/
|
||||
typedef struct event_block
|
||||
{
|
||||
/**
|
||||
@@ -60,7 +63,7 @@ typedef struct block
|
||||
wchar_t *for_variable; /**< Name of the variable to loop over */
|
||||
int if_state; /**< The state of the if block */
|
||||
wchar_t *switch_value; /**< The value to test in a switch block */
|
||||
wchar_t *function_name; /**< The name of the function to define */
|
||||
wchar_t *function_name; /**< The name of the function to define or the function called*/
|
||||
} param1;
|
||||
|
||||
/**
|
||||
@@ -71,6 +74,7 @@ typedef struct block
|
||||
array_list_t for_vars; /**< List of values for a for block */
|
||||
int switch_taken; /**< Whether a switch match has already been found */
|
||||
wchar_t *function_description; /**< The description of the function to define */
|
||||
array_list_t function_vars; /**< List of arguments for a function call */
|
||||
} param2;
|
||||
|
||||
/**
|
||||
@@ -79,6 +83,7 @@ typedef struct block
|
||||
union
|
||||
{
|
||||
int function_is_binding; /**< Whether a function is a keybinding */
|
||||
int function_lineno; /**< Function invocation line number */
|
||||
} param3;
|
||||
|
||||
/**
|
||||
@@ -87,6 +92,7 @@ typedef struct block
|
||||
union
|
||||
{
|
||||
array_list_t *function_events;
|
||||
wchar_t *function_filename;
|
||||
} param4;
|
||||
|
||||
/**
|
||||
@@ -193,10 +199,10 @@ wchar_t *get_filename( const wchar_t *cmd );
|
||||
Evaluate the expressions contained in cmd.
|
||||
|
||||
\param cmd the string to evaluate
|
||||
\param out buffer to insert output to. May be null.
|
||||
\param the type of block to push onto the scope stack
|
||||
\param io io redirections to perform on all started jobs
|
||||
\param block_type The type of block to push on the block stack
|
||||
\return 0 on success.
|
||||
|
||||
\return 0 on success, 1 otherwise
|
||||
*/
|
||||
int eval( const wchar_t *cmd, io_data_t *io, int block_type );
|
||||
|
||||
@@ -235,10 +241,10 @@ int parser_is_subcommand( const wchar_t *cmd );
|
||||
command scope, like 'for', 'end' or 'command' or 'exec'. These
|
||||
functions may not be overloaded, so their names are reserved.
|
||||
|
||||
\param cmd The command name to test
|
||||
\param word The command name to test
|
||||
\return 1 of the command parameter is a command, 0 otherwise
|
||||
*/
|
||||
int parser_is_reserved( wchar_t *word);
|
||||
int parser_is_reserved( wchar_t *word );
|
||||
|
||||
/**
|
||||
Returns a string describing the current parser pisition in the format 'FILENAME (line LINE_NUMBER): LINE'.
|
||||
@@ -248,6 +254,11 @@ int parser_is_reserved( wchar_t *word);
|
||||
*/
|
||||
wchar_t *parser_current_line();
|
||||
|
||||
/**
|
||||
Returns the current line number
|
||||
*/
|
||||
int parser_get_lineno();
|
||||
|
||||
/**
|
||||
Returns the current position in the latest string of the tokenizer.
|
||||
*/
|
||||
@@ -328,4 +339,12 @@ void parser_destroy();
|
||||
*/
|
||||
int parser_is_help( wchar_t *s, int min_match );
|
||||
|
||||
/**
|
||||
Returns the file currently evaluated by the parser. This can be
|
||||
different than reader_current_filename, e.g. if we are evaulating a
|
||||
function defined in a different file than the one curently read.
|
||||
*/
|
||||
const wchar_t *parser_current_filename();
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
41
proc.c
41
proc.c
@@ -36,7 +36,11 @@ Some of the code in this file is based on code from the Glibc manual.
|
||||
#include <termio.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_TERM_H
|
||||
#include <term.h>
|
||||
#elif HAVE_NCURSES_TERM_H
|
||||
#include <ncurses/term.h>
|
||||
#endif
|
||||
|
||||
#include "util.h"
|
||||
#include "wutil.h"
|
||||
@@ -646,13 +650,18 @@ int job_reap( int interactive )
|
||||
|
||||
|
||||
#ifdef HAVE__PROC_SELF_STAT
|
||||
|
||||
/**
|
||||
Maximum length of a /proc/[PID]/stat filename
|
||||
*/
|
||||
#define FN_SIZE 256
|
||||
|
||||
/**
|
||||
Get the CPU time for the specified process
|
||||
*/
|
||||
unsigned long proc_get_jiffies( process_t *p )
|
||||
{
|
||||
wchar_t fn[256];
|
||||
//char stat_line[1024];
|
||||
wchar_t fn[FN_SIZE];
|
||||
|
||||
char state;
|
||||
int pid, ppid, pgrp,
|
||||
@@ -674,7 +683,7 @@ unsigned long proc_get_jiffies( process_t *p )
|
||||
if( p->pid <= 0 )
|
||||
return 0;
|
||||
|
||||
swprintf( fn, 512, L"/proc/%d/stat", p->pid );
|
||||
swprintf( fn, FN_SIZE, L"/proc/%d/stat", p->pid );
|
||||
|
||||
FILE *f = wfopen( fn, "r" );
|
||||
if( !f )
|
||||
@@ -846,22 +855,6 @@ static void read_try( job_t *j )
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Test if a specified job contains external commands
|
||||
|
||||
\param j the job to test
|
||||
*/
|
||||
static int job_is_external( job_t *j )
|
||||
{
|
||||
process_t *p;
|
||||
for( p=j->first_process; p; p=p->next )
|
||||
{
|
||||
if( p->type == EXTERNAL )
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void job_continue (job_t *j, int cont)
|
||||
{
|
||||
@@ -873,7 +866,7 @@ void job_continue (job_t *j, int cont)
|
||||
first_job = j;
|
||||
j->notified = 0;
|
||||
|
||||
debug( 3,
|
||||
debug( 4,
|
||||
L"Continue on job %d (%ls), %ls, %ls",
|
||||
j->job_id,
|
||||
j->command,
|
||||
@@ -882,7 +875,7 @@ void job_continue (job_t *j, int cont)
|
||||
|
||||
if( !job_is_completed( j ) )
|
||||
{
|
||||
if( is_interactive && job_is_external( j ) )
|
||||
if( j->terminal )
|
||||
{
|
||||
|
||||
/* Put the job into the foreground. */
|
||||
@@ -937,6 +930,7 @@ void job_continue (job_t *j, int cont)
|
||||
{
|
||||
int quit = 0;
|
||||
|
||||
// debug( 1, L"wait loop" );
|
||||
/*
|
||||
Wait for job to report. Looks a bit ugly because it has to
|
||||
handle the possibility that a signal is dispatched while
|
||||
@@ -953,7 +947,7 @@ void job_continue (job_t *j, int cont)
|
||||
if( !quit )
|
||||
{
|
||||
|
||||
debug( 3, L"select_try()" );
|
||||
// debug( 1, L"select_try()" );
|
||||
switch( select_try(j) )
|
||||
{
|
||||
case 1:
|
||||
@@ -973,6 +967,7 @@ void job_continue (job_t *j, int cont)
|
||||
short-lived jobs.
|
||||
*/
|
||||
int status;
|
||||
// debug( 1, L"waitpid" );
|
||||
pid_t pid = waitpid(-1, &status, WUNTRACED );
|
||||
if( pid > 0 )
|
||||
handle_child_status( pid, status );
|
||||
@@ -1010,7 +1005,7 @@ void job_continue (job_t *j, int cont)
|
||||
/*
|
||||
Put the shell back in the foreground.
|
||||
*/
|
||||
if( is_interactive && job_is_external( j ) )
|
||||
if( j->terminal )
|
||||
{
|
||||
signal_block();
|
||||
if( tcsetpgrp (0, getpid()) )
|
||||
|
||||
11
proc.h
11
proc.h
@@ -14,6 +14,7 @@
|
||||
#include <wchar.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "io.h"
|
||||
@@ -154,7 +155,10 @@ typedef struct job
|
||||
|
||||
/** Skip executing this job. This flag is set by the short-circut builtins, i.e. and and or */
|
||||
int skip;
|
||||
|
||||
|
||||
/** Whether this job wants to have control of the terminal when it is in the foreground */
|
||||
int terminal;
|
||||
|
||||
/** Pointer to the next job */
|
||||
struct job *next;
|
||||
}
|
||||
@@ -207,6 +211,9 @@ extern job_t *first_job;
|
||||
*/
|
||||
extern int proc_had_barrier;
|
||||
|
||||
/**
|
||||
Pid of last process to be started in the background
|
||||
*/
|
||||
extern pid_t proc_last_bg_pid;
|
||||
|
||||
/**
|
||||
@@ -303,7 +310,7 @@ void proc_sanity_check();
|
||||
*/
|
||||
void proc_fire_event( const wchar_t *msg, int type, pid_t pid, int status );
|
||||
|
||||
/*
|
||||
/**
|
||||
Initializations
|
||||
*/
|
||||
void proc_init();
|
||||
|
||||
32
reader.c
32
reader.c
@@ -45,7 +45,12 @@ commence.
|
||||
#include <termio.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_TERM_H
|
||||
#include <term.h>
|
||||
#elif HAVE_NCURSES_TERM_H
|
||||
#include <ncurses/term.h>
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
@@ -272,8 +277,16 @@ static struct termios saved_modes;
|
||||
*/
|
||||
static pid_t original_pid;
|
||||
|
||||
/**
|
||||
This variable is set to true by the signal handler when ^C is pressed
|
||||
*/
|
||||
static int interupted=0;
|
||||
|
||||
/**
|
||||
Original terminal mode when fish was started
|
||||
*/
|
||||
static struct termios old_modes;
|
||||
|
||||
/*
|
||||
Prototypes for a bunch of functions defined later on.
|
||||
*/
|
||||
@@ -282,8 +295,10 @@ 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 );
|
||||
|
||||
static struct termios old_modes;
|
||||
|
||||
/**
|
||||
Give up control of terminal
|
||||
*/
|
||||
static void term_donate()
|
||||
{
|
||||
tcgetattr(0,&old_modes); /* get the current terminal modes */
|
||||
@@ -308,6 +323,9 @@ static void term_donate()
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Grab control of terminal
|
||||
*/
|
||||
static void term_steal()
|
||||
{
|
||||
|
||||
@@ -367,7 +385,7 @@ void reader_handle_int( int sig )
|
||||
|
||||
wchar_t *reader_current_filename()
|
||||
{
|
||||
return (wchar_t *)al_peek( ¤t_filename );
|
||||
return al_get_count( ¤t_filename )?(wchar_t *)al_peek( ¤t_filename ):0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1723,6 +1741,9 @@ void reader_current_subshell_extent( wchar_t **a, wchar_t **b )
|
||||
*b = end;
|
||||
}
|
||||
|
||||
/**
|
||||
Get the beginning and dend of the job or process definition under the cursor
|
||||
*/
|
||||
static void reader_current_job_or_process_extent( wchar_t **a,
|
||||
wchar_t **b,
|
||||
int process )
|
||||
@@ -1992,6 +2013,9 @@ static int contains( const wchar_t *needle,
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Reset the data structures associated with the token search
|
||||
*/
|
||||
static void reset_token_history()
|
||||
{
|
||||
wchar_t *begin, *end;
|
||||
@@ -2525,8 +2549,8 @@ static int read_i()
|
||||
{
|
||||
prev_end_loop=0;
|
||||
}
|
||||
|
||||
error_reset();
|
||||
|
||||
}
|
||||
reader_pop();
|
||||
return 0;
|
||||
@@ -2829,7 +2853,7 @@ wchar_t *reader_readline()
|
||||
break;
|
||||
}
|
||||
|
||||
/* exit, but only if line is empty or the previous keypress was also an exit call */
|
||||
/* exit, but only if line is empty */
|
||||
case R_EXIT:
|
||||
{
|
||||
if( data->buff_len == 0 )
|
||||
|
||||
33
seq.in
Executable file
33
seq.in
Executable file
@@ -0,0 +1,33 @@
|
||||
#!@prefix@/bin/fish
|
||||
|
||||
set -l from 1
|
||||
set -l step 1
|
||||
set -l to 1
|
||||
|
||||
switch (count $argv)
|
||||
case 1
|
||||
set to $argv[1]
|
||||
|
||||
case 2
|
||||
set from $argv[1]
|
||||
set to $argv[2]
|
||||
|
||||
case 3
|
||||
set from $argv[1]
|
||||
set step $argv[2]
|
||||
set to $argv[3]
|
||||
|
||||
case '*'
|
||||
printf (_ "%s: Expected 1, 2 or 3 arguments, got %d\n") seq (count $argv)
|
||||
return 1
|
||||
|
||||
end
|
||||
|
||||
for i in $from $step $to
|
||||
if not echo $i | grep '^-\?[0-9]*\(\|.[0-9]\+\)$' >/dev/null
|
||||
printf (_ "%s: '%s' is not a number\n") seq $i
|
||||
return 1
|
||||
end
|
||||
end
|
||||
|
||||
echo "for( i=$from; i<=$to ; i+=$step ) i;" | bc
|
||||
45
set_color.c
45
set_color.c
@@ -7,6 +7,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <locale.h>
|
||||
|
||||
#if HAVE_NCURSES_H
|
||||
#include <ncurses.h>
|
||||
@@ -14,18 +15,26 @@
|
||||
#include <curses.h>
|
||||
#endif
|
||||
|
||||
|
||||
#if HAVE_TERMIO_H
|
||||
#include <termio.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_TERM_H
|
||||
#include <term.h>
|
||||
#elif HAVE_NCURSES_TERM_H
|
||||
#include <ncurses/term.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_LIBINTL_H
|
||||
#include <libintl.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
Small utility for setting the color.
|
||||
Usage: set_color COLOR
|
||||
@@ -34,6 +43,17 @@
|
||||
|
||||
#define COLORS (sizeof(col)/sizeof(char *))
|
||||
|
||||
/**
|
||||
Program name
|
||||
*/
|
||||
#define SET_COLOR "set_color"
|
||||
|
||||
#if HAVE_GETTEXT
|
||||
#define _(string) gettext(string)
|
||||
#else
|
||||
#define _(string) (string)
|
||||
#endif
|
||||
|
||||
char *col[]=
|
||||
{
|
||||
"black",
|
||||
@@ -105,12 +125,25 @@ void print_colors()
|
||||
}
|
||||
}
|
||||
|
||||
static void locale_init()
|
||||
{
|
||||
setlocale( LC_ALL, "" );
|
||||
#if HAVE_GETTEXT
|
||||
bindtextdomain( PACKAGE_NAME, LOCALEDIR );
|
||||
textdomain( PACKAGE_NAME );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
char *bgcolor=0;
|
||||
char *fgcolor=0;
|
||||
int fg, bg;
|
||||
int bold=0;
|
||||
|
||||
locale_init();
|
||||
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
@@ -176,7 +209,7 @@ int main( int argc, char **argv )
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
fprintf( stderr, "set_color, version %s\n", PACKAGE_VERSION );
|
||||
fprintf( stderr, _("%s, version %s\n"), SET_COLOR, PACKAGE_VERSION );
|
||||
exit( 0 );
|
||||
|
||||
case 'c':
|
||||
@@ -202,13 +235,13 @@ int main( int argc, char **argv )
|
||||
break;
|
||||
|
||||
default:
|
||||
printf( "set_color: Too many arguments\n" );
|
||||
printf( _("%s: Too many arguments\n"), SET_COLOR );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( !fgcolor && !bgcolor && !bold )
|
||||
{
|
||||
fprintf( stderr, "set_color: Expected an argument\n" );
|
||||
fprintf( stderr, _("%s: Expected an argument\n"), SET_COLOR );
|
||||
print_help();
|
||||
return 1;
|
||||
}
|
||||
@@ -216,14 +249,14 @@ int main( int argc, char **argv )
|
||||
fg = translate_color(fgcolor);
|
||||
if( fgcolor && (fg==-1))
|
||||
{
|
||||
fprintf( stderr, "set_color: Unknown color %s\n", fgcolor );
|
||||
fprintf( stderr, _("%s: Unknown color '%s'\n"), SET_COLOR, fgcolor );
|
||||
return 1;
|
||||
}
|
||||
|
||||
bg = translate_color(bgcolor);
|
||||
if( bgcolor && (bg==-1))
|
||||
{
|
||||
fprintf( stderr, "set_color: Unknown color %s\n", bgcolor );
|
||||
fprintf( stderr, _("%s: Unknown color '%s'\n"), SET_COLOR, bgcolor );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
59
signal.c
59
signal.c
@@ -186,30 +186,44 @@ static struct lookup_entry lookup[] =
|
||||
N_( L"CPU time limit exceeded" )
|
||||
}
|
||||
,
|
||||
#ifdef SIGXFSZ
|
||||
{
|
||||
SIGXFSZ,
|
||||
L"SIGXFSZ",
|
||||
N_( L"File size limit exceeded" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
{
|
||||
SIGVTALRM,
|
||||
L"SIGVTALRM",
|
||||
N_( L"Virtual timer expired" )
|
||||
}
|
||||
,
|
||||
#ifdef SIGPROF
|
||||
{
|
||||
SIGPROF,
|
||||
L"SIGPROF",
|
||||
N_( L"Profiling timer expired" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGWINCH
|
||||
{
|
||||
SIGWINCH,
|
||||
L"SIGWINCH",
|
||||
N_( L"Window size change" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGWIND
|
||||
{
|
||||
SIGWIND,
|
||||
L"SIGWIND",
|
||||
N_( L"Window size change" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
{
|
||||
SIGIO,
|
||||
L"SIGIO",
|
||||
@@ -224,12 +238,54 @@ static struct lookup_entry lookup[] =
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGSYS
|
||||
{
|
||||
SIGSYS,
|
||||
L"SIGSYS",
|
||||
N_( L"Bad system call" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGINFO
|
||||
{
|
||||
SIGINFO,
|
||||
L"SIGINFO",
|
||||
N_( L"Information request" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGSTKFLT
|
||||
{
|
||||
SIGSTKFLT,
|
||||
L"SISTKFLT",
|
||||
N_( L"Stack fault" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGEMT
|
||||
{
|
||||
SIGEMT,
|
||||
L"SIGEMT",
|
||||
N_( L"Emulator trap" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGIOT
|
||||
{
|
||||
SIGIOT,
|
||||
L"SIGIOT",
|
||||
N_( L"Abort (Alias for SIGABRT)" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
#ifdef SIGUNUSED
|
||||
{
|
||||
SIGUNUSED,
|
||||
L"SIGUNUSED",
|
||||
N_( L"Unused signal" )
|
||||
}
|
||||
,
|
||||
#endif
|
||||
{
|
||||
0,
|
||||
0,
|
||||
@@ -299,6 +355,9 @@ const wchar_t *sig_description( int sig )
|
||||
return L"Unknown";
|
||||
}
|
||||
|
||||
/**
|
||||
Standard signal handler
|
||||
*/
|
||||
static void default_handler(int signal, siginfo_t *info, void *context)
|
||||
{
|
||||
event_t e;
|
||||
|
||||
2
signal.h
2
signal.h
@@ -38,7 +38,7 @@ void signal_set_handlers();
|
||||
*/
|
||||
void signal_handle( int sig, int do_handle );
|
||||
|
||||
/*
|
||||
/**
|
||||
Block all signals
|
||||
*/
|
||||
void signal_block();
|
||||
|
||||
@@ -54,6 +54,9 @@
|
||||
*/
|
||||
#define FD_STR_MAX_LEN 16
|
||||
|
||||
/**
|
||||
Descriptions of all tokenizer errors
|
||||
*/
|
||||
static const wchar_t *tok_desc[] =
|
||||
{
|
||||
N_(L"Tokenizer not yet initialized"),
|
||||
|
||||
28
translate.c
28
translate.c
@@ -8,22 +8,46 @@ Translation library, internally uses catgets
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#if HAVE_LIBINTL_H
|
||||
#include <libintl.h>
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
#include "util.h"
|
||||
|
||||
#if HAVE_GETTEXT
|
||||
|
||||
/**
|
||||
Number of string_buffer_t in the ring of buffers
|
||||
*/
|
||||
#define BUFF_COUNT 64
|
||||
|
||||
/**
|
||||
The ring of string_buffer_t
|
||||
*/
|
||||
static string_buffer_t buff[BUFF_COUNT];
|
||||
/**
|
||||
Current position in the ring
|
||||
*/
|
||||
static int curr_buff=0;
|
||||
|
||||
/**
|
||||
Buffer used by translate_wcs2str
|
||||
*/
|
||||
static char *wcs2str_buff=0;
|
||||
/**
|
||||
Size of buffer used by translate_wcs2str
|
||||
*/
|
||||
static size_t wcs2str_buff_count=0;
|
||||
|
||||
char *translate_wcs2str( const wchar_t *in )
|
||||
/**
|
||||
Wide to narrow character conversion. Internal implementation that
|
||||
avoids exessive calls to malloc
|
||||
*/
|
||||
static char *translate_wcs2str( const wchar_t *in )
|
||||
{
|
||||
size_t len = MAX_UTF8_BYTES*wcslen(in)+1;
|
||||
if( len > wcs2str_buff_count )
|
||||
@@ -90,6 +114,8 @@ void translate_destroy()
|
||||
|
||||
#else
|
||||
|
||||
int _nl_msg_cat_cntr=0;
|
||||
|
||||
const wchar_t *wgettext( const wchar_t *in )
|
||||
{
|
||||
return in;
|
||||
|
||||
@@ -21,7 +21,9 @@ const wchar_t *wgettext( const wchar_t *in );
|
||||
|
||||
/**
|
||||
Initialize (or reinitialize) the translation library
|
||||
\param lang The two-character language name, such as 'de' or 'en'
|
||||
*/
|
||||
void translate_init();
|
||||
/**
|
||||
Free memory used by the translation library
|
||||
*/
|
||||
void translate_destroy();
|
||||
|
||||
51
util.c
51
util.c
@@ -168,10 +168,6 @@ int q_empty( dyn_queue_t *q )
|
||||
return q->put_pos == q->get_pos;
|
||||
}
|
||||
|
||||
/* Stack functions */
|
||||
|
||||
|
||||
|
||||
|
||||
/* Hash table functions */
|
||||
|
||||
@@ -836,6 +832,12 @@ int wcsfilecmp( const wchar_t *a, const wchar_t *b )
|
||||
void sb_init( string_buffer_t * b)
|
||||
{
|
||||
wchar_t c=0;
|
||||
|
||||
if( !b )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
memset( b, 0, sizeof(string_buffer_t) );
|
||||
b_append( b, &c, sizeof( wchar_t));
|
||||
b->used -= sizeof(wchar_t);
|
||||
@@ -856,8 +858,14 @@ void sb_append( string_buffer_t *b, const wchar_t * s)
|
||||
// fwprintf( stderr, L"Append string \'%ls\'\n", s );
|
||||
|
||||
if( !s )
|
||||
{
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if( !b )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
b_append( b, s, sizeof(wchar_t)*(wcslen(s)+1) );
|
||||
b->used -= sizeof(wchar_t);
|
||||
@@ -868,7 +876,14 @@ void sb_append_substring( string_buffer_t *b, const wchar_t *s, size_t l )
|
||||
wchar_t tmp=0;
|
||||
|
||||
if( !s )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( !b )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
b_append( b, s, sizeof(wchar_t)*l );
|
||||
b_append( b, &tmp, sizeof(wchar_t) );
|
||||
@@ -883,6 +898,12 @@ void sb_append_char( string_buffer_t *b, wchar_t c )
|
||||
c, 0
|
||||
}
|
||||
;
|
||||
|
||||
if( !b )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sb_append( b, buff );
|
||||
|
||||
}
|
||||
@@ -892,6 +913,11 @@ void sb_append2( string_buffer_t *b, ... )
|
||||
va_list va;
|
||||
wchar_t *arg;
|
||||
|
||||
if( !b )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
va_start( va, b );
|
||||
while( (arg=va_arg(va, wchar_t *) )!= 0 )
|
||||
{
|
||||
@@ -905,6 +931,11 @@ int sb_printf( string_buffer_t *buffer, const wchar_t *format, ... )
|
||||
va_list va;
|
||||
int res;
|
||||
|
||||
if( !buffer )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
va_start( va, format );
|
||||
res = sb_vprintf( buffer, format, va );
|
||||
va_end( va );
|
||||
@@ -916,6 +947,11 @@ int sb_vprintf( string_buffer_t *buffer, const wchar_t *format, va_list va_orig
|
||||
{
|
||||
int res;
|
||||
|
||||
if( !buffer )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( !buffer->length )
|
||||
{
|
||||
buffer->length = MIN_SIZE;
|
||||
@@ -972,6 +1008,11 @@ int sb_vprintf( string_buffer_t *buffer, const wchar_t *format, va_list va_orig
|
||||
|
||||
void sb_destroy( string_buffer_t * b )
|
||||
{
|
||||
if( !b )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
free( b->buff );
|
||||
}
|
||||
|
||||
|
||||
53
util.h
53
util.h
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <wchar.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/**
|
||||
Data structure for an automatically resizing dynamically allocated queue,
|
||||
@@ -165,19 +166,29 @@ float minf( float a, float b );
|
||||
*/
|
||||
void q_init( dyn_queue_t *q );
|
||||
|
||||
/** Destroy the queue */
|
||||
/**
|
||||
Destroy the queue
|
||||
*/
|
||||
void q_destroy( dyn_queue_t *q );
|
||||
|
||||
/** Insert element into queue */
|
||||
/**
|
||||
Insert element into queue
|
||||
*/
|
||||
int q_put( dyn_queue_t *q, void *e );
|
||||
|
||||
/** Remove and return next element from queue */
|
||||
/**
|
||||
Remove and return next element from queue
|
||||
*/
|
||||
void *q_get( dyn_queue_t *q);
|
||||
|
||||
/** Return next element from queue without removing it */
|
||||
/**
|
||||
Return next element from queue without removing it
|
||||
*/
|
||||
void *q_peek( dyn_queue_t *q);
|
||||
|
||||
/** Returns 1 if the queue is empty, 0 otherwise */
|
||||
/**
|
||||
Returns 1 if the queue is empty, 0 otherwise
|
||||
*/
|
||||
int q_empty( dyn_queue_t *q );
|
||||
|
||||
/**
|
||||
@@ -251,15 +262,15 @@ void hash_get_keys( hash_table_t *h,
|
||||
void hash_get_data( hash_table_t *h,
|
||||
array_list_t *arr );
|
||||
|
||||
/**
|
||||
Call the function func for each key/data pair in the table
|
||||
/**
|
||||
Call the function func for each key/data pair in the table
|
||||
*/
|
||||
void hash_foreach( hash_table_t *h,
|
||||
void (*func)( const void *, const void * ) );
|
||||
|
||||
/**
|
||||
Same as hash_foreach, but the function func takes an additional
|
||||
argument, which is provided by the caller in the variable aux
|
||||
/**
|
||||
Same as hash_foreach, but the function func takes an additional
|
||||
argument, which is provided by the caller in the variable aux
|
||||
*/
|
||||
void hash_foreach2( hash_table_t *h, void (*func)( const void *,
|
||||
const void *,
|
||||
@@ -273,7 +284,8 @@ int hash_str_func( const void *data );
|
||||
/**
|
||||
Hash comparison function suitable for character strings
|
||||
*/
|
||||
int hash_str_cmp( const void *a, const void *b );
|
||||
int hash_str_cmp( const void *a,
|
||||
const void *b );
|
||||
|
||||
/**
|
||||
Hash function suitable for wide character strings.
|
||||
@@ -283,7 +295,8 @@ int hash_wcs_func( const void *data );
|
||||
/**
|
||||
Hash comparison function suitable for wide character strings
|
||||
*/
|
||||
int hash_wcs_cmp( const void *a, const void *b );
|
||||
int hash_wcs_cmp( const void *a,
|
||||
const void *b );
|
||||
|
||||
/**
|
||||
Initialize the priority queue
|
||||
@@ -296,12 +309,12 @@ void pq_init( priority_queue_t *q,
|
||||
/**
|
||||
Add element to the queue
|
||||
|
||||
\param q the queue
|
||||
\param e the new element
|
||||
\param q the queue
|
||||
\param e the new element
|
||||
|
||||
*/
|
||||
int pq_put( priority_queue_t *q,
|
||||
void *e );
|
||||
void *e );
|
||||
/**
|
||||
Removes and returns the last entry in the priority queue
|
||||
*/
|
||||
@@ -445,11 +458,18 @@ void al_foreach2( array_list_t *l, void (*func)(const void *, void *), void *aux
|
||||
int wcsfilecmp( const wchar_t *a, const wchar_t *b );
|
||||
|
||||
|
||||
/*
|
||||
String buffer functions
|
||||
*/
|
||||
|
||||
/**
|
||||
Initialize the specified string_buffer
|
||||
*/
|
||||
void sb_init( string_buffer_t * );
|
||||
|
||||
/**
|
||||
Allocate memory for storing a stringbuffer and init it
|
||||
*/
|
||||
string_buffer_t *sb_new();
|
||||
|
||||
/**
|
||||
@@ -500,6 +520,9 @@ void sb_destroy( string_buffer_t * );
|
||||
*/
|
||||
void sb_clear( string_buffer_t * );
|
||||
|
||||
/*
|
||||
Buffer functions
|
||||
*/
|
||||
|
||||
/**
|
||||
Initialize the specified buffer_t
|
||||
|
||||
@@ -49,12 +49,6 @@ License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
|
||||
Ditto for AIX 3.2 and <stdlib.h>. */
|
||||
#ifndef _NO_PROTO
|
||||
#define _NO_PROTO
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if !defined (__STDC__) || !__STDC__
|
||||
|
||||
11
wildcard.c
11
wildcard.c
@@ -278,17 +278,22 @@ void get_desc( wchar_t *fn, string_buffer_t *sb, int is_cmd )
|
||||
}
|
||||
|
||||
desc = complete_get_desc( fn );
|
||||
|
||||
|
||||
if( wcschr( desc, COMPLETE_SEP )==0 )
|
||||
{
|
||||
sb_append( sb, COMPLETE_SEP_STR );
|
||||
}
|
||||
|
||||
if( sz >= 0 && S_ISDIR(buf.st_mode) )
|
||||
{
|
||||
sb_append2( sb, desc, (void *)0 );
|
||||
sb_append( sb, desc );
|
||||
}
|
||||
else
|
||||
{
|
||||
sb_append2( sb, desc, L", ", (void *)0 );
|
||||
if( sz < 0 )
|
||||
{
|
||||
sb_append( sb, _(L"unknown") );
|
||||
sb_append( sb, L"unknown" );
|
||||
}
|
||||
else if( sz < 1 )
|
||||
{
|
||||
|
||||
321
wutil.c
321
wutil.c
@@ -1,5 +1,7 @@
|
||||
/** \file wutil.c
|
||||
Wide character equivalents of various standard unix functions.
|
||||
Wide character equivalents of various standard unix
|
||||
functions. Also contains fallback implementations of a large number
|
||||
of wide character unix functions.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
@@ -218,7 +220,7 @@ void wperror(const wchar_t *s)
|
||||
}
|
||||
|
||||
|
||||
#if !HAVE_WPRINTF
|
||||
#if !HAVE_FWPRINTF
|
||||
|
||||
void pad( void (*writer)(wchar_t), int count)
|
||||
{
|
||||
@@ -707,3 +709,318 @@ int wprintf( const wchar_t *filter, ... )
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FGETWC
|
||||
|
||||
wint_t fgetwc(FILE *stream)
|
||||
{
|
||||
wchar_t res=0;
|
||||
mbstate_t state;
|
||||
memset (&state, '\0', sizeof (state));
|
||||
|
||||
while(1)
|
||||
{
|
||||
int b = fgetc( stream );
|
||||
char bb;
|
||||
|
||||
int sz;
|
||||
|
||||
if( b == EOF )
|
||||
return WEOF;
|
||||
|
||||
bb=b;
|
||||
|
||||
sz = mbrtowc( &res, &bb, 1, &state );
|
||||
|
||||
switch( sz )
|
||||
{
|
||||
case -1:
|
||||
memset (&state, '\0', sizeof (state));
|
||||
return WEOF;
|
||||
|
||||
case -2:
|
||||
break;
|
||||
case 0:
|
||||
return 0;
|
||||
default:
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
wint_t getwc(FILE *stream)
|
||||
{
|
||||
return fgetwc( stream );
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FPUTWC
|
||||
|
||||
wint_t fputwc(wchar_t wc, FILE *stream)
|
||||
{
|
||||
int res;
|
||||
char s[MB_CUR_MAX+1];
|
||||
memset( s, 0, MB_CUR_MAX+1 );
|
||||
wctomb( s, wc );
|
||||
res = fputs( s, stream );
|
||||
return res==EOF?WEOF:wc;
|
||||
}
|
||||
|
||||
wint_t putwc(wchar_t wc, FILE *stream)
|
||||
{
|
||||
return fputwc( wc, stream );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCSTOK
|
||||
|
||||
/*
|
||||
Used by fallback wcstok. Borrowed from glibc
|
||||
*/
|
||||
static size_t fish_wcsspn (const wchar_t *wcs,
|
||||
const wchar_t *accept )
|
||||
{
|
||||
register const wchar_t *p;
|
||||
register const wchar_t *a;
|
||||
register size_t count = 0;
|
||||
|
||||
for (p = wcs; *p != L'\0'; ++p)
|
||||
{
|
||||
for (a = accept; *a != L'\0'; ++a)
|
||||
if (*p == *a)
|
||||
break;
|
||||
|
||||
if (*a == L'\0')
|
||||
return count;
|
||||
else
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
Used by fallback wcstok. Borrowed from glibc
|
||||
*/
|
||||
static wchar_t *fish_wcspbrk (const wchar_t *wcs, const wchar_t *accept)
|
||||
{
|
||||
while (*wcs != L'\0')
|
||||
if (wcschr (accept, *wcs) == NULL)
|
||||
++wcs;
|
||||
else
|
||||
return (wchar_t *) wcs;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
Fallback wcstok implementation. Borrowed from glibc.
|
||||
*/
|
||||
wchar_t *wcstok(wchar_t *wcs, const wchar_t *delim, wchar_t **save_ptr)
|
||||
{
|
||||
wchar_t *result;
|
||||
|
||||
if (wcs == NULL)
|
||||
{
|
||||
if (*save_ptr == NULL)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
wcs = *save_ptr;
|
||||
}
|
||||
|
||||
/* Scan leading delimiters. */
|
||||
wcs += fish_wcsspn (wcs, delim);
|
||||
|
||||
if (*wcs == L'\0')
|
||||
{
|
||||
*save_ptr = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Find the end of the token. */
|
||||
result = wcs;
|
||||
|
||||
wcs = fish_wcspbrk (result, delim);
|
||||
|
||||
if (wcs == NULL)
|
||||
{
|
||||
/* This token finishes the string. */
|
||||
*save_ptr = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Terminate the token and make *SAVE_PTR point past it. */
|
||||
*wcs = L'\0';
|
||||
*save_ptr = wcs + 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCSDUP
|
||||
wchar_t *wcsdup( const wchar_t *in )
|
||||
{
|
||||
size_t len=wcslen(in);
|
||||
wchar_t *out = malloc( sizeof( wchar_t)*(len+1));
|
||||
if( out == 0 )
|
||||
{
|
||||
die_mem();
|
||||
}
|
||||
|
||||
memcpy( out, in, sizeof( wchar_t)*(len+1));
|
||||
return out;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCSLEN
|
||||
size_t wcslen(const wchar_t *in)
|
||||
{
|
||||
const wchar_t *end=in;
|
||||
while( *end )
|
||||
end++;
|
||||
return end-in;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_WCSCASECMP
|
||||
int wcscasecmp( const wchar_t *a, const wchar_t *b )
|
||||
{
|
||||
if( *a == 0 )
|
||||
{
|
||||
return (*b==0)?0:-1;
|
||||
}
|
||||
else if( *b == 0 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
int diff = towlower(*a)-towlower(*b);
|
||||
if( diff != 0 )
|
||||
return diff;
|
||||
else
|
||||
return wcscasecmp( a+1,b+1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_WCSNCASECMP
|
||||
int wcsncasecmp( const wchar_t *a, const wchar_t *b, int count )
|
||||
{
|
||||
if( count == 0 )
|
||||
return 0;
|
||||
|
||||
if( *a == 0 )
|
||||
{
|
||||
return (*b==0)?0:-1;
|
||||
}
|
||||
else if( *b == 0 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
int diff = towlower(*a)-towlower(*b);
|
||||
if( diff != 0 )
|
||||
return diff;
|
||||
else
|
||||
return wcsncasecmp( a+1,b+1, count-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCWIDTH
|
||||
int wcwidth( wchar_t c )
|
||||
{
|
||||
if( c < 32 )
|
||||
return 0;
|
||||
if ( c == 127 )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCSNDUP
|
||||
wchar_t *wcsndup( const wchar_t *in, int c )
|
||||
{
|
||||
wchar_t *res = malloc( sizeof(wchar_t)*(c+1) );
|
||||
if( res == 0 )
|
||||
{
|
||||
die_mem();
|
||||
}
|
||||
wcsncpy( res, in, c );
|
||||
res[c] = L'\0';
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
long convert_digit( wchar_t d, int base )
|
||||
{
|
||||
long res=-1;
|
||||
if( (d <= L'9') && (d >= L'0') )
|
||||
{
|
||||
res = d - L'0';
|
||||
}
|
||||
else if( (d <= L'z') && (d >= L'a') )
|
||||
{
|
||||
res = d + 10 - L'a';
|
||||
}
|
||||
else if( (d <= L'Z') && (d >= L'A') )
|
||||
{
|
||||
res = d + 10 - L'A';
|
||||
}
|
||||
if( res >= base )
|
||||
{
|
||||
res = -1;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifndef HAVE_WCSTOL
|
||||
long wcstol(const wchar_t *nptr,
|
||||
wchar_t **endptr,
|
||||
int base)
|
||||
{
|
||||
long long res=0;
|
||||
int is_set=0;
|
||||
if( base > 36 )
|
||||
{
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
long nxt = convert_digit( *nptr, base );
|
||||
if( endptr != 0 )
|
||||
*endptr = (wchar_t *)nptr;
|
||||
if( nxt < 0 )
|
||||
{
|
||||
if( !is_set )
|
||||
{
|
||||
errno = EINVAL;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
res = (res*base)+nxt;
|
||||
is_set = 1;
|
||||
if( res > LONG_MAX )
|
||||
{
|
||||
errno = ERANGE;
|
||||
return LONG_MAX;
|
||||
}
|
||||
if( res < LONG_MIN )
|
||||
{
|
||||
errno = ERANGE;
|
||||
return LONG_MIN;
|
||||
}
|
||||
nptr++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
149
wutil.h
149
wutil.h
@@ -1,8 +1,8 @@
|
||||
/** \file wutil.h
|
||||
|
||||
Prototypes for wide character equivalents of various standard unix
|
||||
functions.
|
||||
|
||||
functions. Also contains fallback implementations of a large number
|
||||
of wide character unix functions.
|
||||
*/
|
||||
#ifndef FISH_WUTIL_H
|
||||
#define FISH_WUTIL_H
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
/**
|
||||
Call this function on startup to create internal wutil
|
||||
@@ -81,8 +81,15 @@ wchar_t *wgetcwd( wchar_t *buff, size_t sz );
|
||||
*/
|
||||
int wchdir( const wchar_t * dir );
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#if !HAVE_WPRINTF
|
||||
#if !HAVE_FWPRINTF
|
||||
|
||||
/**
|
||||
Print formated string. Some operating systems (Like NetBSD) do not
|
||||
@@ -112,7 +119,141 @@ int swprintf( wchar_t *str, size_t l, const wchar_t *format, ... );
|
||||
*/
|
||||
int wprintf( const wchar_t *format, ... );
|
||||
|
||||
/**
|
||||
Print formated string. Some operating systems (Like NetBSD) do not
|
||||
have wide string formating functions. Therefore we define our
|
||||
own. Not at all complete. Supports wide and narrow characters,
|
||||
strings and decimal numbers, position (%n), field width and
|
||||
precision.
|
||||
*/
|
||||
int vwprintf( const wchar_t *filter, va_list va );
|
||||
|
||||
/**
|
||||
Print formated string. Some operating systems (Like NetBSD) do not
|
||||
have wide string formating functions. Therefore we define our
|
||||
own. Not at all complete. Supports wide and narrow characters,
|
||||
strings and decimal numbers, position (%n), field width and
|
||||
precision.
|
||||
*/
|
||||
int vfwprintf( FILE *f, const wchar_t *filter, va_list va );
|
||||
|
||||
/**
|
||||
Print formated string. Some operating systems (Like NetBSD) do not
|
||||
have wide string formating functions. Therefore we define our
|
||||
own. Not at all complete. Supports wide and narrow characters,
|
||||
strings and decimal numbers, position (%n), field width and
|
||||
precision.
|
||||
*/
|
||||
int vswprintf( wchar_t *out, size_t n, const wchar_t *filter, va_list va );
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FGETWC
|
||||
|
||||
/**
|
||||
Fallback implementation of fgetwc
|
||||
*/
|
||||
wint_t fgetwc(FILE *stream);
|
||||
|
||||
/**
|
||||
Fallback implementation of getwc
|
||||
*/
|
||||
wint_t getwc(FILE *stream);
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FPUTWC
|
||||
|
||||
/**
|
||||
Fallback implementation of fputwc
|
||||
*/
|
||||
wint_t fputwc(wchar_t wc, FILE *stream);
|
||||
/**
|
||||
Fallback implementation of putwc
|
||||
*/
|
||||
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
|
||||
|
||||
/**
|
||||
Return the number of columns used by a character. This is a libc
|
||||
function, but the prototype for this function is missing in some libc
|
||||
implementations.
|
||||
|
||||
Fish has a fallback implementation in case the implementation is
|
||||
missing altogether. In locales without a native wcwidth, Unicode
|
||||
is probably so broken that it isn't worth trying to implement a
|
||||
real wcwidth. Therefore, the fallback wcwidth assumes any printing
|
||||
character takes up one column and anything else uses 0 columns.
|
||||
*/
|
||||
int wcwidth( wchar_t c );
|
||||
|
||||
/**
|
||||
Create a duplicate string. Wide string version of strdup. Will
|
||||
automatically exit if out of memory.
|
||||
*/
|
||||
wchar_t *wcsdup(const wchar_t *in);
|
||||
|
||||
size_t wcslen(const wchar_t *in);
|
||||
|
||||
/**
|
||||
Case insensitive string compare function. Wide string version of
|
||||
strcasecmp.
|
||||
|
||||
This implementation of wcscasecmp does not take into account
|
||||
esoteric locales where uppercase and lowercase do not cleanly
|
||||
transform between each other. Hopefully this should be fine since
|
||||
fish only uses this function with one of the strings supplied by
|
||||
fish and guaranteed to be a sane, english word. Using wcscasecmp on
|
||||
a user-supplied string should be considered a bug.
|
||||
*/
|
||||
int wcscasecmp( const wchar_t *a, const wchar_t *b );
|
||||
|
||||
/**
|
||||
Case insensitive string compare function. Wide string version of
|
||||
strncasecmp.
|
||||
|
||||
This implementation of wcsncasecmp does not take into account
|
||||
esoteric locales where uppercase and lowercase do not cleanly
|
||||
transform between each other. Hopefully this should be fine since
|
||||
fish only uses this function with one of the strings supplied by
|
||||
fish and guaranteed to be a sane, english word. Using wcsncasecmp on
|
||||
a user-supplied string should be considered a bug.
|
||||
*/
|
||||
int wcsncasecmp( const wchar_t *a, const wchar_t *b, int count );
|
||||
|
||||
/**
|
||||
Returns a newly allocated wide character string wich is a copy of
|
||||
the string in, but of length c or shorter. The returned string is
|
||||
always null terminated, and the null is not included in the string
|
||||
length.
|
||||
*/
|
||||
wchar_t *wcsndup( const wchar_t *in, int c );
|
||||
|
||||
/**
|
||||
Converts from wide char to digit in the specified base. If d is not
|
||||
a valid digit in the specified base, return -1.
|
||||
*/
|
||||
long convert_digit( wchar_t d, int base );
|
||||
|
||||
/**
|
||||
Fallback implementation. Convert a wide character string to a
|
||||
number in the specified base. This functions is the wide character
|
||||
string equivalent of strtol. For bases of 10 or lower, 0..9 are
|
||||
used to represent numbers. For bases below 36, a-z and A-Z are used
|
||||
to represent numbers higher than 9. Higher bases than 36 are not
|
||||
supported.
|
||||
*/
|
||||
long wcstol(const wchar_t *nptr,
|
||||
wchar_t **endptr,
|
||||
int base);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user