mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-27 16:51:15 -03:00
Compare commits
86 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b044b785a | ||
|
|
ddff3561e3 | ||
|
|
c4dfdfa849 | ||
|
|
08251dcc98 | ||
|
|
57d53c70e3 | ||
|
|
4e77ee4516 | ||
|
|
6291be256b | ||
|
|
e756f7d619 | ||
|
|
cf3d30d4e4 | ||
|
|
585191310b | ||
|
|
530bbfc9ac | ||
|
|
a521fa4165 | ||
|
|
0f76f77173 | ||
|
|
c743ebf211 | ||
|
|
04ce9ecf16 | ||
|
|
bde5921258 | ||
|
|
89ae02976f | ||
|
|
d8382acc74 | ||
|
|
749c44fe27 | ||
|
|
88ec924323 | ||
|
|
7ff069a2e1 | ||
|
|
8e05c8bee8 | ||
|
|
0fa3c15114 | ||
|
|
58667673d9 | ||
|
|
a53a9aa293 | ||
|
|
09402223e8 | ||
|
|
4f947015d2 | ||
|
|
9f3a7543aa | ||
|
|
7ae6805698 | ||
|
|
1401c44a79 | ||
|
|
40ea5987b2 | ||
|
|
6920f039eb | ||
|
|
ff00354305 | ||
|
|
f9c63a142b | ||
|
|
3733fe3997 | ||
|
|
7e3128f097 | ||
|
|
727472d5bd | ||
|
|
3616a23bdd | ||
|
|
f13262d87e | ||
|
|
f71cd494de | ||
|
|
264c065006 | ||
|
|
07c89c71d8 | ||
|
|
19c67db731 | ||
|
|
294da72d11 | ||
|
|
847b6daa34 | ||
|
|
807a0b8dbd | ||
|
|
c3a1473419 | ||
|
|
29707e66e6 | ||
|
|
a97b652046 | ||
|
|
91b46b305d | ||
|
|
fbe66f54aa | ||
|
|
ff03fe7e41 | ||
|
|
06fd1aa9f8 | ||
|
|
5942a6d6c1 | ||
|
|
a781736fb7 | ||
|
|
feabc032f6 | ||
|
|
9f9f7bf95a | ||
|
|
02f638ad2b | ||
|
|
e95effb043 | ||
|
|
7a1a5a6f01 | ||
|
|
bfefe7f262 | ||
|
|
44e8dcd331 | ||
|
|
3580811f8e | ||
|
|
35cf20640f | ||
|
|
eff36003db | ||
|
|
0eab394c24 | ||
|
|
028e1f36a1 | ||
|
|
f59e9baab9 | ||
|
|
1c6f685522 | ||
|
|
c8a36c9889 | ||
|
|
521d09b6d0 | ||
|
|
3efb0bf5cf | ||
|
|
003c4d776f | ||
|
|
00dea8a082 | ||
|
|
7f195b2f23 | ||
|
|
ecc2fbca98 | ||
|
|
631acd529d | ||
|
|
369f1709be | ||
|
|
1505cc3d81 | ||
|
|
78ae6d3bea | ||
|
|
ea81321ccb | ||
|
|
1977d3beb3 | ||
|
|
285984196d | ||
|
|
5f8e6c85e4 | ||
|
|
e01ccb14af | ||
|
|
86b7ae6d21 |
31
INSTALL
31
INSTALL
@@ -2,39 +2,38 @@
|
||||
Known issues
|
||||
============
|
||||
|
||||
Older versions of Doxygen has bugs in the man-page generation which
|
||||
cause the builtin help to render incorrectly. Version 1.2.14 is known
|
||||
to have this problem.
|
||||
Fish currently requires a semi-modern GCC version to
|
||||
compile. Specifically, GCC 2.95.* won't compile fish, but GCC 3.23
|
||||
should work. Fish has not been coded with an C99- or GNU-specific
|
||||
features in mind, so it is hoped that it should be possible to make
|
||||
fish work with other compilers. Patches are welcome.
|
||||
|
||||
In version 1.9.2, the installation prefix for fish rpms and debs has
|
||||
changed from /usr/local to /usr. The package should automatically
|
||||
change any instances of /usr/local/bin/fish in /etc/passwd to
|
||||
/usr/bin/fish, but some programs, like screen, may need to be
|
||||
restarted to notice the changes. You may also run into problems when
|
||||
switching between using a package and personal builds.
|
||||
Older versions of Doxygen has bugs in the man-page generation which
|
||||
cause the builtin help to render incorrectly. Doxygen 1.2.14 is known
|
||||
to have this problem.
|
||||
|
||||
|
||||
Prerequisites
|
||||
=============
|
||||
|
||||
Fish requires the following packages to build:
|
||||
Fish requires the following programs and libraries to build:
|
||||
|
||||
- Doxygen
|
||||
- Curses or Ncurses
|
||||
- GNU make
|
||||
- GCC
|
||||
|
||||
fish also relies on standard unix tools such as cat, cut, grep, sed,
|
||||
whoami and echo. Fish does not support cross-compilation, separate
|
||||
build directories or any other fancy configure options. Use a recent
|
||||
version of Doxygen, since older versions have bugs that make the
|
||||
builtin help pages render incorrectly. Version 1.2.14 is known to be
|
||||
broken.
|
||||
whoami, bc and echo. Fish does not yet support cross-compilation,
|
||||
separate build directories or any other fancy configure options.
|
||||
|
||||
|
||||
Simple install procedure
|
||||
========================
|
||||
|
||||
If you have downloaded the darcs repository of fish, you need to run
|
||||
autoconf.
|
||||
the autoconf command first. Then use the following commands to compile
|
||||
fish:
|
||||
|
||||
% ./configure
|
||||
% make # Compile fish
|
||||
|
||||
32
Makefile.in
32
Makefile.in
@@ -16,6 +16,10 @@
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
|
||||
#
|
||||
# @configure_input@
|
||||
#
|
||||
|
||||
#
|
||||
# Makefile for the fish shell. Can build fish and associated
|
||||
# applications, install them, recalculate dependencies and also create
|
||||
@@ -33,9 +37,9 @@ CC := @CC@
|
||||
INSTALL:=@INSTALL@
|
||||
|
||||
# Compiler flags
|
||||
CFLAGS := @CFLAGS@ @INCLUDEDIR@ -Wall -std=gnu99 -fno-strict-aliasing
|
||||
CFLAGS:=@CFLAGS@ -Wall -std=gnu99 -fno-strict-aliasing
|
||||
CPPFLAGS=@CPPFLAGS@
|
||||
LDFLAGS:= -l@CURSESLIB@ @LIBS@ @LDFLAGS@ @LIBDIR@
|
||||
LDFLAGS:= @LIBS@ @LDFLAGS@
|
||||
|
||||
# Installation directories
|
||||
prefix = @prefix@
|
||||
@@ -61,7 +65,8 @@ COMMON_OBJS := function.o builtin.o common.o complete.o env.o exec.o \
|
||||
expand.o highlight.o history.o kill.o parser.o proc.o reader.o \
|
||||
sanity.o tokenizer.o util.o wildcard.o wgetopt.o wutil.o input.o \
|
||||
output.o intern.o env_universal.o env_universal_common.o \
|
||||
input_common.o event.o signal.o io.o translate.o
|
||||
input_common.o event.o signal.o io.o translate.o parse_util.o \
|
||||
halloc.o
|
||||
|
||||
# builtin_help.h exists, but builtin_help.c is autogenerated
|
||||
COMMON_OBJS_WITH_HEADER := builtin_help.o
|
||||
@@ -77,7 +82,7 @@ FISH_OBJS := $(COMMON_OBJS) $(COMMON_OBJS_WITH_CODE) \
|
||||
# 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
|
||||
translate.o halloc.o
|
||||
|
||||
# All objects that the system needs to build fish_tests
|
||||
FISH_TESTS_OBJS := $(COMMON_OBJS) $(COMMON_OBJS_WITH_CODE) \
|
||||
@@ -85,11 +90,11 @@ FISH_TESTS_OBJS := $(COMMON_OBJS) $(COMMON_OBJS_WITH_CODE) \
|
||||
|
||||
# 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
|
||||
doc_src/fishd.o halloc.o
|
||||
|
||||
# All objects needed to build mimedb
|
||||
MIME_OBJS := mimedb.o xdgmimealias.o xdgmime.o xdgmimeglob.o \
|
||||
xdgmimeint.o xdgmimemagic.o xdgmimeparent.o wutil.o
|
||||
xdgmimeint.o xdgmimemagic.o xdgmimeparent.o wutil.o halloc.o
|
||||
|
||||
#
|
||||
# Files containing documentation for builtins. Should be listed
|
||||
@@ -119,12 +124,13 @@ 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/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
|
||||
CMD_DOC_SRC := doc_src/contains.txt doc_src/count.txt doc_src/dirh.txt \
|
||||
doc_src/dirs.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)
|
||||
@@ -187,7 +193,7 @@ all: $(PROGRAMS) user_doc
|
||||
.PHONY: all
|
||||
|
||||
debug:
|
||||
make fish CFLAGS="-O0 -Wno-unused -Werror -g @INCLUDEDIR@ -Wall -std=gnu99 -fno-strict-aliasing"
|
||||
make fish CFLAGS="-O0 -Wno-unused -Werror -g -Wall -std=gnu99 -fno-strict-aliasing"
|
||||
.PHONY: debug
|
||||
|
||||
# User documentation, describing the features of the fish shell.
|
||||
|
||||
@@ -159,6 +159,8 @@ int builtin_ulimit(wchar_t **argv);
|
||||
*/
|
||||
int builtin_complete(wchar_t **argv);
|
||||
|
||||
const wchar_t *builtin_complete_get_temporary_buffer();
|
||||
|
||||
/**
|
||||
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
|
||||
|
||||
@@ -24,6 +24,7 @@ Functions used for implementing the commandline builtin.
|
||||
#include "input_common.h"
|
||||
#include "input.h"
|
||||
#include "translate.h"
|
||||
#include "parse_util.h"
|
||||
|
||||
/**
|
||||
Which part of the comandbuffer are we operating on
|
||||
@@ -48,6 +49,26 @@ enum
|
||||
}
|
||||
;
|
||||
|
||||
/**
|
||||
Returns the current commandline buffer.
|
||||
*/
|
||||
static const wchar_t *get_buffer()
|
||||
{
|
||||
const wchar_t *buff = builtin_complete_get_temporary_buffer();
|
||||
if( !buff )
|
||||
buff = reader_get_buffer();
|
||||
return buff;
|
||||
}
|
||||
|
||||
static int get_cursor_pos()
|
||||
{
|
||||
const wchar_t *buff = builtin_complete_get_temporary_buffer();
|
||||
if( buff )
|
||||
return wcslen( buff );
|
||||
else
|
||||
return reader_get_cursor_pos();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Replace/append/insert the selection with/at/after the specified string.
|
||||
@@ -57,14 +78,14 @@ enum
|
||||
\param insert the string to insert
|
||||
\param append_mode can be one of REPLACE_MODE, INSERT_MODE or APPEND_MODE, affects the way the test update is performed
|
||||
*/
|
||||
static void replace_part( wchar_t *begin,
|
||||
wchar_t *end,
|
||||
static void replace_part( const wchar_t *begin,
|
||||
const wchar_t *end,
|
||||
wchar_t *insert,
|
||||
int append_mode )
|
||||
{
|
||||
wchar_t *buff = reader_get_buffer();
|
||||
const wchar_t *buff = get_buffer();
|
||||
string_buffer_t out;
|
||||
int out_pos=reader_get_cursor_pos();
|
||||
int out_pos=get_cursor_pos();
|
||||
|
||||
sb_init( &out );
|
||||
|
||||
@@ -88,7 +109,7 @@ static void replace_part( wchar_t *begin,
|
||||
}
|
||||
case INSERT_MODE:
|
||||
{
|
||||
int cursor = reader_get_cursor_pos() -(begin-buff);
|
||||
int cursor = get_cursor_pos() -(begin-buff);
|
||||
sb_append_substring( &out, begin, cursor );
|
||||
sb_append( &out, insert );
|
||||
sb_append_substring( &out, begin+cursor, end-begin-cursor );
|
||||
@@ -109,8 +130,8 @@ static void replace_part( wchar_t *begin,
|
||||
\param cut_at_cursor whether printing should stop at the surrent cursor position
|
||||
\param tokenize whether the string should be tokenized, printing one string token on every line and skipping non-string tokens
|
||||
*/
|
||||
static void write_part( wchar_t *begin,
|
||||
wchar_t *end,
|
||||
static void write_part( const wchar_t *begin,
|
||||
const wchar_t *end,
|
||||
int cut_at_cursor,
|
||||
int tokenize )
|
||||
{
|
||||
@@ -119,7 +140,7 @@ static void write_part( wchar_t *begin,
|
||||
wchar_t *buff;
|
||||
int pos;
|
||||
|
||||
pos = reader_get_cursor_pos()-(begin-reader_get_buffer());
|
||||
pos = get_cursor_pos()-(begin-get_buffer());
|
||||
|
||||
if( tokenize )
|
||||
{
|
||||
@@ -184,7 +205,7 @@ int builtin_commandline( wchar_t **argv )
|
||||
|
||||
int tokenize = 0;
|
||||
|
||||
if( !reader_get_buffer() )
|
||||
if( !get_buffer() )
|
||||
{
|
||||
sb_append2( sb_err,
|
||||
argv[0],
|
||||
@@ -429,32 +450,42 @@ int builtin_commandline( wchar_t **argv )
|
||||
buffer_part = STRING_MODE;
|
||||
}
|
||||
|
||||
wchar_t *begin, *end;
|
||||
const wchar_t *begin, *end;
|
||||
|
||||
switch( buffer_part )
|
||||
{
|
||||
case STRING_MODE:
|
||||
{
|
||||
begin = reader_get_buffer();
|
||||
begin = get_buffer();
|
||||
end = begin+wcslen(begin);
|
||||
break;
|
||||
}
|
||||
|
||||
case PROCESS_MODE:
|
||||
{
|
||||
reader_current_process_extent( &begin, &end );
|
||||
parse_util_process_extent( get_buffer(),
|
||||
get_cursor_pos(),
|
||||
&begin,
|
||||
&end );
|
||||
break;
|
||||
}
|
||||
|
||||
case JOB_MODE:
|
||||
{
|
||||
reader_current_job_extent( &begin, &end );
|
||||
parse_util_job_extent( get_buffer(),
|
||||
get_cursor_pos(),
|
||||
&begin,
|
||||
&end );
|
||||
break;
|
||||
}
|
||||
|
||||
case TOKEN_MODE:
|
||||
{
|
||||
reader_current_token_extent( &begin, &end, 0, 0 );
|
||||
parse_util_token_extent( get_buffer(),
|
||||
get_cursor_pos(),
|
||||
&begin,
|
||||
&end,
|
||||
0, 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,11 @@ Functions used for implementing the complete builtin.
|
||||
#include "complete.h"
|
||||
#include "wgetopt.h"
|
||||
#include "parser.h"
|
||||
#include "reader.h"
|
||||
#include "translate.h"
|
||||
|
||||
const static wchar_t *temporary_buffer;
|
||||
|
||||
/*
|
||||
builtin_complete_* are a set of rather silly looping functions that
|
||||
make sure that all the proper combinations of complete_add or
|
||||
@@ -235,6 +238,11 @@ static void builtin_complete_remove( array_list_t *cmd,
|
||||
}
|
||||
|
||||
|
||||
const wchar_t *builtin_complete_get_temporary_buffer()
|
||||
{
|
||||
return temporary_buffer;
|
||||
}
|
||||
|
||||
int builtin_complete( wchar_t **argv )
|
||||
{
|
||||
int res=0;
|
||||
@@ -247,9 +255,18 @@ int builtin_complete( wchar_t **argv )
|
||||
array_list_t gnu_opt, old_opt;
|
||||
wchar_t *comp=L"", *desc=L"", *condition=L"", *load=0;
|
||||
|
||||
wchar_t *do_complete = 0;
|
||||
|
||||
array_list_t cmd;
|
||||
array_list_t path;
|
||||
|
||||
static int recursion_level=0;
|
||||
|
||||
if( !is_interactive_session )
|
||||
{
|
||||
debug( 1, _(L"%ls: Command only available in interactive sessions"), argv[0] );
|
||||
}
|
||||
|
||||
al_init( &cmd );
|
||||
al_init( &path );
|
||||
sb_init( &short_opt );
|
||||
@@ -320,6 +337,10 @@ int builtin_complete( wchar_t **argv )
|
||||
L"load", required_argument, 0, 'y'
|
||||
}
|
||||
,
|
||||
{
|
||||
L"do-complete", required_argument, 0, 'C'
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
@@ -330,7 +351,7 @@ int builtin_complete( wchar_t **argv )
|
||||
|
||||
int opt = wgetopt_long( argc,
|
||||
argv,
|
||||
L"a:c:p:s:l:o:d:frxeun:y:",
|
||||
L"a:c:p:s:l:o:d:frxeun:y:C:",
|
||||
long_options,
|
||||
&opt_index );
|
||||
if( opt == -1 )
|
||||
@@ -410,8 +431,11 @@ int builtin_complete( wchar_t **argv )
|
||||
case 'y':
|
||||
load = woptarg;
|
||||
break;
|
||||
|
||||
|
||||
case 'C':
|
||||
do_complete = woptarg?woptarg:reader_get_buffer();
|
||||
break;
|
||||
|
||||
case '?':
|
||||
// builtin_print_help( argv[0], sb_err );
|
||||
|
||||
@@ -424,6 +448,40 @@ int builtin_complete( wchar_t **argv )
|
||||
|
||||
if( res != 0 )
|
||||
{
|
||||
}
|
||||
else if( do_complete )
|
||||
{
|
||||
array_list_t comp;
|
||||
int i;
|
||||
|
||||
const wchar_t *prev_temporary_buffer = temporary_buffer;
|
||||
temporary_buffer = do_complete;
|
||||
|
||||
if( recursion_level < 1 )
|
||||
{
|
||||
recursion_level++;
|
||||
|
||||
|
||||
al_init( &comp );
|
||||
|
||||
complete( do_complete, &comp );
|
||||
|
||||
for( i=0; i<al_get_count( &comp ); i++ )
|
||||
{
|
||||
wchar_t *next = (wchar_t *)al_get( &comp, i );
|
||||
wchar_t *sep = wcschr( next, COMPLETE_SEP );
|
||||
if( sep )
|
||||
*sep = L'\t';
|
||||
sb_printf( sb_out, L"%ls\n", next );
|
||||
}
|
||||
|
||||
al_foreach( &comp, (void (*)(const void *))&free );
|
||||
al_destroy( &comp );
|
||||
recursion_level--;
|
||||
}
|
||||
|
||||
temporary_buffer = prev_temporary_buffer;
|
||||
|
||||
}
|
||||
else if( woptind != argc )
|
||||
{
|
||||
|
||||
@@ -509,9 +509,6 @@ int builtin_set( wchar_t **argv )
|
||||
!erase &&
|
||||
!list )
|
||||
{
|
||||
/*
|
||||
Only update the variable scope
|
||||
*/
|
||||
env_set( name, 0, scope );
|
||||
finished = 1;
|
||||
}
|
||||
|
||||
181
common.c
181
common.c
@@ -58,11 +58,7 @@ parts of fish.
|
||||
#include "proc.h"
|
||||
#include "wildcard.h"
|
||||
#include "parser.h"
|
||||
|
||||
/**
|
||||
Error message to show on string convertion error
|
||||
*/
|
||||
#define STR2WCS_MSG "fish: Invalid multibyte sequence \'"
|
||||
#include "halloc.h"
|
||||
|
||||
/**
|
||||
The maximum number of minor errors to report. Further errors will be omitted.
|
||||
@@ -120,18 +116,20 @@ void common_destroy()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
wchar_t **list_to_char_arr( array_list_t *l )
|
||||
wchar_t **list_to_char_arr( void *context, array_list_t *l )
|
||||
{
|
||||
wchar_t ** res = malloc( sizeof(wchar_t *)*(al_get_count( l )+1) );
|
||||
wchar_t ** res = halloc( context, sizeof(wchar_t *)*(al_get_count( l )+1) );
|
||||
int i;
|
||||
if( res == 0 )
|
||||
{
|
||||
die_mem();
|
||||
}
|
||||
for( i=0; i<al_get_count( l ); i++ )
|
||||
{
|
||||
res[i] = (wchar_t *)al_get(l,i);
|
||||
if( context )
|
||||
halloc_register( context, res[i] );
|
||||
}
|
||||
res[i]='\0';
|
||||
return res;
|
||||
}
|
||||
@@ -255,38 +253,51 @@ void sort_list( array_list_t *comp )
|
||||
|
||||
wchar_t *str2wcs( const char *in )
|
||||
{
|
||||
wchar_t *res;
|
||||
wchar_t *out;
|
||||
size_t res=0;
|
||||
int in_pos=0;
|
||||
int out_pos = 0;
|
||||
size_t len = strlen(in);
|
||||
mbstate_t state;
|
||||
|
||||
res = malloc( sizeof(wchar_t)*(strlen(in)+1) );
|
||||
out = malloc( sizeof(wchar_t)*(len+1) );
|
||||
memset( &state, 0, sizeof(state) );
|
||||
|
||||
if( !res )
|
||||
if( !out )
|
||||
{
|
||||
die_mem();
|
||||
}
|
||||
|
||||
if( (size_t)-1 == mbstowcs( res, in, sizeof(wchar_t)*(strlen(in)) +1) )
|
||||
|
||||
while( in[in_pos] )
|
||||
{
|
||||
error_count++;
|
||||
if( error_count <=error_max )
|
||||
res = mbrtowc( &out[out_pos], &in[in_pos], len-in_pos, &state );
|
||||
|
||||
switch( res )
|
||||
{
|
||||
fflush( stderr );
|
||||
write( 2,
|
||||
STR2WCS_MSG,
|
||||
strlen(STR2WCS_MSG) );
|
||||
write( 2,
|
||||
in,
|
||||
strlen(in ));
|
||||
write( 2,
|
||||
"\'\n",
|
||||
2 );
|
||||
case (size_t)(-2):
|
||||
case (size_t)(-1):
|
||||
{
|
||||
out[out_pos] = ENCODE_DIRECT_BASE + (unsigned char)in[in_pos];
|
||||
in_pos++;
|
||||
memset( &state, 0, sizeof(state) );
|
||||
break;
|
||||
}
|
||||
|
||||
case 0:
|
||||
{
|
||||
return out;
|
||||
}
|
||||
default:
|
||||
{
|
||||
in_pos += res;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(res);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return res;
|
||||
out_pos++;
|
||||
}
|
||||
out[out_pos] = 0;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void error_reset()
|
||||
@@ -296,20 +307,51 @@ void error_reset()
|
||||
|
||||
char *wcs2str( const wchar_t *in )
|
||||
{
|
||||
char *res = malloc( MAX_UTF8_BYTES*wcslen(in)+1 );
|
||||
char *out;
|
||||
size_t res=0;
|
||||
int in_pos=0;
|
||||
int out_pos = 0;
|
||||
mbstate_t state;
|
||||
|
||||
out = malloc( MAX_UTF8_BYTES*wcslen(in)+1 );
|
||||
memset( &state, 0, sizeof(state) );
|
||||
|
||||
if( res == 0 )
|
||||
if( !out )
|
||||
{
|
||||
die_mem();
|
||||
}
|
||||
|
||||
wcstombs( res,
|
||||
in,
|
||||
MAX_UTF8_BYTES*wcslen(in)+1 );
|
||||
|
||||
res = realloc( res, strlen( res )+1 );
|
||||
|
||||
return res;
|
||||
while( in[in_pos] )
|
||||
{
|
||||
if( ( in[in_pos] >= ENCODE_DIRECT_BASE) &&
|
||||
( in[in_pos] < ENCODE_DIRECT_BASE+256) )
|
||||
{
|
||||
out[out_pos++] = in[in_pos]- ENCODE_DIRECT_BASE;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = wcrtomb( &out[out_pos], in[in_pos], &state );
|
||||
|
||||
switch( res )
|
||||
{
|
||||
case (size_t)(-1):
|
||||
{
|
||||
debug( 1, L"Wide character has no narrow representation" );
|
||||
memset( &state, 0, sizeof(state) );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
out_pos += res;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
in_pos++;
|
||||
}
|
||||
out[out_pos] = 0;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
char **wcsv2strv( const wchar_t **in )
|
||||
@@ -534,25 +576,7 @@ int my_wcswidth( const wchar_t *c )
|
||||
|
||||
wchar_t *quote_end( const wchar_t *in )
|
||||
{
|
||||
switch( *in )
|
||||
{
|
||||
case '"':
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
in = wcschr( in+1, L'"' );
|
||||
if( !in )
|
||||
return 0;
|
||||
if( *(in-1) != L'\\' )
|
||||
return (wchar_t *)in;
|
||||
}
|
||||
}
|
||||
case '\'':
|
||||
{
|
||||
return wcschr( in+1, L'\'' );
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return wcschr( in+1, *in );
|
||||
}
|
||||
|
||||
|
||||
@@ -752,6 +776,26 @@ wchar_t *escape( const wchar_t *in,
|
||||
|
||||
while( *in != 0 )
|
||||
{
|
||||
|
||||
if( ( *in >= ENCODE_DIRECT_BASE) &&
|
||||
( *in < ENCODE_DIRECT_BASE+256) )
|
||||
{
|
||||
int val = *in - ENCODE_DIRECT_BASE;
|
||||
int tmp;
|
||||
|
||||
*(pos++) = L'\\';
|
||||
*(pos++) = L'X';
|
||||
|
||||
tmp = val/16;
|
||||
*pos++ = tmp > 9? L'a'+(tmp-10):L'0'+tmp;
|
||||
|
||||
tmp = val%16;
|
||||
*pos++ = tmp > 9? L'a'+(tmp-10):L'0'+tmp;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
switch( *in )
|
||||
{
|
||||
case L'\t':
|
||||
@@ -820,6 +864,8 @@ wchar_t *escape( const wchar_t *in,
|
||||
*pos++ = *in;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
in++;
|
||||
}
|
||||
*pos = 0;
|
||||
@@ -892,6 +938,7 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special )
|
||||
break;
|
||||
}
|
||||
|
||||
case L'X':
|
||||
case L'u':
|
||||
case L'U':
|
||||
case L'x':
|
||||
@@ -901,7 +948,9 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special )
|
||||
wchar_t res=0;
|
||||
int chars=2;
|
||||
int base=16;
|
||||
|
||||
|
||||
int byte = 0;
|
||||
|
||||
switch( in[in_pos] )
|
||||
{
|
||||
case L'u':
|
||||
@@ -925,6 +974,14 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special )
|
||||
break;
|
||||
}
|
||||
|
||||
case L'X':
|
||||
{
|
||||
byte=1;
|
||||
base=16;
|
||||
chars=2;
|
||||
break;
|
||||
}
|
||||
|
||||
case L'o':
|
||||
{
|
||||
base=8;
|
||||
@@ -947,7 +1004,7 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special )
|
||||
|
||||
}
|
||||
|
||||
in[out_pos] = res;
|
||||
in[out_pos] = (byte?ENCODE_DIRECT_BASE:0)+res;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
18
common.h
18
common.h
@@ -8,6 +8,8 @@
|
||||
*/
|
||||
#define FISH_COMMON_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
#include <termios.h>
|
||||
|
||||
@@ -42,6 +44,11 @@ typedef char tputs_arg_t;
|
||||
*/
|
||||
#define FISH_COLOR_RESET -2
|
||||
|
||||
/**
|
||||
This is in the unicode private use area.
|
||||
*/
|
||||
#define ENCODE_DIRECT_BASE 0xf000
|
||||
|
||||
/**
|
||||
Save the shell mode on startup so we can restore them on exit
|
||||
*/
|
||||
@@ -76,9 +83,12 @@ extern wchar_t *program_name;
|
||||
|
||||
/**
|
||||
Take an array_list_t containing wide strings and converts them to a
|
||||
single null-terminated wchar_t **.
|
||||
single null-terminated wchar_t **. The array is allocated using
|
||||
halloc, and uses the \c context parameter as context. If \c context
|
||||
is not noll, all elements of the \c array_list_t are also
|
||||
registered to \c context using \c halloc_register().
|
||||
*/
|
||||
wchar_t **list_to_char_arr( array_list_t *l );
|
||||
wchar_t **list_to_char_arr( void *context, array_list_t *l );
|
||||
|
||||
/**
|
||||
Read a line from the stream f into the buffer buff of length len. If
|
||||
@@ -172,8 +182,8 @@ int my_wcswidth( const wchar_t *c );
|
||||
|
||||
/**
|
||||
This functions returns the end of the quoted substring beginning at
|
||||
\c in. It can handle both single and double quotes. Returns 0 on
|
||||
error.
|
||||
\c in. The type of quoting character is detemrined by examining \c
|
||||
in. Returns 0 on error.
|
||||
|
||||
\param in the position of the opening quote
|
||||
*/
|
||||
|
||||
422
complete.c
422
complete.c
File diff suppressed because it is too large
Load Diff
86
configure.ac
86
configure.ac
@@ -1,17 +1,50 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(fish,1.20.0,fish-users@lists.sf.net)
|
||||
AC_INIT(fish,1.20.2,fish-users@lists.sf.net)
|
||||
|
||||
for i in /usr/pkg /sw /opt /opt/local; do
|
||||
|
||||
AC_MSG_CHECKING([for $i/include include directory])
|
||||
if test -d $i/include; then
|
||||
AC_MSG_RESULT(yes)
|
||||
CPPFLAGS="$CPPFLAGS -I$i/include/"
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for $i/lib library directory])
|
||||
if test -d $i/lib; then
|
||||
AC_MSG_RESULT(yes)
|
||||
LDFLAGS="$LDFLAGS -L$i/lib/ -R$i/lib/"
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for $i/bin command directory])
|
||||
if test -d $i/bin; then
|
||||
AC_MSG_RESULT(yes)
|
||||
optbindirs="$optbindirs $i/bin"
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
AC_SUBST( optbindirs, $optbindirs )
|
||||
|
||||
# If needed, run autoheader automatically
|
||||
AC_MSG_CHECKING([if autoheader needs to be run])
|
||||
if test ! -f ./config.h.in -o config.h.in -ot configure.ac; then
|
||||
AC_MSG_RESULT([yes])
|
||||
if which autoheader >/dev/null; then
|
||||
echo running autoheader...
|
||||
AC_MSG_NOTICE([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
|
||||
AC_MSG_ERROR( [cannot find the autoheader program in your path.
|
||||
This program is needed because the configure.ac file has been modified.
|
||||
Please install it and try again.])
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
# Tell autoconf to create config.h header
|
||||
@@ -26,10 +59,9 @@ AC_PROG_INSTALL
|
||||
AC_CHECK_PROG( has_doxygen, [doxygen], "true")
|
||||
|
||||
if ! test $has_doxygen = "true"; then
|
||||
echo Could not find the Doxygen program in your path.
|
||||
echo This program is needed to build fish.
|
||||
echo Please install it and try again.
|
||||
exit 1
|
||||
AC_MSG_ERROR( [cannot find the Doxygen program in your path.
|
||||
This program is needed to build fish.
|
||||
Please install it and try again.])
|
||||
fi
|
||||
|
||||
# Check for seq program. If missing, install fallback shellscript implementation
|
||||
@@ -93,10 +125,6 @@ AC_SUBST( [LOCALEDIR], [$datadir/locale])
|
||||
# See if Linux procfs is present
|
||||
AC_CHECK_FILES([/proc/self/stat])
|
||||
|
||||
# See if NetBSD pkgsrc is installed
|
||||
AC_CHECK_FILE([/usr/pkg/lib],[AC_SUBST(LIBDIR,[-L/usr/pkg/lib\ -R/usr/pkg/lib])])
|
||||
AC_CHECK_FILE([/usr/pkg/include],[AC_SUBST(INCLUDEDIR,[-I/usr/pkg/include])])
|
||||
|
||||
# Check for RLIMIT_AS in sys/resource.h.
|
||||
AC_MSG_CHECKING([for RLIMIT_AS in sys/resource.h])
|
||||
AC_TRY_COMPILE([#include <sys/resource.h>],
|
||||
@@ -146,6 +174,24 @@ else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
# Check if realpath accepts null for its second argument
|
||||
AC_MSG_CHECKING([if realpath accepts null for its second argument])
|
||||
AC_RUN_IFELSE(
|
||||
[AC_LANG_PROGRAM([#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>],
|
||||
[int status; char *res; res = realpath( "somefile", 0 ); status = !(res != 0 || errno == ENOENT); exit( status );])],
|
||||
[have_realpath_null=yes],
|
||||
[have_realpath_null=no] )
|
||||
|
||||
if test "$have_realpath_null" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([HAVE_REALPATH_NULL], [1],
|
||||
[Define to 1 if realpath accepts null for its second argument.])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
|
||||
# Check for libraries
|
||||
AC_CHECK_LIB(socket, connect)
|
||||
@@ -165,6 +211,9 @@ AC_CHECK_FUNCS( wcsdup wcsndup wcslen wcscasecmp wcsncasecmp gettext fwprintf )
|
||||
AC_CHECK_FUNCS( futimes wcwidth wcswidth getopt_long wcstok fputwc fgetwc )
|
||||
AC_CHECK_FUNCS( wcstol dcgettext )
|
||||
|
||||
AC_DEFINE([HAVE_TRANSLATE_H], [1],
|
||||
[Define to 1 if the wgettext function should be used for translating strings.])
|
||||
|
||||
# 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) )
|
||||
|
||||
@@ -174,7 +223,7 @@ 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)
|
||||
[int tmp = _nl_msg_cat_cntr; exit(tmp);], 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],
|
||||
@@ -184,12 +233,7 @@ else
|
||||
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])])
|
||||
|
||||
# Force use of ncurses if it is avialable via NetBSD pkgsrc. This is an
|
||||
# ugly kludge to force NetBSD to use ncurses, since NetBSDs own version
|
||||
# does not properly support terminfo.
|
||||
AC_CHECK_FILE([/usr/pkg/include/ncurses.h],[AC_SUBST(CURSESLIB,[ncurses]) AC_DEFINE(HAVE_NCURSES_H)])
|
||||
AC_SEARCH_LIBS( setupterm, [ncurses curses], [ AC_MSG_NOTICE([Found curses implementation])], [AC_MSG_ERROR([Could not find a curses implementation, needed to build 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
|
||||
|
||||
@@ -43,6 +43,10 @@ Other switches
|
||||
that they will be returned to the reader before any additional
|
||||
actual keypresses are read.
|
||||
|
||||
If commandline is called during a call to complete a given string
|
||||
using <code>complete -C STRING</code>, commandline will consider the
|
||||
specified string to be the current contents of the commandline.
|
||||
|
||||
\subsection commandline-example Example
|
||||
|
||||
<tt>commandline -j $history[3]</tt>
|
||||
|
||||
@@ -14,6 +14,7 @@ the fish manual.
|
||||
- <tt>LONG_OPTION</tt> is a multi character option for the command
|
||||
- <tt>OPTION_ARGUMENTS</tt> is parameter containing a space-separated list of possible option-arguments, which may contain subshells
|
||||
- <tt>DESCRIPTION</tt> is a description of what the option and/or option arguments do
|
||||
- <tt>-C STRING</tt> or <tt>--do-complete=STRING</tt> makes complete try to find all possible completions for the specified string
|
||||
- <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> 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.
|
||||
@@ -31,8 +32,8 @@ options, the same styles as the GNU version of the getopt
|
||||
library. These styles are:
|
||||
|
||||
- Short options, like '-a'. Short options are a single character long, are preceded by a single hyphen and may be grouped together (like '-la', which is equivalent to '-l -a'). Option arguments may be specified in the following parameter ('-w 32') or by appending the option with the value ('-w32').
|
||||
- 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').
|
||||
- Old style long options, like '-Wall'. Old style long options can be 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 can be 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').
|
||||
|
||||
The options for specifying command name, command path, or command
|
||||
switches may all be used multiple times to specify multiple commands
|
||||
|
||||
24
doc_src/contains.txt
Normal file
24
doc_src/contains.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
\section contains contains - Test if a word is present in a list
|
||||
|
||||
\subsection contains-synopsis Synopsis
|
||||
<code>contains [OPTIONS] KEY [VALUES...]</code>
|
||||
|
||||
\subsection contains-description Description
|
||||
|
||||
- \c -h or \c --help display this message
|
||||
|
||||
Test if the set VALUES contains the string KEY. Return status is 0 if
|
||||
yes, 1 otherwise
|
||||
|
||||
|
||||
\subsection contains-example Example
|
||||
<pre>
|
||||
for i in ~/bin /usr/local/bin
|
||||
if not contains \$i \$PATH
|
||||
set PATH \$PATH i
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
|
||||
The above code tests if ~/bin and /usr/local/bin are in the path and if they are not, they are added.
|
||||
188
doc_src/doc.hdr
188
doc_src/doc.hdr
@@ -6,7 +6,7 @@ This is the documentation for \c fish, the friendly interactive
|
||||
shell. \c fish is a user friendly commandline shell intended
|
||||
mostly for interactive use. A shell is a program used to execute other
|
||||
programs. For the latest information on \c fish, please visit the <a
|
||||
href="http://roo.no-ip.org/fish/"><tt>fish</tt> homepage</a>.
|
||||
href="http://roo.no-ip.org/fish/"><code>fish</code> homepage</a>.
|
||||
|
||||
\section syntax Syntax overview
|
||||
|
||||
@@ -18,7 +18,7 @@ any arguments.
|
||||
|
||||
Example:
|
||||
|
||||
<tt>echo hello world</tt>
|
||||
<code>echo hello world</code>
|
||||
|
||||
calls the \c echo command. \c echo is a command which will write its
|
||||
arguments to the screen. In the example above, the output will be
|
||||
@@ -31,7 +31,7 @@ syntax.
|
||||
If you wish to find out more about the echo command used above, read
|
||||
the manual page for the echo command by writing:
|
||||
|
||||
<tt>man echo</tt>
|
||||
<code>man echo</code>
|
||||
|
||||
\c man is a command for displaying a manual page on a given
|
||||
topic. There are manual pages for almost every command on most
|
||||
@@ -76,11 +76,11 @@ and vice versa.
|
||||
|
||||
Example:
|
||||
|
||||
<tt>rm "cumbersome filename.txt"</tt>
|
||||
<code>rm "cumbersome filename.txt"</code>
|
||||
|
||||
Will remove the file 'cumbersome filename.txt', while
|
||||
|
||||
<tt>rm cumbersome filename.txt</tt>
|
||||
<code>rm cumbersome filename.txt</code>
|
||||
|
||||
would remove the two files 'cumbersome' and 'filenmae.txt'.
|
||||
|
||||
@@ -89,31 +89,32 @@ would remove the two files 'cumbersome' and 'filenmae.txt'.
|
||||
Some characters can not be written directly on the command line. For
|
||||
these characters, so called escape sequences are provided. These are:
|
||||
|
||||
- <tt>'\\n'</tt>, escapes a newline character
|
||||
- <tt>'\\t'</tt>, escapes the tab character
|
||||
- <tt>'\\b'</tt>, escapes the backspace character
|
||||
- <tt>'\\r'</tt>, escapes the carriage return character
|
||||
- <tt>'\\e'</tt>, escapes the escape character
|
||||
- <tt>'\\ '</tt>, escapes the space character
|
||||
- <tt>'\\$'</tt>, escapes the dollar character
|
||||
- <tt>'\\\\'</tt>, escapes the backslash character
|
||||
- <tt>'\\*'</tt>, escapes the star character
|
||||
- <tt>'\\?'</tt>, escapes the question mark character
|
||||
- <tt>'\\~'</tt>, escapes the tilde character
|
||||
- <tt>'\\#'</tt>, escapes the hash character
|
||||
- <tt>'\\('</tt>, escapes the left parenthesis character
|
||||
- <tt>'\\)'</tt>, escapes the right parenthesis character
|
||||
- <tt>'\\{'</tt>, escapes the left curly bracket character
|
||||
- <tt>'\\}'</tt>, escapes the right curly bracket character
|
||||
- <tt>'\\['</tt>, escapes the left bracket character
|
||||
- <tt>'\\]'</tt>, escapes the right bracket character
|
||||
- <tt>'\\\<'</tt>, escapes the less than character
|
||||
- <tt>'\\\>'</tt>, escapes the more than character
|
||||
- <tt>'\\^'</tt>, escapes the circumflex character
|
||||
- <tt>'\\x<i>xx</i>'</tt>, where <tt><i>xx</i></tt> is a hexadecimal number, escapes the ascii character with the specified value
|
||||
- <tt>'\\o<i>ooo</i>'</tt>, where <tt><i>ooo</i></tt> is an octal number, escapes the ascii character with the specified value
|
||||
- <tt>'\\u<i>xxxx</i>'</tt>, where <tt><i>xxxx</i></tt> is a hexadecimal number, escapes the 16-bit unicode character with the specified value
|
||||
- <tt>'\\U<i>xxxxxxxx</i>'</tt>, where <tt><i>xxxxxxxx</i></tt> is a hexadecimal number, escapes the 32-bit unicode character with the specified value
|
||||
- <code>'\\n'</code>, escapes a newline character
|
||||
- <code>'\\t'</code>, escapes the tab character
|
||||
- <code>'\\b'</code>, escapes the backspace character
|
||||
- <code>'\\r'</code>, escapes the carriage return character
|
||||
- <code>'\\e'</code>, escapes the escape character
|
||||
- <code>'\\ '</code>, escapes the space character
|
||||
- <code>'\\$'</code>, escapes the dollar character
|
||||
- <code>'\\\\'</code>, escapes the backslash character
|
||||
- <code>'\\*'</code>, escapes the star character
|
||||
- <code>'\\?'</code>, escapes the question mark character
|
||||
- <code>'\\~'</code>, escapes the tilde character
|
||||
- <code>'\\#'</code>, escapes the hash character
|
||||
- <code>'\\('</code>, escapes the left parenthesis character
|
||||
- <code>'\\)'</code>, escapes the right parenthesis character
|
||||
- <code>'\\{'</code>, escapes the left curly bracket character
|
||||
- <code>'\\}'</code>, escapes the right curly bracket character
|
||||
- <code>'\\['</code>, escapes the left bracket character
|
||||
- <code>'\\]'</code>, escapes the right bracket character
|
||||
- <code>'\\\<'</code>, escapes the less than character
|
||||
- <code>'\\\>'</code>, escapes the more than character
|
||||
- <code>'\\^'</code>, escapes the circumflex character
|
||||
- <code>'\\x<i>xx</i>'</code>, where <code><i>xx</i></code> is a hexadecimal number, escapes the ascii character with the specified value
|
||||
- <code>'\\X<i>xx</i>'</code>, where <code><i>xx</i></code> is a hexadecimal number, escapes a byte of data with the specified value. If you are using a mutibyte encoding, this can be used to enter invalid strings. Only use this if you know what you are doing.
|
||||
- <code>'\\o<i>ooo</i>'</code>, where <code><i>ooo</i></code> is an octal number, escapes the ascii character with the specified value
|
||||
- <code>'\\u<i>xxxx</i>'</code>, where <code><i>xxxx</i></code> is a hexadecimal number, escapes the 16-bit unicode character with the specified value
|
||||
- <code>'\\U<i>xxxxxxxx</i>'</code>, where <code><i>xxxxxxxx</i></code> is a hexadecimal number, escapes the 32-bit unicode character with the specified value
|
||||
|
||||
\subsection redirects IO redirection
|
||||
|
||||
@@ -124,41 +125,41 @@ a number called a file descriptor (FD). These are:
|
||||
- Standard output, FD 1, for writing, defaults to writing to the screen.
|
||||
- Standard error, FD 2, for writing errors and warnings, defaults to writing to the screen.
|
||||
|
||||
The reason for providing for two methods of output is that errors and
|
||||
warnings can be separated from regular program output.
|
||||
The reason for providing for two output file descriptors is to allow
|
||||
separation of errors and warnings from regular program output.
|
||||
|
||||
Any file descriptor can be directed to a different output than it's
|
||||
default through a simple mechanism called a redirection.
|
||||
|
||||
An example of a file redirection is <tt> echo hello \>output.txt</tt>,
|
||||
An example of a file redirection is <code> echo hello \>output.txt</code>,
|
||||
which directs the output of the echo command to the file error.txt.
|
||||
|
||||
- To redirect standard input, write <tt>\<SOURCE_FILE</tt>
|
||||
- To redirect standard output, write <tt>\>DESTINATION</tt>
|
||||
- To redirect standard error, write <tt>^DESTINATION</tt>
|
||||
- To redirect standard output to a file which will be appended, write <tt>\>\>DESTINATION_FILE</tt>
|
||||
- To redirect standard error to a file which will be appended, write <tt>^^DESTINATION_FILE</tt>
|
||||
- To redirect standard input, write <code>\<SOURCE_FILE</code>
|
||||
- To redirect standard output, write <code>\>DESTINATION</code>
|
||||
- To redirect standard error, write <code>^DESTINATION</code>
|
||||
- To redirect standard output to a file which will be appended, write <code>\>\>DESTINATION_FILE</code>
|
||||
- To redirect standard error to a file which will be appended, write <code>^^DESTINATION_FILE</code>
|
||||
|
||||
<tt>DESTINATION</tt> can be one of the following:
|
||||
<code>DESTINATION</code> can be one of the following:
|
||||
|
||||
- A filename. The output will be written to the specified file.
|
||||
- An ampersand (\&) followed by the number of another file descriptor. The file descriptor will be a duplicate of the specified file descriptor.
|
||||
- A minus sign (-). The file descriptor will be closed.
|
||||
- An ampersand followed by a minus sign (\&-). The file descriptor will be closed.
|
||||
|
||||
Example:
|
||||
|
||||
To redirect both standard output and standard error to the file
|
||||
all_output.txt, you can write <tt>echo Hello \>all_output.txt
|
||||
^\&1</tt>.
|
||||
all_output.txt, you can write <code>echo Hello \>all_output.txt
|
||||
^\&1</code>.
|
||||
|
||||
Any FD can be redirected in an arbitrary way by prefixing the
|
||||
redirection with the number of the FD.
|
||||
|
||||
- To redirect input of FD number N, write <tt>N\<DESTINATION</tt>
|
||||
- To redirect output of FD number N, write <tt>N\>DESTINATION</tt>
|
||||
- To redirect output of FD number N to a file which will be appended, write <tt>N\>\>DESTINATION_FILE</tt>
|
||||
- To redirect input of FD number N, write <code>N\<DESTINATION</code>
|
||||
- To redirect output of FD number N, write <code>N\>DESTINATION</code>
|
||||
- To redirect output of FD number N to a file which will be appended, write <code>N\>\>DESTINATION_FILE</code>
|
||||
|
||||
Example: <tt>echo Hello 2\>-</tt> and <tt>echo Hello ^-</tt> are
|
||||
Example: <code>echo Hello 2\>-</code> and <code>echo Hello ^-</code> are
|
||||
equivalent.
|
||||
|
||||
\subsection piping Piping
|
||||
@@ -168,7 +169,7 @@ pipeline. This means that the standard output of one command will be read
|
||||
in as standard input into the next command. This is done by separating
|
||||
the commands by the pipe character (|). For example
|
||||
|
||||
<tt>cat foo.txt | head</tt>
|
||||
<code>cat foo.txt | head</code>
|
||||
|
||||
will call the 'cat' program with the parameter 'foo.txt', which will
|
||||
print the contents of the file 'foo.txt'. The contents of foo.txt will
|
||||
@@ -176,7 +177,7 @@ then be filtered through the program 'head', which will pass on the
|
||||
first ten lines of the file to the screen. For more information on how
|
||||
to combine commands through pipes, read the manual pages of the
|
||||
commands you want to use using the 'man' command. If you want to find
|
||||
out more about the 'cat' program, type <tt>man cat</tt>.
|
||||
out more about the 'cat' program, type <code>man cat</code>.
|
||||
|
||||
Pipes usually connect file descriptor 1 (standard output) of the first
|
||||
process to file descriptor 0 (standard input) of the second
|
||||
@@ -184,7 +185,7 @@ process. It is possible use a different output file descriptor by
|
||||
prepending the desired FD number and then output redirect symbol to
|
||||
the pipe. For example:
|
||||
|
||||
<tt>make fish 2>|less</tt>
|
||||
<code>make fish 2>|less</code>
|
||||
|
||||
will attempt to build the fish program, and any errors will be shown
|
||||
using the less pager.
|
||||
@@ -199,7 +200,6 @@ your command. This will tell fish to run the job in the background.
|
||||
|
||||
\subsection syntax-job-control Job control
|
||||
|
||||
|
||||
Most programs allow you to suspend the programs execution and return
|
||||
control to \c fish by Pressing ^Z (Press and hold the Control key and
|
||||
press 'z'). Once back at the \c fish commandline, you can start other
|
||||
@@ -219,7 +219,7 @@ href="builtins.html#jobs">jobs</a> command.
|
||||
This is a short explanation of some of the commonly used words in fish.
|
||||
|
||||
- argument, a parameter given to a command
|
||||
- builtin, a command that is implemented as part of the shell
|
||||
- builtin, a command that is implemented in the shell
|
||||
- command, a program
|
||||
- function, a block of one or more fish commands that can be called as a single command. By using functions, it is possible to string together multiple smaller commands into one more advanced command.
|
||||
- job, a running pipeline or command
|
||||
@@ -229,14 +229,14 @@ This is a short explanation of some of the commonly used words in fish.
|
||||
\section help Help
|
||||
|
||||
\c fish has an extensive help system. Use the <a
|
||||
href="commands.html#help"><tt>help</tt></a> command to obtain help on
|
||||
a specific subject or command. For instance, writing <tt>help
|
||||
syntax</tt> displays the <a href="#syntax">syntax section</a> of this
|
||||
href="commands.html#help"><code>help</code></a> command to obtain help on
|
||||
a specific subject or command. For instance, writing <code>help
|
||||
syntax</code> displays the <a href="#syntax">syntax section</a> of this
|
||||
documentation.
|
||||
|
||||
Help on a specific builtin can also be obtained with the <tt>-h</tt>
|
||||
Help on a specific builtin can also be obtained with the <code>-h</code>
|
||||
parameter. For instance, to obtain help on the \c fg builtin, either
|
||||
type <tt>fg -h</tt> or <tt>help fg</tt>.
|
||||
type <code>fg -h</code> or <code>help fg</code>.
|
||||
|
||||
|
||||
\section completion Tab completion
|
||||
@@ -282,11 +282,11 @@ Specifying your own completions is not complicated. To specify a
|
||||
completion, use the \c complete command. \c complete takes
|
||||
as a parameter the name of the command to specify a completion
|
||||
for. For example, to add a completion for the program \c myprog, one
|
||||
would start the completion command with <tt>complete -c myprog
|
||||
...</tt>. To provide a list of possible completions for myprog, use
|
||||
would start the completion command with <code>complete -c myprog
|
||||
...</code>. To provide a list of possible completions for myprog, use
|
||||
the \c -a switch. If \c myprog accepts the arguments start and stop,
|
||||
this can be specified as <tt>complete -c myprog -a 'start
|
||||
stop'</tt>. The argument to the \c -a switch is always a single
|
||||
this can be specified as <code>complete -c myprog -a 'start
|
||||
stop'</code>. The argument to the \c -a switch is always a single
|
||||
string. At completion time, it will be tokenized on spaces and tabs,
|
||||
and variable expansion, command substitution and other forms of
|
||||
parameter expansion will take place.
|
||||
@@ -299,7 +299,7 @@ respectively. If the command 'myprog' has an option '-o' which can
|
||||
also be written as '--output', and which can take an additional value
|
||||
of either 'yes' or 'no', this can be specified by writing:
|
||||
|
||||
<tt>complete -c myprog -s o -l output -a "yes no"</tt>
|
||||
<code>complete -c myprog -s o -l output -a "yes no"</code>
|
||||
|
||||
There are also special switches for specifying that a switch requires
|
||||
an argument, to disable filename completion, to create completions
|
||||
@@ -359,8 +359,8 @@ Example:
|
||||
The command <code>echo (basename image.jpg .jpg).png</code> will
|
||||
output 'image.png'.
|
||||
|
||||
The command <tt>for i in *.jpg; convert $i (basename $i .jpg).png;
|
||||
end</tt> will convert all Jpeg files in the current directory to the
|
||||
The command <code>for i in *.jpg; convert $i (basename $i .jpg).png;
|
||||
end</code> will convert all Jpeg files in the current directory to the
|
||||
PNG format.
|
||||
|
||||
|
||||
@@ -371,9 +371,9 @@ expanded so each element of the list becomes a new parameter.
|
||||
|
||||
Example:
|
||||
|
||||
<tt>echo input.{c,h,txt}</tt> outputs 'input.c input.h input.txt'
|
||||
<code>echo input.{c,h,txt}</code> outputs 'input.c input.h input.txt'
|
||||
|
||||
The command <tt>mv *.{c,h} src/</tt> moves all files with the suffix
|
||||
The command <code>mv *.{c,h} src/</code> moves all files with the suffix
|
||||
'.c' or '.h' to the subdirectory src.
|
||||
|
||||
\subsection expand-variable Variable expansion
|
||||
@@ -385,12 +385,12 @@ href="#variables"> Environment variables</a> section.
|
||||
|
||||
Example:
|
||||
|
||||
<tt> echo \$HOME</tt> prints the home directory of the current
|
||||
<code> echo \$HOME</code> prints the home directory of the current
|
||||
user.
|
||||
|
||||
If you wish to combine environment variables with text, you can
|
||||
encase the variables within braces to embed a variable inside running
|
||||
text like <tt>echo Konnichiwa {$USER}san</tt>, which will print a
|
||||
text like <code>echo Konnichiwa {$USER}san</code>, which will print a
|
||||
personalized Japanese greeting.
|
||||
|
||||
The {$USER}san syntax might need a bit of an elaboration. Posix
|
||||
@@ -451,11 +451,11 @@ take the process ids as an argument.
|
||||
|
||||
Example:
|
||||
|
||||
<tt>fg \%ema</tt> will search for a process whose command line begins
|
||||
<code>fg \%ema</code> will search for a process whose command line begins
|
||||
with the letters 'ema', such as emacs, and if found, put it in the
|
||||
foreground.
|
||||
|
||||
<tt>kill -s SIGINT \%3</tt> will send the SIGINT signal to the job
|
||||
<code>kill -s SIGINT \%3</code> will send the SIGINT signal to the job
|
||||
with job id 3.
|
||||
|
||||
\subsection combine Combining different expansions
|
||||
@@ -467,7 +467,7 @@ created.
|
||||
Example:
|
||||
|
||||
If the current directory contains the files 'foo' and 'bar', the command
|
||||
<tt>echo a(ls){1,2,3} </tt>
|
||||
<code>echo a(ls){1,2,3} </code>
|
||||
will output 'abar1 abar2 abar3 afoo1 afoo2 afoo3'.
|
||||
|
||||
|
||||
@@ -485,7 +485,7 @@ command</a>.
|
||||
Example:
|
||||
|
||||
To set the variable \c smurf to the value \c blue, use the command
|
||||
<tt>set smurf blue</tt>.
|
||||
<code>set smurf blue</code>.
|
||||
|
||||
After a variable has been set, you can use the value of a variable in
|
||||
the shell through <a href="expand-variable">variable expansion</a>.
|
||||
@@ -493,8 +493,8 @@ the shell through <a href="expand-variable">variable expansion</a>.
|
||||
Example:
|
||||
|
||||
To use the value of a the variable \c smurf, write $ (dollar symbol)
|
||||
followed by the name of the variable, like <tt>echo Smurfs are
|
||||
$smurf</tt>, which would print the result 'Smurfs are blue'.
|
||||
followed by the name of the variable, like <code>echo Smurfs are
|
||||
$smurf</code>, which would print the result 'Smurfs are blue'.
|
||||
|
||||
\subsection variables-scope Variable scope
|
||||
|
||||
@@ -503,7 +503,7 @@ local variables. Universal variables are shared between all fish
|
||||
sessions a user is running on one computer. Global variables are
|
||||
specific to the current fish session, but are not associated with any
|
||||
specific block scope, and will never be erased unless the user
|
||||
explicitly requests it using <tt>set -e</tt>. Local variables are
|
||||
explicitly requests it using <code>set -e</code>. Local variables are
|
||||
specific to the current fish session, and associated with a specific
|
||||
block of commands, and is automatically erased when a specific block
|
||||
goes out of scope. A block of commands is a series of commands that
|
||||
@@ -550,8 +550,8 @@ value once, and it will be automatically updated for all sessions, and
|
||||
preserved across computer reboots and login/logout.
|
||||
|
||||
To see universal variables in action, start two fish sessions side by
|
||||
side, and issue the following command in one of them <tt>set
|
||||
fish_color_cwd blue</tt>. Since \c fish_color_cwd is a universal
|
||||
side, and issue the following command in one of them <code>set
|
||||
fish_color_cwd blue</code>. Since \c fish_color_cwd is a universal
|
||||
variable, the color of the current working directory listing in the
|
||||
prompt will instantly change to blue on both terminals.
|
||||
|
||||
@@ -748,7 +748,7 @@ builtins or shellscript functions, and can only be used inside fish.
|
||||
- <a href="commands.html#umask">umask</a>, set or get the file creation mask
|
||||
- <a href="builtins.html#while">while</a>, perform a block of commands while a condition is met
|
||||
|
||||
For more information about these commands, use the <tt>--help</tt>
|
||||
For more information about these commands, use the <code>--help</code>
|
||||
option of the command to display a longer explanation.
|
||||
|
||||
\section editor Command Line editor
|
||||
@@ -781,7 +781,7 @@ You can change these key bindings by making an inputrc file. To do
|
||||
this, copy the file /etc/fish_inputrc to your home directory and
|
||||
rename it to '.fish_inputrc'. Now you can edit the file .fish_inputrc,
|
||||
to change your key bindings. The fileformat of this file is described
|
||||
in the manual page for readline. Use the command <tt>man readline</tt>
|
||||
in the manual page for readline. Use the command <code>man readline</code>
|
||||
to read up on this syntax. Please note that the list of key binding
|
||||
functions in fish is different to that offered by readline. Currently,
|
||||
the following functions are available:
|
||||
@@ -863,7 +863,7 @@ fish will be stopped until the program finishes. Sometimes this is not
|
||||
desirable. For example, you may wish to start an application with a
|
||||
graphical user interface from the terminal, and then be able to
|
||||
continue using the shell. In such cases, there are several ways in
|
||||
which the user can change <tt>fish</tt>'s behaviour.
|
||||
which the user can change <code>fish</code>'s behaviour.
|
||||
|
||||
-# By ending a command with the \& (ampersand) symbol, the user tells \c fish to put the specified command into the background. A background process will be run simultaneous with \c fish. \c fish will retain control of the terminal, so the program will not be able to read from the keyboard.
|
||||
-# By pressing ^Z, the user stops a currently running foreground program and returns control to \c fish. Some programs do not support this feature, or remap it to another key. Gnu emacs uses ^X z to stop running.
|
||||
@@ -875,13 +875,13 @@ On startup, \c fish evaluates the file /etc/fish (Or ~/etc/fish if you
|
||||
installed fish in your home directory) and ~/.fish, in that order. If
|
||||
you want to run a command only on starting an interactive shell, use
|
||||
the exit status of the command 'status --is-interactive' to determine
|
||||
if the shell is interactive. If you want to run a command only on
|
||||
starting a login shell, use 'status --is-login' instead.
|
||||
if the shell is interactive. If you want to run a command only when
|
||||
using a login shell, use 'status --is-login' instead.
|
||||
|
||||
Example:
|
||||
Examples:
|
||||
|
||||
If you want to add the directory ~/linux/bin to your PATH variable
|
||||
when loging in, add the following to your ~/.fish file:
|
||||
when using a login shell, add the following to your ~/.fish file:
|
||||
|
||||
<pre>if status --is-login
|
||||
set PATH $PATH ~/linux/bin
|
||||
@@ -891,7 +891,7 @@ If you want to run a set of commands when \c fish exits, use an <a
|
||||
href='#event'>event handler</a> that is triggered by the exit of the
|
||||
shell:
|
||||
|
||||
<pre>function on_exit --on-process %self
|
||||
<pre>function on_exit --on-process \%self
|
||||
echo fish is now exiting
|
||||
end</pre>
|
||||
|
||||
@@ -1056,10 +1056,10 @@ might become:
|
||||
|
||||
<pre>
|
||||
msgid "%ls: No suitable job\n"
|
||||
msgstr "%ls: Inget jobb matchar\n"
|
||||
msgstr "%ls: Inget passande jobb\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
|
||||
@@ -1411,7 +1411,7 @@ between different shell sessions and applications.
|
||||
|
||||
The open command uses the mimetype database (Also used by both Gnome
|
||||
or KDE) to launch the default application for a file. Just type
|
||||
<tt>open *.html</tt> and all the HTML files in your current directory
|
||||
<code>open *.html</code> and all the HTML files in your current directory
|
||||
will be opened in your default browser. No longer will you have to
|
||||
convert your filenames to URLS, remember clunky Open Office command
|
||||
names, worry about absolute paths or any the other common pitfalls when
|
||||
@@ -1421,10 +1421,10 @@ opening files from the commandline.
|
||||
|
||||
\c fish is heavily commented. Both the source code and the
|
||||
program in general features a great deal of easily accessible
|
||||
documentation. The <tt>help</tt> command is used to display HTML-based
|
||||
help files. Just type <tt>help</tt> and a subject, and the help system
|
||||
documentation. The <code>help</code> command is used to display HTML-based
|
||||
help files. Just type <code>help</code> and a subject, and the help system
|
||||
will try to fill your needs. To view the page you are reading right
|
||||
now, you could simply type <tt>help difference</tt>. <tt>help</tt>
|
||||
now, you could simply type <code>help difference</code>. <code>help</code>
|
||||
also works great together with tab completion. Write \c help and
|
||||
double tap on tab, a list of all help sections will be displayed, with
|
||||
a description of the content of each section.
|
||||
@@ -1475,9 +1475,9 @@ information.
|
||||
\subsection difference-simple Simplicity
|
||||
|
||||
\c fish has a simple syntax. There is only one form of
|
||||
alias/function/whatever, accessed through the <tt>function</tt>
|
||||
alias/function/whatever, accessed through the <code>function</code>
|
||||
builtin. The are very few builtins, \c fish relies on normal commands
|
||||
like <tt>echo</tt>, <tt>kill</tt>, <tt>printf</tt> and <tt>time</tt>
|
||||
like <code>echo</code>, <code>kill</code>, <code>printf</code> and <code>time</code>
|
||||
instead of reimplementing them as builtins.
|
||||
|
||||
Token separation is performed before variable expansion. This means
|
||||
@@ -1485,13 +1485,13 @@ that even if a variable contains spaces, it will never be separated
|
||||
into multiple arguments. If you want to tokenize a string, you can use
|
||||
the <a href="commands.html#tokenize">tokenize</a> command.
|
||||
|
||||
Command substitution is specified using parenthesis, as in <tt>set name (whoami)</tt>.
|
||||
Command substitution is specified using parenthesis, as in <code>set name (whoami)</code>.
|
||||
|
||||
There is no math mode, use bc.
|
||||
|
||||
The POSIX way of setting variables is <i>lame</i>. Whitespace
|
||||
sensitive languages are awful. "foo=bar" and "foo = bar" should not
|
||||
mean different things. \c fish uses a builtin, <tt>set</tt> to set and
|
||||
mean different things. \c fish uses a builtin, <code>set</code> to set and
|
||||
remove environment variables. While this may seem a bit obscure, this
|
||||
makes for a very consistent language. In fish, everything, including
|
||||
the loops, assignments and switch/case statements is a command.
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
\section nextd nextd
|
||||
|
||||
\subsection nextd-synopsis Synopsis
|
||||
<tt>nextd [-l] [pos]</tt>
|
||||
<tt>nextd [-l | --list] [pos]</tt>
|
||||
|
||||
\subsection nextd-description Description
|
||||
<tt>nextd</tt> moves forwards <tt>pos</tt> positions in the history of visited directories;
|
||||
if the end of the history has been hit, a warning is printed. If the <tt>-l></tt> flag is
|
||||
specified, the current history is also displayed.
|
||||
\subsection nextd-description Description <tt>nextd</tt> moves
|
||||
forwards <tt>pos</tt> positions in the history of visited directories;
|
||||
if the end of the history has been hit, a warning is printed. If the
|
||||
<code>-l></code> or <code>--list</code> flag is specified, the current
|
||||
history is also displayed.
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
\section prevd prevd
|
||||
|
||||
\subsection prevd-synopsis Synopsis
|
||||
<tt>prevd [-l] [pos]</tt>
|
||||
<tt>prevd [-l | --list] [pos]</tt>
|
||||
|
||||
\subsection prevd-description Description
|
||||
<tt>prevd</tt> moves backwards <tt>pos</tt> positions in the history of visited directories;
|
||||
if the beginning of the history has been hit, a warning is printed. If the <tt>-l</tt> flag
|
||||
is specified, the current history is also displayed.
|
||||
\subsection prevd-description Description <tt>prevd</tt> moves
|
||||
backwards <tt>pos</tt> positions in the history of visited
|
||||
directories; if the beginning of the history has been hit, a warning
|
||||
is printed. If the <code>-l</code> or <code>--list</code> flag is
|
||||
specified, the current history is also displayed.
|
||||
|
||||
@@ -27,8 +27,14 @@ If a variable is set to more than one value, the variable will be an
|
||||
array with the specified elements. If a variable is set to zero
|
||||
elements, it will become an array with zero elements.
|
||||
|
||||
If the variable name is one or more array elements, such as <code>PATH[1
|
||||
3 7]</code>, only those array elements specified will be changed.
|
||||
If the variable name is one or more array elements, such as
|
||||
<code>PATH[1 3 7]</code>, only those array elements specified will be
|
||||
changed.
|
||||
|
||||
The set command requires all switch arguments to come before any
|
||||
non-switch arguments. For example, <code>set flags -l</code> will have
|
||||
the effect of setting the value of the variable <code>flags</code> to
|
||||
'-l', not making the variable local.
|
||||
|
||||
\subsection set-example Example
|
||||
|
||||
|
||||
2
env.c
2
env.c
@@ -386,7 +386,7 @@ static void setup_path()
|
||||
path = env_get( L"PATH" );
|
||||
if( !path )
|
||||
{
|
||||
env_set( L"PATH", 0, ENV_EXPORT | ENV_GLOBAL | ENV_USER );
|
||||
env_set( L"PATH", 0, ENV_EXPORT | ENV_GLOBAL );
|
||||
path=0;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
client library and by the daemon.
|
||||
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
@@ -186,7 +188,7 @@ void read_message( connection_t *src )
|
||||
}
|
||||
else
|
||||
{
|
||||
sb_printf( &src->input, L"%lc", res );
|
||||
sb_append_char( &src->input, res );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
85
event.c
85
event.c
@@ -74,11 +74,15 @@ static array_list_t *killme;
|
||||
*/
|
||||
static array_list_t *blocked;
|
||||
|
||||
/**
|
||||
String buffer used for formating event descriptions in event_get_desc()
|
||||
*/
|
||||
static string_buffer_t *get_desc_buff=0;
|
||||
|
||||
/**
|
||||
Tests if one event instance matches the definition of a event
|
||||
class. If the class defines a function name, that will also be a
|
||||
match criterion.
|
||||
class. If both the class and the instance name a function,
|
||||
they must name the same function.
|
||||
|
||||
*/
|
||||
static int event_match( event_t *class, event_t *instance )
|
||||
@@ -186,6 +190,63 @@ static int event_is_blocked( event_t *e )
|
||||
return 0;
|
||||
}
|
||||
|
||||
const wchar_t *event_get_desc( event_t *e )
|
||||
{
|
||||
if( !get_desc_buff )
|
||||
{
|
||||
get_desc_buff=malloc(sizeof(string_buffer_t) );
|
||||
if( !get_desc_buff )
|
||||
die_mem();
|
||||
sb_init( get_desc_buff );
|
||||
}
|
||||
else
|
||||
{
|
||||
sb_clear( get_desc_buff );
|
||||
}
|
||||
|
||||
switch( e->type )
|
||||
{
|
||||
|
||||
case EVENT_SIGNAL:
|
||||
sb_printf( get_desc_buff, _(L"signal handler for %ls (%ls)"), sig2wcs(e->param1.signal ), signal_get_desc( e->param1.signal ) );
|
||||
break;
|
||||
|
||||
case EVENT_VARIABLE:
|
||||
sb_printf( get_desc_buff, _(L"handler for variable '%ls'"), e->param1.variable );
|
||||
break;
|
||||
|
||||
case EVENT_EXIT:
|
||||
if( e->param1.pid > 0 )
|
||||
{
|
||||
sb_printf( get_desc_buff, _(L"exit handler for process %d"), e->param1.pid );
|
||||
}
|
||||
else
|
||||
{
|
||||
job_t *j = job_get_from_pid( -e->param1.pid );
|
||||
if( j )
|
||||
sb_printf( get_desc_buff, _(L"exit handler for job %d, '%ls'"), j->job_id, j->command );
|
||||
else
|
||||
sb_printf( get_desc_buff, _(L"exit handler for job with process group %d"), -e->param1.pid );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case EVENT_JOB_ID:
|
||||
{
|
||||
job_t *j = job_get( e->param1.job_id );
|
||||
if( j )
|
||||
sb_printf( get_desc_buff, _(L"exit handler for job %d, '%ls'"), j->job_id, j->command );
|
||||
else
|
||||
sb_printf( get_desc_buff, _(L"exit handler for job with job id %d"), j->job_id );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return (const wchar_t *)get_desc_buff->buff;
|
||||
}
|
||||
|
||||
|
||||
void event_add_handler( event_t *event )
|
||||
{
|
||||
@@ -327,7 +388,7 @@ static void event_fire_internal( event_t *event )
|
||||
string_buffer_t *b=0;
|
||||
array_list_t *fire=0;
|
||||
|
||||
int was_subshell = is_subshell;
|
||||
int was_interactive = is_interactive;
|
||||
|
||||
/*
|
||||
First we free all events that have been removed
|
||||
@@ -403,15 +464,18 @@ static void event_fire_internal( event_t *event )
|
||||
Event handlers are not part of the main flow of code, so
|
||||
they are marked as non-interactive and as a subshell
|
||||
*/
|
||||
is_subshell=1;
|
||||
is_interactive=0;
|
||||
parser_push_block( EVENT );
|
||||
current_block->param1.event = event;
|
||||
eval( (wchar_t *)b->buff, 0, TOP );
|
||||
|
||||
parser_pop_block();
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Restore interactivity flags
|
||||
*/
|
||||
is_subshell = was_subshell;
|
||||
is_interactive = was_interactive;
|
||||
|
||||
if( b )
|
||||
{
|
||||
@@ -564,6 +628,7 @@ void event_init()
|
||||
|
||||
void event_destroy()
|
||||
{
|
||||
|
||||
if( events )
|
||||
{
|
||||
al_foreach( events, (void (*)(const void *))&event_free );
|
||||
@@ -571,6 +636,7 @@ void event_destroy()
|
||||
free( events );
|
||||
events=0;
|
||||
}
|
||||
|
||||
if( killme )
|
||||
{
|
||||
al_foreach( killme, (void (*)(const void *))&event_free );
|
||||
@@ -578,6 +644,13 @@ void event_destroy()
|
||||
free( killme );
|
||||
killme=0;
|
||||
}
|
||||
|
||||
if( get_desc_buff )
|
||||
{
|
||||
sb_destroy( get_desc_buff );
|
||||
free( get_desc_buff );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void event_free( event_t *e )
|
||||
|
||||
6
event.h
6
event.h
@@ -130,4 +130,10 @@ void event_destroy();
|
||||
*/
|
||||
void event_free( event_t *e );
|
||||
|
||||
/**
|
||||
Returns a string describing the specified event. The string should
|
||||
not be freed.
|
||||
*/
|
||||
const wchar_t *event_get_desc( event_t *e );
|
||||
|
||||
#endif
|
||||
|
||||
185
exec.c
185
exec.c
@@ -37,6 +37,7 @@
|
||||
#include "signal.h"
|
||||
#include "env_universal.h"
|
||||
#include "translate.h"
|
||||
#include "halloc.h"
|
||||
|
||||
/**
|
||||
Prototype for the getpgid library function. The prototype for this
|
||||
@@ -67,6 +68,8 @@ pid_t getpgid( pid_t pid );
|
||||
*/
|
||||
static array_list_t *open_fds=0;
|
||||
|
||||
static int set_child_group( job_t *j, process_t *p, int print_errors );
|
||||
|
||||
|
||||
void exec_close( int fd )
|
||||
{
|
||||
@@ -238,7 +241,7 @@ void free_fd( io_data_t *io, int fd )
|
||||
\param io the list of IO redirections for the child
|
||||
\param exit_on_error whether to call exit() on errors
|
||||
|
||||
\return 1 on sucess, 0 on failiure
|
||||
\return 0 on sucess, -1 on failiure
|
||||
*/
|
||||
static int handle_child_io( io_data_t *io, int exit_on_error )
|
||||
{
|
||||
@@ -283,7 +286,7 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if( tmp != io->fd)
|
||||
@@ -302,7 +305,7 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
exec_close( tmp );
|
||||
@@ -326,7 +329,7 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -349,7 +352,7 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -373,7 +376,7 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
|
||||
if( env_universal_server.fd >= 0 )
|
||||
exec_close( env_universal_server.fd );
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
@@ -387,41 +390,24 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
|
||||
\param j the job to set up the IO for
|
||||
\param p the child process to set up
|
||||
|
||||
\return 1 on sucess, 0 on failiure
|
||||
\return 0 on sucess, -1 on failiure
|
||||
*/
|
||||
static int setup_child_process( job_t *j, process_t *p )
|
||||
{
|
||||
int res;
|
||||
|
||||
if( j->terminal )
|
||||
{
|
||||
pid_t pid;
|
||||
/*
|
||||
Put the process into the process group and give the process
|
||||
group the terminal, if appropriate. This has to be done
|
||||
both by the shell and in the individual child processes
|
||||
because of potential race conditions.
|
||||
*/
|
||||
pid = getpid ();
|
||||
if (j->pgid == 0)
|
||||
j->pgid = pid;
|
||||
|
||||
/* Wait till shell puts os in our own group */
|
||||
while( getpgrp() != j->pgid )
|
||||
sleep(0);
|
||||
|
||||
/* Wait till shell gives us stdin */
|
||||
if ( j->fg )
|
||||
{
|
||||
while( tcgetpgrp( 0 ) != j->pgid )
|
||||
sleep(0);
|
||||
}
|
||||
int res=0;
|
||||
|
||||
if( p )
|
||||
{
|
||||
res = set_child_group( j, p, 1 );
|
||||
}
|
||||
|
||||
if( !res )
|
||||
{
|
||||
res = handle_child_io( j->io, (p==0) );
|
||||
}
|
||||
|
||||
res = handle_child_io( j->io, (p==0) );
|
||||
|
||||
/* Set the handling for job control signals back to the default. */
|
||||
if( res )
|
||||
if( !res )
|
||||
{
|
||||
signal_reset_handlers();
|
||||
}
|
||||
@@ -595,14 +581,22 @@ static void internal_exec_helper( const wchar_t *def,
|
||||
}
|
||||
|
||||
/**
|
||||
This function should be called by the parent process right after
|
||||
fork() has been called. If job control is enabled, the child is put
|
||||
in the jobs group.
|
||||
This function should be called by both the parent process and the
|
||||
child right after fork() has been called. If job control is
|
||||
enabled, the child is put in the jobs group, and if the child is
|
||||
also in the foreground, it is also given control of the
|
||||
terminal. When called in the parent process, this function may
|
||||
fail, since the child might have already finished and called
|
||||
exit. The parent process may safely ignore the exit status of this
|
||||
call.
|
||||
|
||||
Returns 0 on sucess, -1 on failiure.
|
||||
*/
|
||||
static int handle_new_child( job_t *j, process_t *p )
|
||||
static int set_child_group( job_t *j, process_t *p, int print_errors )
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
if( j->terminal )
|
||||
if( j->job_control )
|
||||
{
|
||||
int new_pgid=0;
|
||||
|
||||
@@ -614,7 +608,7 @@ static int handle_new_child( job_t *j, process_t *p )
|
||||
|
||||
if( setpgid (p->pid, j->pgid) )
|
||||
{
|
||||
if( getpgid( p->pid) != j->pgid )
|
||||
if( getpgid( p->pid) != j->pgid && print_errors )
|
||||
{
|
||||
debug( 1,
|
||||
_( L"Could not send process %d from group %d to group %d" ),
|
||||
@@ -622,38 +616,28 @@ static int handle_new_child( job_t *j, process_t *p )
|
||||
getpgid( p->pid),
|
||||
j->pgid );
|
||||
wperror( L"setpgid" );
|
||||
res = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if( j->fg )
|
||||
{
|
||||
if( tcsetpgrp (0, j->pgid) )
|
||||
{
|
||||
debug( 1, _( L"Could not send job %d ('%ls') to foreground" ),
|
||||
j->job_id,
|
||||
j->command );
|
||||
wperror( L"tcsetpgrp" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if( j->fg && new_pgid)
|
||||
{
|
||||
if( tcsetpgrp (0, j->pgid) )
|
||||
{
|
||||
debug( 1, _( L"Could not send job %d ('%ls') to foreground" ),
|
||||
j->job_id,
|
||||
j->command );
|
||||
wperror( L"tcsetpgrp" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
j->pgid = getpid();
|
||||
}
|
||||
return 0;
|
||||
|
||||
if( j->terminal && j->fg )
|
||||
{
|
||||
if( tcsetpgrp (0, j->pgid) && print_errors )
|
||||
{
|
||||
debug( 1, _( L"Could not send job %d ('%ls') to foreground" ),
|
||||
j->job_id,
|
||||
j->command );
|
||||
wperror( L"tcsetpgrp" );
|
||||
res = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -689,9 +673,10 @@ void exec( job_t *j )
|
||||
signal_block();
|
||||
|
||||
/*
|
||||
setup_child_process make sure signals are propelry set up
|
||||
setup_child_process make sure signals are properly set
|
||||
up. It will also call signal_unblock
|
||||
*/
|
||||
if( setup_child_process( j, 0 ) )
|
||||
if( !setup_child_process( j, 0 ) )
|
||||
{
|
||||
/*
|
||||
launch_process never returns
|
||||
@@ -722,9 +707,9 @@ void exec( job_t *j )
|
||||
if( block_io )
|
||||
{
|
||||
if( j->io )
|
||||
j->io = io_add( io_duplicate(block_io), j->io );
|
||||
j->io = io_add( io_duplicate( j, block_io), j->io );
|
||||
else
|
||||
j->io=io_duplicate(block_io);
|
||||
j->io=io_duplicate( j, block_io);
|
||||
}
|
||||
|
||||
j->io = io_add( j->io, &pipe_write );
|
||||
@@ -807,26 +792,18 @@ void exec( job_t *j )
|
||||
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] );
|
||||
wchar_t * def = halloc_register( j, wcsdup( function_get_definition( p->argv[0] )));
|
||||
//fwprintf( stderr, L"run function %ls\n", argv[0] );
|
||||
if( def == 0 )
|
||||
{
|
||||
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;
|
||||
current_block->param2.function_call_process = p;
|
||||
current_block->param1.function_name = halloc_register( current_block, wcsdup( p->argv[0] ) );
|
||||
|
||||
if( builtin_count_args(p->argv)>1 )
|
||||
{
|
||||
@@ -834,9 +811,6 @@ void exec( job_t *j )
|
||||
|
||||
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 );
|
||||
@@ -1016,7 +990,7 @@ void exec( job_t *j )
|
||||
if( !io_buffer )
|
||||
{
|
||||
/*
|
||||
No buffer, se we exit directly. This means we
|
||||
No buffer, so we exit directly. This means we
|
||||
have to manually set the exit status.
|
||||
*/
|
||||
if( p->next == 0 )
|
||||
@@ -1062,12 +1036,19 @@ void exec( job_t *j )
|
||||
it control over the terminal.
|
||||
*/
|
||||
p->pid = pid;
|
||||
if( handle_new_child( j, p ) )
|
||||
exit(1);
|
||||
|
||||
set_child_group( j, p, 0 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if( p->next == 0 )
|
||||
{
|
||||
proc_set_last_status( j->negate?(status?0:1):status);
|
||||
}
|
||||
p->completed = 1;
|
||||
}
|
||||
|
||||
io_buffer_destroy( io_buffer );
|
||||
|
||||
@@ -1154,9 +1135,8 @@ void exec( job_t *j )
|
||||
*/
|
||||
p->pid = pid;
|
||||
|
||||
if( handle_new_child( j, p ) )
|
||||
exit( 1 );
|
||||
|
||||
set_child_group( j, p, 0 );
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -1194,20 +1174,16 @@ void exec( job_t *j )
|
||||
*/
|
||||
p->pid = pid;
|
||||
|
||||
if( handle_new_child( j, p ) )
|
||||
exit( 1 );
|
||||
|
||||
|
||||
set_child_group( j, p, 0 );
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if( p->type == INTERNAL_BUILTIN )
|
||||
builtin_pop_io();
|
||||
|
||||
builtin_pop_io();
|
||||
|
||||
/*
|
||||
Close the pipe the current process uses to read from the previous process_t
|
||||
@@ -1312,15 +1288,8 @@ int exec_subshell( const wchar_t *cmd,
|
||||
{
|
||||
wchar_t *el;
|
||||
*end=0;
|
||||
el = str2wcs( begin );
|
||||
if( !el )
|
||||
{
|
||||
debug( 0, _( L"Subshell '%ls' returned illegal string, discarded one entry" ), cmd );
|
||||
}
|
||||
else
|
||||
{
|
||||
al_push( l, el );
|
||||
}
|
||||
el = str2wcs( begin );
|
||||
al_push( l, el );
|
||||
begin = end+1;
|
||||
break;
|
||||
}
|
||||
|
||||
39
expand.h
39
expand.h
@@ -143,31 +143,6 @@ int expand_string( wchar_t *in, array_list_t *out, int flag );
|
||||
*/
|
||||
wchar_t *expand_one( wchar_t *in, int flag );
|
||||
|
||||
/**
|
||||
Expand backslashed escapes and substitute them with their unescaped
|
||||
counterparts. Also optionally change the wildcards, the tilde
|
||||
character and a few more into constants which are defined in a
|
||||
private use area of Unicode. This assumes wchar_t is a unicode
|
||||
character. character set.
|
||||
|
||||
The result must be free()d. The original string is not modified. If
|
||||
an invalid sequence is specified, 0 is returned.
|
||||
|
||||
*/
|
||||
wchar_t *expand_unescape( const wchar_t * in, int escape_special );
|
||||
|
||||
/**
|
||||
Replace special characters with escape sequences. Newline is
|
||||
replaced with \n, etc.
|
||||
|
||||
The result must be free()d. The original string is not modified.
|
||||
|
||||
\param in The string to be escaped
|
||||
\param escape_all Whether all characters wich hold special meaning in fish (Pipe, semicolon, etc,) should be escaped, or only unprintable characters
|
||||
\return The escaped string
|
||||
*/
|
||||
wchar_t *expand_escape( const wchar_t *in, int escape_all );
|
||||
|
||||
/**
|
||||
Convert the variable value to a human readable form, i.e. escape things, handle arrays, etc. Suitable for pretty-printing.
|
||||
*/
|
||||
@@ -182,20 +157,6 @@ wchar_t *expand_escape_variable( const wchar_t *in );
|
||||
*/
|
||||
wchar_t *expand_tilde(wchar_t *in);
|
||||
|
||||
/**
|
||||
Locate the first subshell in the specified string.
|
||||
|
||||
\param in the string to search for subshells
|
||||
\param begin the starting paranthesis of the subshell
|
||||
\param end the ending paranthesis of the subshell
|
||||
\param flags set this variable to ACCEPT_INCOMPLETE if in tab_completion mode
|
||||
\return -1 on syntax error, 0 if no subshells exist and 1 on sucess
|
||||
*/
|
||||
int expand_locate_subshell( wchar_t *in,
|
||||
wchar_t **begin,
|
||||
wchar_t **end,
|
||||
int flags );
|
||||
|
||||
|
||||
/**
|
||||
Tokenize the specified string into the specified array_list_t.
|
||||
|
||||
151
fish_pager.c
151
fish_pager.c
@@ -412,54 +412,68 @@ static void printed_length( wchar_t *str,
|
||||
int has_description = 0;
|
||||
while( *str != 0 )
|
||||
{
|
||||
switch( *str )
|
||||
if( ( *str >= ENCODE_DIRECT_BASE) &&
|
||||
( *str < ENCODE_DIRECT_BASE+256) )
|
||||
{
|
||||
case L'\n':
|
||||
case L'\b':
|
||||
case L'\r':
|
||||
case L'\e':
|
||||
case L'\t':
|
||||
case L'\\':
|
||||
case L'&':
|
||||
case L'$':
|
||||
case L' ':
|
||||
case L'#':
|
||||
case L'^':
|
||||
case L'<':
|
||||
case L'>':
|
||||
case L'(':
|
||||
case L')':
|
||||
case L'[':
|
||||
case L']':
|
||||
case L'{':
|
||||
case L'}':
|
||||
case L'?':
|
||||
case L'*':
|
||||
case L'|':
|
||||
case L';':
|
||||
case L':':
|
||||
case L'\'':
|
||||
case L'"':
|
||||
case L'%':
|
||||
case L'~':
|
||||
|
||||
if( has_description )
|
||||
desc_len++;
|
||||
else
|
||||
comp_len+=2;
|
||||
break;
|
||||
if( has_description )
|
||||
desc_len+=4;
|
||||
else
|
||||
comp_len+=4;
|
||||
|
||||
case COMPLETE_SEP:
|
||||
has_description = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
if( has_description )
|
||||
desc_len+= wcwidth(*str);
|
||||
else
|
||||
comp_len+= wcwidth(*str);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
switch( *str )
|
||||
{
|
||||
case L'\n':
|
||||
case L'\b':
|
||||
case L'\r':
|
||||
case L'\e':
|
||||
case L'\t':
|
||||
case L'\\':
|
||||
case L'&':
|
||||
case L'$':
|
||||
case L' ':
|
||||
case L'#':
|
||||
case L'^':
|
||||
case L'<':
|
||||
case L'>':
|
||||
case L'(':
|
||||
case L')':
|
||||
case L'[':
|
||||
case L']':
|
||||
case L'{':
|
||||
case L'}':
|
||||
case L'?':
|
||||
case L'*':
|
||||
case L'|':
|
||||
case L';':
|
||||
case L':':
|
||||
case L'\'':
|
||||
case L'"':
|
||||
case L'%':
|
||||
case L'~':
|
||||
|
||||
if( has_description )
|
||||
desc_len++;
|
||||
else
|
||||
comp_len+=2;
|
||||
break;
|
||||
|
||||
case COMPLETE_SEP:
|
||||
has_description = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
if( has_description )
|
||||
desc_len+= wcwidth(*str);
|
||||
else
|
||||
comp_len+= wcwidth(*str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
str++;
|
||||
}
|
||||
if( has_description )
|
||||
@@ -550,7 +564,7 @@ static int completion_try_print( int cols,
|
||||
memset( pref_width, 0, sizeof(pref_width) );
|
||||
memset( min_width, 0, sizeof(min_width) );
|
||||
|
||||
/* Calculated how wide the list would be */
|
||||
/* Calculate how wide the list would be */
|
||||
for( j = 0; j < cols; j++ )
|
||||
{
|
||||
for( i = 0; i<rows; i++ )
|
||||
@@ -800,7 +814,7 @@ static void mangle_descriptions( array_list_t *l )
|
||||
{
|
||||
wchar_t *next = (wchar_t *)al_get(l, i);
|
||||
wchar_t *in, *out;
|
||||
skip=0;
|
||||
skip=1;
|
||||
|
||||
while( *next != COMPLETE_SEP && *next )
|
||||
next++;
|
||||
@@ -851,7 +865,11 @@ static void init()
|
||||
struct sigaction act;
|
||||
program_name = L"fish_pager";
|
||||
wsetlocale( LC_ALL, L"" );
|
||||
|
||||
|
||||
/*
|
||||
Make fd 1 output to screen, and use some other fd for writing
|
||||
the resulting output back to the caller
|
||||
*/
|
||||
int out = dup( 1 );
|
||||
close(1);
|
||||
if( open( ttyname(0), O_WRONLY ) != 1 )
|
||||
@@ -863,6 +881,10 @@ static void init()
|
||||
}
|
||||
}
|
||||
out_file = fdopen( out, "w" );
|
||||
|
||||
/**
|
||||
Init the stringbuffer used to keep any output in
|
||||
*/
|
||||
sb_init( &out_buff );
|
||||
|
||||
output_init();
|
||||
@@ -880,33 +902,6 @@ static void init()
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Loop until we are in the foreground. */
|
||||
while (tcgetpgrp( 0 ) != getpid())
|
||||
{
|
||||
kill (- getpid(), SIGTTIN);
|
||||
}
|
||||
|
||||
/* Put ourselves in our own process group. */
|
||||
if( getpgrp() != getpid() )
|
||||
{
|
||||
if (setpgid (getpid(), getpid()) < 0)
|
||||
{
|
||||
debug( 1,
|
||||
L"Couldn't put the shell in its own process group");
|
||||
wperror( L"setpgid" );
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Grab control of the terminal. */
|
||||
if( tcsetpgrp (STDIN_FILENO, getpid()) )
|
||||
{
|
||||
debug( 1,
|
||||
L"Couldn't grab control of terminal" );
|
||||
wperror( L"tcsetpgrp" );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
handle_winch( 0 ); /* Set handler for window change events */
|
||||
|
||||
tcgetattr(0,&pager_modes); /* get the current terminal modes */
|
||||
@@ -968,7 +963,11 @@ int main( int argc, char **argv )
|
||||
|
||||
for( i=3; i<argc; i++ )
|
||||
{
|
||||
al_push( &comp, str2wcs( argv[i] ) );
|
||||
wchar_t *wcs = str2wcs( argv[i] );
|
||||
if( wcs )
|
||||
{
|
||||
al_push( &comp, wcs );
|
||||
}
|
||||
}
|
||||
|
||||
mangle_descriptions( &comp );
|
||||
|
||||
38
function.c
38
function.c
@@ -18,6 +18,7 @@
|
||||
#include "intern.h"
|
||||
#include "event.h"
|
||||
#include "reader.h"
|
||||
#include "parse_util.h"
|
||||
|
||||
|
||||
/**
|
||||
@@ -65,18 +66,6 @@ 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,
|
||||
@@ -86,16 +75,14 @@ void function_add( const wchar_t *name,
|
||||
{
|
||||
int i;
|
||||
wchar_t *cmd_end;
|
||||
function_data_t *d;
|
||||
|
||||
|
||||
if( function_exists( name ) )
|
||||
function_remove( 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 = malloc( sizeof( function_data_t ) );
|
||||
d->definition_offset = parse_util_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 ) )
|
||||
{
|
||||
@@ -104,7 +91,8 @@ void function_add( const wchar_t *name,
|
||||
|
||||
d->desc = desc?wcsdup( desc ):0;
|
||||
d->is_binding = is_binding;
|
||||
d->definition_file = reader_current_filename()?intern(reader_current_filename()):0;
|
||||
d->definition_file = intern(reader_current_filename());
|
||||
|
||||
hash_put( &function, intern(name), d );
|
||||
|
||||
for( i=0; i<al_get_count( events ); i++ )
|
||||
@@ -123,20 +111,20 @@ void function_remove( const wchar_t *name )
|
||||
{
|
||||
void *key;
|
||||
function_data_t *d;
|
||||
|
||||
event_t ev;
|
||||
ev.type=EVENT_ANY;
|
||||
ev.function_name=name;
|
||||
event_remove( &ev );
|
||||
|
||||
hash_remove( &function,
|
||||
name,
|
||||
(const void **) &key,
|
||||
(const void **)&d );
|
||||
|
||||
if( !d )
|
||||
if( !key )
|
||||
return;
|
||||
|
||||
ev.type=EVENT_ANY;
|
||||
ev.function_name=name;
|
||||
event_remove( &ev );
|
||||
|
||||
clear_function_entry( key, d );
|
||||
}
|
||||
|
||||
|
||||
78
halloc.c
Normal file
78
halloc.c
Normal file
@@ -0,0 +1,78 @@
|
||||
/** \file halloc.c
|
||||
|
||||
A hierarchical memory allocation system. Works just like talloc
|
||||
used in Samba, except that an arbitrary block allocated with
|
||||
malloc() can be registered to be freed by halloc_free.
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "common.h"
|
||||
#include "halloc.h"
|
||||
|
||||
typedef struct halloc
|
||||
{
|
||||
array_list_t children;
|
||||
array_list_t hchildren;
|
||||
long long data[0];
|
||||
}
|
||||
halloc_t;
|
||||
|
||||
static halloc_t *halloc_from_data( void *data )
|
||||
{
|
||||
return (halloc_t *)(data - sizeof( halloc_t ) );
|
||||
}
|
||||
|
||||
|
||||
void *halloc( void *context, size_t size )
|
||||
{
|
||||
|
||||
halloc_t *me, *parent;
|
||||
|
||||
me = (halloc_t *)calloc( 1, sizeof(halloc_t) + size );
|
||||
|
||||
if( !me )
|
||||
return 0;
|
||||
|
||||
al_init( &me->children );
|
||||
|
||||
if( context )
|
||||
{
|
||||
parent = halloc_from_data( context );
|
||||
al_push( &parent->hchildren, &me->data );
|
||||
}
|
||||
|
||||
return &me->data;
|
||||
}
|
||||
|
||||
void *halloc_register( void *context, void *data )
|
||||
{
|
||||
halloc_t *me;
|
||||
if( !context )
|
||||
return data;
|
||||
|
||||
me = halloc_from_data( context );
|
||||
al_push( &me->children, data );
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
void halloc_free( void *context )
|
||||
{
|
||||
halloc_t *me;
|
||||
if( !context )
|
||||
return;
|
||||
|
||||
me = halloc_from_data( context );
|
||||
al_foreach( &me->hchildren, (void (*)(const void *))&halloc_free );
|
||||
al_foreach( &me->children, (void (*)(const void *))&free );
|
||||
al_destroy( &me->children );
|
||||
al_destroy( &me->hchildren );
|
||||
free(me);
|
||||
}
|
||||
|
||||
35
halloc.h
Normal file
35
halloc.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/** \file halloc.h
|
||||
|
||||
A hierarchical memory allocation system. Works just like talloc
|
||||
used in Samba, except that an arbitrary block allocated with
|
||||
malloc() can be registered to be freed by halloc_free.
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
Allocate new memory using specified parent memory context. If \c
|
||||
context is null, a new root context is created. Context _must_ be
|
||||
either 0 or the result of a previous call to halloc.
|
||||
|
||||
If \c context is null, the resulting block must be freed with a
|
||||
call to halloc_free().
|
||||
|
||||
If \c context is not null, the resulting memory block must never be
|
||||
explicitly freed, it will be automatically freed whenever the
|
||||
parent context is freed.
|
||||
*/
|
||||
void *halloc( void *context, size_t size );
|
||||
|
||||
/**
|
||||
Free memory context and all children contexts. Only root contexts
|
||||
may be freed explicitly.
|
||||
*/
|
||||
void halloc_free( void *context );
|
||||
|
||||
/**
|
||||
Free the memory pointed to by \c data when the memory pointed to by
|
||||
\c context is free:d. Note that this will _not_ turn the specified
|
||||
memory area into a valid halloc context. Only memory areas created
|
||||
using a call to halloc() can be used as a context.
|
||||
*/
|
||||
void *halloc_register( void *context, void *data );
|
||||
11
highlight.c
11
highlight.c
@@ -18,6 +18,7 @@
|
||||
#include "tokenizer.h"
|
||||
#include "proc.h"
|
||||
#include "parser.h"
|
||||
#include "parse_util.h"
|
||||
#include "builtin.h"
|
||||
#include "function.h"
|
||||
#include "env.h"
|
||||
@@ -365,11 +366,11 @@ void highlight_shell( wchar_t * buff,
|
||||
while( 1 )
|
||||
{
|
||||
wchar_t *begin, *end;
|
||||
|
||||
if( expand_locate_subshell( subpos,
|
||||
&begin,
|
||||
&end,
|
||||
1) <= 0)
|
||||
|
||||
if( parse_util_locate_cmdsubst( subpos,
|
||||
(const wchar_t **)&begin,
|
||||
(const wchar_t **)&end,
|
||||
1) <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
51
history.c
51
history.c
@@ -45,6 +45,8 @@ typedef struct
|
||||
The last item loaded from file
|
||||
*/
|
||||
ll_node_t *last_loaded;
|
||||
|
||||
int is_loaded;
|
||||
}
|
||||
history_data;
|
||||
|
||||
@@ -82,25 +84,31 @@ static wchar_t *mode_name;
|
||||
*/
|
||||
static hash_table_t history_table;
|
||||
|
||||
/**
|
||||
Flag, set to 1 once the history file has been loaded
|
||||
*/
|
||||
static int is_loaded;
|
||||
|
||||
/**
|
||||
Load history from ~/.fish_history
|
||||
Load history from file
|
||||
*/
|
||||
static void history_load( wchar_t *name )
|
||||
static void history_load()
|
||||
{
|
||||
wchar_t *fn;
|
||||
wchar_t *buff=0;
|
||||
int buff_len=0;
|
||||
FILE *in_stream;
|
||||
hash_table_t used;
|
||||
|
||||
|
||||
is_loaded = 1;
|
||||
|
||||
block();
|
||||
hash_init2( &used,
|
||||
&hash_wcs_func,
|
||||
&hash_wcs_cmp,
|
||||
4096 );
|
||||
|
||||
fn = wcsdupcat2( env_get(L"HOME"), L"/.", name, L"_history", 0 );
|
||||
fn = wcsdupcat2( env_get(L"HOME"), L"/.", mode_name, L"_history", 0 );
|
||||
|
||||
in_stream = wfopen( fn, "r" );
|
||||
|
||||
@@ -111,7 +119,7 @@ static void history_load( wchar_t *name )
|
||||
int buff_read = fgetws2( &buff, &buff_len, in_stream );
|
||||
if( buff_read == -1 )
|
||||
{
|
||||
debug( 1, L"The following non-fatal error occurred while reading command history from \'%ls\':", name );
|
||||
debug( 1, L"The following non-fatal error occurred while reading command history from \'%ls\':", mode_name );
|
||||
wperror( L"fgetws2" );
|
||||
fclose( in_stream );
|
||||
free( fn );
|
||||
@@ -161,7 +169,7 @@ static void history_load( wchar_t *name )
|
||||
{
|
||||
if( errno != ENOENT )
|
||||
{
|
||||
debug( 1, L"The following non-fatal error occurred while reading command history from \'%ls\':", name );
|
||||
debug( 1, L"The following non-fatal error occurred while reading command history from \'%ls\':", mode_name );
|
||||
wperror( L"fopen" );
|
||||
}
|
||||
|
||||
@@ -198,6 +206,7 @@ static void history_to_hash()
|
||||
d->last=history_last;
|
||||
d->last_loaded=last_loaded;
|
||||
d->count=history_count;
|
||||
d->is_loaded = is_loaded;
|
||||
|
||||
hash_put( &history_table,
|
||||
mode_name,
|
||||
@@ -223,13 +232,14 @@ void history_set_mode( wchar_t *name )
|
||||
history_current = history_last = curr->last;
|
||||
last_loaded = curr->last_loaded;
|
||||
history_count = curr->count;
|
||||
is_loaded = curr->is_loaded;
|
||||
}
|
||||
else
|
||||
{
|
||||
history_count=0;
|
||||
history_last = history_current = last_loaded=0;
|
||||
mode_name = wcsdup( name );
|
||||
history_load( name );
|
||||
is_loaded = 0;
|
||||
}
|
||||
|
||||
past_end=1;
|
||||
@@ -259,6 +269,9 @@ static void history_save()
|
||||
/* First we save this sessions history in local variables */
|
||||
ll_node_t *real_pos = history_last, *real_first = last_loaded;
|
||||
|
||||
if( !is_loaded )
|
||||
return;
|
||||
|
||||
if( !real_first )
|
||||
{
|
||||
real_first = history_current;
|
||||
@@ -390,6 +403,9 @@ void history_destroy()
|
||||
*/
|
||||
static ll_node_t *history_find( ll_node_t *n, const wchar_t *s )
|
||||
{
|
||||
if( !is_loaded )
|
||||
history_load();
|
||||
|
||||
if( n == 0 )
|
||||
return 0;
|
||||
|
||||
@@ -406,6 +422,9 @@ void history_add( const wchar_t *str )
|
||||
{
|
||||
ll_node_t *old_node;
|
||||
|
||||
if( !is_loaded )
|
||||
history_load();
|
||||
|
||||
if( wcslen( str ) == 0 )
|
||||
return;
|
||||
|
||||
@@ -460,6 +479,9 @@ static int history_test( const wchar_t *needle, const wchar_t *haystack )
|
||||
|
||||
const wchar_t *history_prev_match( const wchar_t *str )
|
||||
{
|
||||
if( !is_loaded )
|
||||
history_load();
|
||||
|
||||
if( history_current == 0 )
|
||||
return str;
|
||||
|
||||
@@ -481,6 +503,9 @@ const wchar_t *history_prev_match( const wchar_t *str )
|
||||
|
||||
const wchar_t *history_next_match( const wchar_t *str)
|
||||
{
|
||||
if( !is_loaded )
|
||||
history_load();
|
||||
|
||||
if( history_current == 0 )
|
||||
return str;
|
||||
|
||||
@@ -507,15 +532,21 @@ void history_reset()
|
||||
*/
|
||||
void history_first()
|
||||
{
|
||||
while( history_current->prev )
|
||||
history_current = history_current->prev;
|
||||
if( is_loaded )
|
||||
while( history_current->prev )
|
||||
history_current = history_current->prev;
|
||||
|
||||
}
|
||||
|
||||
wchar_t *history_get( int idx )
|
||||
{
|
||||
ll_node_t *n=history_last;
|
||||
ll_node_t *n;
|
||||
int i;
|
||||
if( !is_loaded )
|
||||
history_load();
|
||||
|
||||
n = history_last;
|
||||
|
||||
if( idx<0)
|
||||
{
|
||||
debug( 1, L"Tried to access negative history index %d", idx );
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
#include <wchar.h>
|
||||
|
||||
/**
|
||||
Load history from file.
|
||||
Init history library. The history file won't actually be loaded
|
||||
until the first time a history search is performed.
|
||||
*/
|
||||
void history_init();
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
complete -c apt-listchanges -l help -d (_ "Display help and exit")
|
||||
complete -c apt-listchanges -l apt -d (_ "Read filenames from pipe")
|
||||
complete -f -c apt-listchanges -s v -l verbose -d (_ "Verbose mode")
|
||||
complete -f -c apt-listchanges -s f -l frontend -a "pager browser xterm-pager xterm-browser text mail none" -d (_ "Select fronend interface")
|
||||
complete -f -c apt-listchanges -s f -l frontend -a "pager browser xterm-pager xterm-browser text mail none" -d (_ "Select frontend interface")
|
||||
complete -r -f -c apt-listchanges -l email-address -d (_ "Specify email address")
|
||||
complete -f -c apt-listchanges -s c -l confirm -d (_ "Ask confirmation")
|
||||
complete -f -c apt-listchanges -s a -l all -d (_ "Display all changelogs")
|
||||
|
||||
@@ -12,7 +12,7 @@ complete -f -c apt-move -a mirror -d (_ "Download package missing from mirror")
|
||||
complete -f -c apt-move -a sync -d (_ "Sync packages installed")
|
||||
complete -f -c apt-move -a exclude -d 'test $LOCALDIR/.exclude file'
|
||||
complete -c apt-move -a movefile -d (_ "Move file specified on commandline")
|
||||
complete -f -c apt-move -a listbin -d (_ "List packags that may serve as input to mirrorbin or mirrorsource" )
|
||||
complete -f -c apt-move -a listbin -d (_ "List packages that may serve as input to mirrorbin or mirrorsource" )
|
||||
complete -f -c apt-move -a mirrorbin -d (_ "Fetch package from STDIN")
|
||||
complete -f -c apt-move -a mirrorsrc -d (_ "Fetch source package from STDIN")
|
||||
complete -f -c apt-move -s a -d (_ "Process all packages")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#apt-rdepends
|
||||
complete -c apt-rdepends -l help -d (_ "Display help and exit")
|
||||
complete -f -c apt-rdepends -s b -l build-depends -d (_ "Show bulid dependencies")
|
||||
complete -f -c apt-rdepends -s b -l build-depends -d (_ "Show build dependencies")
|
||||
complete -f -c apt-rdepends -s d -l dotty -d (_ "Generate a dotty graph")
|
||||
complete -f -c apt-rdepends -s p -l print-state -d (_ "Show state of dependencies")
|
||||
complete -f -c apt-rdepends -s r -l reverse -d (_ "List packages depending on")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#apt-spy
|
||||
complete -c apt-spy -s h -d (_ "Display help and exit")
|
||||
complete -f -c apt-spy -s d -a "stable testing unstable" -d (_ "Debian distribtion")
|
||||
complete -f -c apt-spy -s d -a "stable testing unstable" -d (_ "Debian distribution")
|
||||
complete -f -c apt-spy -s a -a "Africa Asia Europe North-America Oceania South-America" -d (_ "Servers in the areas")
|
||||
complete -c apt-spy -s c -d (_ "Conf file")
|
||||
complete -f -c apt-spy -s e -d (_ "Finish after number of servers")
|
||||
|
||||
@@ -11,3 +11,4 @@ complete -c complete -s d -l description -d (_ "Description of this completions"
|
||||
complete -c complete -s u -l unauthorative -d (_ "Option list is not complete")
|
||||
complete -c complete -s e -l erase -d (_ "Remove completion")
|
||||
complete -c complete -s h -l help -d (_ "Display help and exit")
|
||||
complete -c complete -s C -l do-complete -d (_ "Print all completions for the specified commandline")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
complete -c cut -s b -l bytes -x -d (_ "Ouput byte range")
|
||||
complete -c cut -s b -l bytes -x -d (_ "Output byte range")
|
||||
complete -c cut -s c -l characters -x -d (_ "Output character range")
|
||||
complete -c cut -s d -l delimiter -x -d (_ "Select field delimiter")
|
||||
complete -c cut -s d -l fields -x -d (_ "Select fields")
|
||||
|
||||
@@ -39,7 +39,7 @@ complete -c cvs -x -s Q -d (_ "Cause CVS to be really quiet")
|
||||
complete -c cvs -x -s q -d (_ "Cause CVS to be somewhat quiet")
|
||||
complete -c cvs -x -s r -d (_ "Make checked-out files read-only")
|
||||
complete -c cvs -x -s w -d (_ "Make checked-out files read-write (default)")
|
||||
complete -c cvs -x -s n -d (_ "Do not execute anything that will change the disk")
|
||||
complete -c cvs -x -s n -d (_ "Do not change any files")
|
||||
complete -c cvs -x -s t -d (_ "Show trace of program execution -- try with -n")
|
||||
complete -c cvs -x -s v -d (_ "Display version and exit")
|
||||
complete -c cvs -x -s T -r -d (_ "Use "tmpdir" for temporary files")
|
||||
|
||||
@@ -42,13 +42,13 @@ complete -c emerge -s B -l buildpkgonly -d (_ "Creates a binary package, but doe
|
||||
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 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 -s N -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")
|
||||
|
||||
@@ -2,4 +2,5 @@ complete -c fish -s c -l "command" -d (_ "Run fish with this command")
|
||||
complete -c fish -s h -l help -d (_ "Display help and exit")
|
||||
complete -c fish -s v -l version -d (_ "Display version and exit")
|
||||
complete -c fish -s i -l interactive -d (_ "Run in interactive mode")
|
||||
complete -c fish -s l -l login -d (_ "Run in login mode")
|
||||
complete -c fish -s p -l profile -d (_ "Output profiling information to specified file") -f
|
||||
|
||||
@@ -23,7 +23,7 @@ complete -c gcc -s x -d (_ "Language") -x -a '
|
||||
complete -c gcc -o pass-exit-codes -d (_ "Pass program exit codes")
|
||||
complete -c gcc -s c -d (_ "Stop after assembler")
|
||||
complete -c gcc -s S -d (_ "Stop after compile")
|
||||
complete -c gcc -s E -d (_ "Stop after preprocesswor")
|
||||
complete -c gcc -s E -d (_ "Stop after preprocessor")
|
||||
complete -c gcc -s o -r -d (_ "Output file")
|
||||
complete -c gcc -s v -d (_ "Print commands to stderr")
|
||||
complete -c gcc -o \#\#\# -d (_ "Print quoted commands to stderr, do not run")
|
||||
|
||||
@@ -270,7 +270,7 @@ complete -c gpg -l allow-freeform-uid -d (_ "Disable all checks on the form of t
|
||||
complete -c gpg -l ignore-time-conflict -d (_ "Do not fail if signature is older than key")
|
||||
complete -c gpg -l ignore-valid-from -d (_ "Allow subkeys that have a timestamp from the future")
|
||||
complete -c gpg -l ignore-crc-error -d (_ "Ignore CRC errors")
|
||||
complete -c gpg -l ignore-mdc-error -d (_ "Do not fail on MDC integrity protection failiure")
|
||||
complete -c gpg -l ignore-mdc-error -d (_ "Do not fail on MDC integrity protection failure")
|
||||
|
||||
complete -c gpg -l lock-once -d (_ "Lock the databases the first time a lock is requested and do not release the lock until the process terminates")
|
||||
complete -c gpg -l lock-multiple -d (_ "Release the locks every time a lock is no longer needed")
|
||||
|
||||
@@ -15,7 +15,7 @@ complete -c gprof -l function-ordering -d (_ "Suggest function ordering")
|
||||
complete -rc gprof -l file-ordering -d (_ "Suggest file ordering")
|
||||
complete -c gprof -s T -l traditional -d (_ "Traditional mode")
|
||||
complete -xc gprof -s w -l width -d (_ "Set width of output")
|
||||
complete -c gprof -s x -l all-lines -d (_ "Anotate every line")
|
||||
complete -c gprof -s x -l all-lines -d (_ "Annotate every line")
|
||||
complete -xc gprof -l demangle -d (_ "Set demangling style")
|
||||
complete -c gprof -l no-demangle -d (_ "Turn of demangling")
|
||||
complete -xc gprof -s a -l no-static -d (_ "Supress static functions")
|
||||
|
||||
@@ -32,5 +32,5 @@ complete -c help -x -a expand-variable -d (_ "Help on variable expansion \$VARNA
|
||||
complete -c help -x -a expand-home -d (_ "Help on home directory expansion ~USER")
|
||||
complete -c help -x -a expand-brace -d (_ "Help on brace expansion {a,b,c}")
|
||||
complete -c help -x -a expand-wildcard -d (_ "Help on wildcard expansion *.*")
|
||||
complete -c help -x -a expand-command-substitution -d (_ "Help on command substututions (SUBCOMMAND)")
|
||||
complete -c help -x -a expand-command-substitution -d (_ "Help on command substitution (SUBCOMMAND)")
|
||||
complete -c help -x -a expand-process -d (_ "Help on process expansion %JOB")
|
||||
|
||||
@@ -24,7 +24,7 @@ complete -c less -s n -l line-numbers -d (_ "Display line number")
|
||||
complete -c less -s N -l LINE-NUMBERS -d (_ "Display line number for each line")
|
||||
complete -c less -s o -l log-file -d (_ "Log input to file") -r
|
||||
complete -c less -s O -l LOG-FILE -d (_ "Log to file, overwrite") -r
|
||||
complete -c less -s p -l pattern -d (_ "Start at first occorance of pattern") -r
|
||||
complete -c less -s p -l pattern -d (_ "Start at first occurrence of pattern") -r
|
||||
complete -c less -s P -l prompt -d (_ "Prompt string") -r
|
||||
complete -c less -s q -l quiet -d (_ "Silent mode")
|
||||
complete -c less -l silent -d (_ "Silent mode")
|
||||
|
||||
10
init/completions/status.fish
Normal file
10
init/completions/status.fish
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
complete -c status -l is-command-substitution -d (_ "Test if a command substitution is currently evaluated")
|
||||
complete -c status -l is-block -d (_ "Test if a code block is currently evaluated")
|
||||
complete -c status -l is-interactive -d (_ "Test if this is an interactive shell")
|
||||
complete -c status -l is-login -d (_ "Test if this is a login shell")
|
||||
complete -c status -l is-full-job-control -d (_ "Test if all new jobs are put under job control")
|
||||
complete -c status -l is-interactive-job-control -d (_ "Test if only interactive new jobs are put under job control")
|
||||
complete -c status -l is-no-job-control -d (_ "Test if new jobs are never put under job control")
|
||||
complete -c status -s j -l job-control -xa "full interactive none" -d (_ "Set which jobs are out under job control")
|
||||
complete -c status -s t -l print-stack-trace -d (_ "Print a list of all function calls leading up to running the current command")
|
||||
@@ -1,10 +1,8 @@
|
||||
#
|
||||
# Completion for sudo
|
||||
#
|
||||
# Generate a list of commands
|
||||
#
|
||||
|
||||
complete -c sudo -d (_ "Command to run") -x -a "(__fish_complete_commands)"
|
||||
complete -c sudo -d (_ "Command to run") -x -a "(__fish_complete_subcommand)"
|
||||
|
||||
complete -c sudo -s h -d (_ "Display help and exit")
|
||||
complete -c sudo -s v -d (_ "Validate")
|
||||
complete -c sudo -s h -n "__fish_no_arguments" -d (_ "Display help and exit")
|
||||
complete -c sudo -s v -n "__fish_no_arguments" -d (_ "Validate")
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
|
||||
complete -c time -a "(__fish_complete_command)" -d (_ "Command")
|
||||
complete -c time -a "(__fish_complete_subcommand -- -o --output -f --format)" -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")
|
||||
complete -c time -s f -l format -n "__fish_no_arguments" -d (_ "Specify output format") -x
|
||||
complete -c time -s p -l portable -n "__fish_no_arguments" -d (_ "Use the portable output format")
|
||||
complete -c time -s o -l output -n "__fish_no_arguments" -d (_ "Do not send the results to stderr, but overwrite the specified file") -r
|
||||
complete -c time -s a -l append -n "__fish_no_arguments" -d (_ "(Used together with -o) Do not overwrite but append")
|
||||
complete -c time -s v -l verbose -n "__fish_no_arguments" -d (_ "Verbose mode")
|
||||
complete -c time -l help -n "__fish_no_arguments" -d (_ "Display help and exit")
|
||||
complete -c time -s V -l version -n "__fish_no_arguments" -d (_ "Display version and exit")
|
||||
|
||||
|
||||
@@ -6,19 +6,19 @@ complete -c wget -s V -l version -d (_ "Display version and exit")
|
||||
complete -c wget -s h -l help -d (_ "Display help and exit")
|
||||
complete -c wget -s b -l background -d (_ "Go to background immediately after startup")
|
||||
complete -c wget -s e -l execute -d (_ "Execute command as if part of .wgetrc") -x
|
||||
complete -c wget -s o -l output-file -d (_ "Log all messages to logfile") -f
|
||||
complete -c wget -s o -l output-file -d (_ "Log all messages to logfile") -r
|
||||
complete -c wget -s a -l append-output -d (_ "Append all messages to logfile")
|
||||
complete -c wget -s d -l debug -d (_ "Turn on debug output")
|
||||
complete -c wget -s q -l quiet -d (_ "Quiet mode")
|
||||
complete -c wget -s v -l verbose -d (_ "Verbose mode")
|
||||
complete -c wget -l non-verbose -d (_ "Turn off verbose without being completely quiet")
|
||||
complete -c wget -o nv -d (_ "Turn off verbose without being completely quiet")
|
||||
complete -c wget -s i -l input-file -d (_ "Read URLs from file") -f
|
||||
complete -c wget -s i -l input-file -d (_ "Read URLs from file") -r
|
||||
complete -c wget -s F -l force-html -d (_ "Force input to be treated as HTML")
|
||||
complete -c wget -s B -l base -d (_ "Prepend string to relative links") -x
|
||||
complete -c wget -l bind-adress -d (_ "Bind address on local machine") -xa "(__fish_print_addresses; __fish_print_hostnames)"
|
||||
complete -c wget -s t -l tries -d (_ "Set number of retries to number") -xa "0 1 2 4 8 16 32 64 128"
|
||||
complete -c wget -s O -l output-document -d (_ "Concatenate output to file") -f
|
||||
complete -c wget -s O -l output-document -d (_ "Concatenate output to file") -r
|
||||
complete -c wget -l no-clobber -d (_ "Never overwrite files with same name")
|
||||
complete -c wget -o nc -d (_ "Never overwrite files with same name")
|
||||
complete -c wget -s c -l continue -d (_ "Continue getting a partially-downloaded file")
|
||||
@@ -57,13 +57,13 @@ complete -c wget -l no-host-directories -d (_ "Disable generation of host-prefix
|
||||
complete -c wget -o nH -d (_ "Disable generation of host-prefixed directories")
|
||||
complete -c wget -l protocal-directories -d (_ "Use the protocol name as a directory component")
|
||||
complete -c wget -l cut-dirs -d (_ "Ignore specified number of directory components") -xa "1 2 3 4 5"
|
||||
complete -c wget -s P -l directory-prefix -d (_ "Set directory prefix") -f
|
||||
complete -c wget -s P -l directory-prefix -d (_ "Set directory prefix") -r
|
||||
complete -c wget -s E -l html-extension -d (_ "Force html files to have html extension")
|
||||
complete -c wget -l http-user -d (_ "Specify the http username") -xa "(__fish_complete_users)"
|
||||
complete -c wget -l http-passwd -d (_ "Specify the http password") -x
|
||||
complete -c wget -l no-cache -d (_ "Disable server-side cache")
|
||||
complete -c wget -l no-cookies -d (_ "Disable the use of cookies")
|
||||
complete -c wget -l load-cookies -d (_ "Load cookies from file") -f
|
||||
complete -c wget -l load-cookies -d (_ "Load cookies from file") -r
|
||||
complete -c wget -l save-cookies -d (_ "Save cookies to file")
|
||||
complete -c wget -l keep-session-cookies -d (_ "Save session cookies")
|
||||
complete -c wget -l ignore-length -d (_ "Ignore 'Content-Length' header")
|
||||
@@ -74,7 +74,7 @@ complete -c wget -l referer -d (_ "Set referer URL") -x
|
||||
complete -c wget -l save-headers -d (_ "Save the headers sent by the HTTP server")
|
||||
complete -c wget -s U -l user-agent -d (_ "Identify as agent-string") -x
|
||||
complete -c wget -l post-data -d (_ "Use POST as the method for all HTTP requests and send the specified data in the request body") -x
|
||||
complete -c wget -l post-file -d (_ "Use POST as the method for all HTTP requests and send the specified data in the request body") -f
|
||||
complete -c wget -l post-file -d (_ "Use POST as the method for all HTTP requests and send the specified data in the request body") -r
|
||||
complete -c wget -l no-http-keep-alive -d (_ "Turn off keep-alive for http downloads")
|
||||
|
||||
#FTP options
|
||||
|
||||
22
init/fish.in
22
init/fish.in
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Init file for fish
|
||||
#
|
||||
|
||||
# @configure_input@
|
||||
|
||||
#
|
||||
# Set default field separators
|
||||
@@ -15,11 +15,10 @@ set -g IFS \ \t\n
|
||||
# want this even for text-only terminals.
|
||||
#
|
||||
|
||||
set -l path_list /bin /usr/bin /usr/X11R6/bin @PREFIX@/bin
|
||||
set -l path_list /bin /usr/bin /usr/X11R6/bin @PREFIX@/bin @optbindirs@
|
||||
|
||||
# Root should also have the sbin directories in the path
|
||||
set -l uid (id -u 2>/dev/null)
|
||||
if test "$uid" = 0
|
||||
if test "$USER" = root
|
||||
set path_list $path_list /sbin /usr/sbin /usr/local/sbin
|
||||
end
|
||||
|
||||
@@ -77,13 +76,14 @@ end
|
||||
# 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
|
||||
function _ -d "Alias for the gettext command"
|
||||
printf "%s" $argv
|
||||
end
|
||||
if test 1 = "@HAVE_GETTEXT@"
|
||||
if which gettext ^/dev/null >/dev/null
|
||||
function _ -d "Alias for the gettext command"
|
||||
gettext fish $argv
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# Main file for fish command completions. This file contains various
|
||||
# common helper functions for the command completions. All actual
|
||||
# completions are located in the completions subdirectory.
|
||||
#
|
||||
# @configure_input@
|
||||
|
||||
#
|
||||
# Don't need completions in non-interactive mode
|
||||
@@ -96,17 +98,57 @@ function __fish_complete_pids -d "Print a list of process identifiers along with
|
||||
end
|
||||
|
||||
function __fish_complete_command -d "Complete using all available commands"
|
||||
for i in $PATH; command ls $i; end
|
||||
printf "%s\n" (commandline -ct)(complete -C (commandline -ct))
|
||||
end
|
||||
|
||||
function __fish_complete_subcommand -d "Complete subcommand"
|
||||
set -l res ""
|
||||
set -l had_cmd 0
|
||||
set -l cmd (commandline -cop) (commandline -ct)
|
||||
set -l skip_next 1
|
||||
|
||||
for i in $cmd
|
||||
|
||||
if test "$skip_next" = 1
|
||||
set skip_next 0
|
||||
continue
|
||||
end
|
||||
|
||||
if test "$had_cmd" = 1
|
||||
set res "$res $i"
|
||||
else
|
||||
|
||||
if contains -- $i $argv
|
||||
set skip_next 1
|
||||
continue
|
||||
end
|
||||
|
||||
switch $i
|
||||
case '-*'
|
||||
|
||||
case '*'
|
||||
set had_cmd 1
|
||||
set res $i
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
printf "%s\n" (commandline -ct)(complete -C $res)
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
function __fish_print_hostnames -d "Print a list of known hostnames"
|
||||
|
||||
# Print all hosts from /etc/hosts
|
||||
cat /etc/hosts|sed -e 's/[0-9.]*\( \|\t\)*\(.*\)/\2/'|sed -e 's/\#.*//'|sed -e 'y/\t/\n/'|grep -v '^$'
|
||||
|
||||
if test -f /etc/hosts
|
||||
sed </etc/hosts -e 's/[0-9.]*\( \|\t\)*\(.*\)/\2/'|sed -e 's/\#.*//'|tr \t \n |grep -v '^$'
|
||||
end
|
||||
# Print nfs servers from /etc/fstab
|
||||
cat /etc/fstab| grep "^\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\|[a-zA-Z.]*\):"|cut -d : -f 1
|
||||
if test -f /etc/fstab
|
||||
grep </etc/fstab "^\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\|[a-zA-Z.]*\):"|cut -d : -f 1
|
||||
end
|
||||
|
||||
# Print hosts with known ssh keys
|
||||
cat ~/.ssh/known_hosts{,2} ^/dev/null|cut -d ' ' -f 1| cut -d , -f 1
|
||||
@@ -294,6 +336,20 @@ function __fish_is_first_token -d 'Test if no non-switch argument has been speci
|
||||
return 0
|
||||
end
|
||||
|
||||
function __fish_no_arguments -d "Internal fish function"
|
||||
set -l cmd (commandline -poc) (commandline -tc)
|
||||
set -e cmd[1]
|
||||
for i in $cmd
|
||||
switch $i
|
||||
case '-*'
|
||||
|
||||
case '*'
|
||||
return 1
|
||||
end
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
#
|
||||
# Completions for SysV startup scripts
|
||||
#
|
||||
|
||||
@@ -1,39 +1,15 @@
|
||||
#
|
||||
# This file defines various functions for fish
|
||||
# This file defines various shellscript functions. Most of them are
|
||||
# meant to be used directly by the user, but some of them, typically
|
||||
# the ones whose name start with '__fish_', are only meant to be used
|
||||
# internally by fish.
|
||||
#
|
||||
|
||||
|
||||
function _contains_help -d "Helper function for contains"
|
||||
|
||||
set bullet \*
|
||||
if expr "$LANG" : ".*UTF" >/dev/null
|
||||
set bullet \u2022
|
||||
end
|
||||
|
||||
echo \tcontains - Test if a word is present in a list\n
|
||||
__bold Synopsis
|
||||
echo \n\n\tcontains \[OPTION] KEY [VALUES...]\n
|
||||
__bold Description
|
||||
echo \n\n\t$bullet (__bold -h) or (__bold --help) display help and exit\n
|
||||
echo \tTest if the set VALUES contains the string KEY.
|
||||
echo \tReturn status is 0 if yes, 1 otherwise.\n
|
||||
__bold Example
|
||||
echo \n
|
||||
echo \tfor i in \~/bin /usr/local/bin
|
||||
echo \t\tif not contains \$i \$PATH
|
||||
echo \t\t\tset PATH \$PATH i
|
||||
echo \t\tend
|
||||
echo \tend
|
||||
echo
|
||||
echo \tThe above code tests if "~/bin" and /usr/local/bin are in the path
|
||||
echo \tand if they are not, they are added.
|
||||
end
|
||||
|
||||
function contains -d "Test if a key is contained in a set of values"
|
||||
while set -q argv
|
||||
switch $argv[1]
|
||||
case '-h' '--h' '--he' '--hel' '--help'
|
||||
_contains_help
|
||||
help contains
|
||||
return
|
||||
|
||||
case '--'
|
||||
@@ -42,8 +18,8 @@ function contains -d "Test if a key is contained in a set of values"
|
||||
break
|
||||
|
||||
case '-*'
|
||||
echo Unknown option $argv[$i]
|
||||
_contains_help
|
||||
printf (_ "%s: Unknown option '%s'\n") contains $argv[$i]
|
||||
help contains
|
||||
return 1
|
||||
|
||||
case '*'
|
||||
@@ -82,8 +58,8 @@ 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 fish_browser
|
||||
set -l fish_browser_bg
|
||||
|
||||
set -l h syntax completion editor job-control todo bugs history killring help
|
||||
set h $h color prompt title variables builtin-overview changes expand
|
||||
@@ -94,8 +70,8 @@ function help -d "Show help for the fish shell"
|
||||
# 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
|
||||
set -l graphical_browsers htmlview x-www-browser firefox galeon mozilla konqueror epiphany opera netscape
|
||||
set -l text_browsers htmlview www-browser links elinks lynx w3m
|
||||
|
||||
if test $BROWSER
|
||||
# User has manualy set a preferred browser, so we respect that
|
||||
@@ -116,7 +92,7 @@ function help -d "Show help for the fish shell"
|
||||
|
||||
# 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" = "" \)
|
||||
if test "$DISPLAY" -a \( "$XAUTHORITY" = "$HOME/.Xauthority" -o "$XAUTHORITY" = "" \)
|
||||
for i in $graphical_browsers
|
||||
if which $i 2>/dev/null >/dev/null
|
||||
set fish_browser $i
|
||||
@@ -145,11 +121,11 @@ function help -d "Show help for the fish shell"
|
||||
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
|
||||
set fish_help_page "builtins.html\#$fish_help_item"
|
||||
case contains count dirh dirs help mimedb nextd open popd prevd pushd set_color tokenize psub umask type vared
|
||||
set fish_help_page "commands.html\#$fish_help_item"
|
||||
case $help_topics
|
||||
set fish_help_page "index.html\#"$fish_help_item
|
||||
set fish_help_page "index.html\#$fish_help_item"
|
||||
case "*"
|
||||
if which $fish_help_item >/dev/null ^/dev/null
|
||||
man $fish_help_item
|
||||
@@ -199,22 +175,35 @@ end
|
||||
# application for the file.
|
||||
#
|
||||
|
||||
function open -d "Open file in default application"
|
||||
mimedb -l -- $argv
|
||||
if not test (uname) = Darwin
|
||||
function open -d "Open file in default application"
|
||||
mimedb -l -- $argv
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Print the current working directory. If it is too long, it will be
|
||||
# ellipsised. This function is used by the default prompt command.
|
||||
# Print the current working directory in a shortened form.This
|
||||
# function is used by the default prompt command.
|
||||
#
|
||||
|
||||
function prompt_pwd -d "Print the current working directory, shortend to fit the prompt"
|
||||
set -l wd (pwd)
|
||||
set -l res (echo $wd|sed -e 's-/\([^/]\)\([^/]*\)-/\1-g')
|
||||
if test $wd != '~'
|
||||
set res $res(echo $wd|sed -e 's-.*/[^/]\([^/]*$\)-\1-')
|
||||
if test (uname) = Darwin
|
||||
function prompt_pwd -d "Print the current working directory, shortend to fit the prompt"
|
||||
if test "$PWD" != "$HOME"
|
||||
printf "%s" (echo $PWD|sed -e 's|/private||' -e "s|^$HOME|~|" -e 's-/\([^/]\)\([^/]*\)-/\1-g')
|
||||
echo $PWD|sed -e 's-.*/[^/]\([^/]*$\)-\1-'
|
||||
else
|
||||
echo '~'
|
||||
end
|
||||
end
|
||||
else
|
||||
function prompt_pwd -d "Print the current working directory, shortend to fit the prompt"
|
||||
if test "$PWD" != "$HOME"
|
||||
printf "%s" (echo $PWD|sed -e "s|^$HOME|~|" -e 's-/\([^/]\)\([^/]*\)-/\1-g')
|
||||
echo $PWD|sed -e 's-.*/[^/]\([^/]*$\)-\1-'
|
||||
else
|
||||
echo '~'
|
||||
end
|
||||
end
|
||||
echo $res
|
||||
end
|
||||
|
||||
#
|
||||
@@ -222,7 +211,7 @@ end
|
||||
#
|
||||
|
||||
function pwd -d "Print working directory"
|
||||
command pwd | sed -e "s|^$HOME|~|"
|
||||
command pwd | sed -e 's|/private||' -e "s|^$HOME|~|"
|
||||
end
|
||||
|
||||
#
|
||||
@@ -235,10 +224,10 @@ function vared -d "Edit variable value"
|
||||
switch $argv
|
||||
|
||||
case '-h' '--h' '--he' '--hel' '--help'
|
||||
__vared_help
|
||||
help vared
|
||||
|
||||
case '-*'
|
||||
printf "vared: Unknown option %s\n" $argv
|
||||
printf (_ "%s: Unknown option %s\n") vared $argv
|
||||
|
||||
case '*'
|
||||
if test (count $$argv ) -lt 2
|
||||
@@ -263,24 +252,20 @@ function vared -d "Edit variable value"
|
||||
|
||||
else
|
||||
|
||||
printf (_ 'vared: %s is an array variable. Use %svared%s %s[n] to edit the n:th element of %s\n') $argv (set_color $fish_color_command) (set_color $fish_color_normal) $argv $argv
|
||||
printf (_ '%s: %s is an array variable. Use %svared%s %s[n] to edit the n:th element of %s\n') $argv (set_color $fish_color_command) (set_color $fish_color_normal) vared $argv $argv
|
||||
end
|
||||
end
|
||||
else
|
||||
printf (_ 'vared: Expected exactly one argument, got %s.\n\nSynopsis:\n\t%svared%s VARIABLE\n') (count $argv) (set_color $fish_color_command) (set_color $fish_color_normal)
|
||||
printf (_ '%s: Expected exactly one argument, got %s.\n\nSynopsis:\n\t%svared%s VARIABLE\n') vared (count $argv) (set_color $fish_color_command) (set_color $fish_color_normal)
|
||||
end
|
||||
end
|
||||
|
||||
function __vared_help -d "Display help for the vared shellscript function"
|
||||
#
|
||||
# This function is used internally by the fish command completion code
|
||||
#
|
||||
|
||||
printf "\tvared - Interactively edit the value of an environment variable\n\n"
|
||||
printf "%s\n\t%svared%s VARIABLE\n\n" (__bold Synopsis) (set_color $fish_color_command) (set_color normal)
|
||||
__bold Description
|
||||
printf "\n\n\tvared is used to interactively edit the value of an environment \n"
|
||||
printf "\tvariable. Array variables as a whole can not be edited using vared,\n"
|
||||
printf "\tbut individual array elements can.\n\n"
|
||||
__bold Example
|
||||
printf "\n\n\t"\'"%svared%s PATH[3]"\'" edits the third element of the PATH array.\n\n" (set_color $fish_color_co\mmand) (set_color normal)
|
||||
function __fish_describe_command -d "Command used to find descriptions for commands"
|
||||
apropos $argv | awk -v FS=" +- +" '{split($1, names, ", "); for (name in names) if (names[name] ~ /^'"$argv"'.* *\([18]\)/) { sub("\\([18]\\)", "", names[name]); print names[name] "\t" $2; } }'
|
||||
end
|
||||
|
||||
#
|
||||
@@ -314,7 +299,7 @@ function popd -d "Pop dir from stack"
|
||||
if test $dirstack[1]
|
||||
cd $dirstack[1]
|
||||
else
|
||||
echo Directory stack is empty...
|
||||
printf (_ "%s: Directory stack is empty...") popd
|
||||
return 1
|
||||
end
|
||||
|
||||
@@ -369,10 +354,10 @@ end
|
||||
|
||||
|
||||
function __fish_move_last -d "Move the last element of a directory history from src to dest"
|
||||
set src $argv[1]
|
||||
set dest $argv[2]
|
||||
set -l src $argv[1]
|
||||
set -l dest $argv[2]
|
||||
|
||||
set size_src (count $$src)
|
||||
set -l size_src (count $$src)
|
||||
|
||||
if test $size_src = 0
|
||||
# Cannot make this step
|
||||
@@ -398,15 +383,15 @@ end
|
||||
|
||||
function prevd -d "Move back in the directory history"
|
||||
# Parse arguments
|
||||
set show_hist 0
|
||||
set times 1
|
||||
set -l show_hist 0
|
||||
set -l times 1
|
||||
for i in (seq (count $argv))
|
||||
switch $argv[$i]
|
||||
case '-l'
|
||||
case '-l' --l --li --lis --list
|
||||
set show_hist 1
|
||||
continue
|
||||
case '-*'
|
||||
echo Uknown option $argv[$i]
|
||||
printf (_ "%s: Unknown option %s\n" ) prevd $argv[$i]
|
||||
return 1
|
||||
case '*'
|
||||
if test $argv[$i] -ge 0 ^/dev/null
|
||||
@@ -420,7 +405,7 @@ function prevd -d "Move back in the directory history"
|
||||
end
|
||||
|
||||
# Traverse history
|
||||
set code 1
|
||||
set -l code 1
|
||||
for i in (seq $times)
|
||||
# Try one step backward
|
||||
if __fish_move_last dirprev dirnext;
|
||||
@@ -449,21 +434,21 @@ end
|
||||
|
||||
function nextd -d "Move forward in the directory history"
|
||||
# Parse arguments
|
||||
set show_hist 0
|
||||
set times 1
|
||||
set -l show_hist 0
|
||||
set -l times 1
|
||||
for i in (seq (count $argv))
|
||||
switch $argv[$i]
|
||||
case '-l'
|
||||
case '-l' --l --li --lis --list
|
||||
set show_hist 1
|
||||
continue
|
||||
case '-*'
|
||||
echo Uknown option $argv[$i]
|
||||
printf (_ "%s: Unknown option %s\n" ) nextd $argv[$i]
|
||||
return 1
|
||||
case '*'
|
||||
if test $argv[$i] -ge 0 ^/dev/null
|
||||
set times $argv[$i]
|
||||
else
|
||||
echo "The number of positions to skip must be a non-negative integer"
|
||||
printf (_ "%s: The number of positions to skip must be a non-negative integer\n" ) nextd
|
||||
return 1
|
||||
end
|
||||
continue
|
||||
@@ -471,7 +456,7 @@ function nextd -d "Move forward in the directory history"
|
||||
end
|
||||
|
||||
# Traverse history
|
||||
set code 1
|
||||
set -l code 1
|
||||
for i in (seq $times)
|
||||
# Try one step backward
|
||||
if __fish_move_last dirnext dirprev;
|
||||
@@ -500,9 +485,9 @@ end
|
||||
|
||||
function dirh -d "Print the current directory history (the back- and fwd- lists)"
|
||||
# Avoid set comment
|
||||
set current (command pwd)
|
||||
set -- separator " "
|
||||
set -- line_len (echo (count $dirprev) + (echo $dirprev $current $dirnext | wc -m) | bc)
|
||||
set -l current (command pwd)
|
||||
set -l separator " "
|
||||
set -l line_len (echo (count $dirprev) + (echo $dirprev $current $dirnext | wc -m) | bc)
|
||||
if test $line_len -gt $COLUMNS
|
||||
# Print one entry per line if history is long
|
||||
set separator "\n"
|
||||
@@ -559,10 +544,9 @@ function trap -d 'Perform an action when the shell recives a signal'
|
||||
set -l shortopt
|
||||
set -l longopt
|
||||
|
||||
set shortopt -o lph
|
||||
if getopt -T >/dev/null
|
||||
set longopt
|
||||
else
|
||||
set -l shortopt -o lph
|
||||
set -l longopt
|
||||
if not getopt -T >/dev/null
|
||||
set longopt -l print,help,list-signals
|
||||
end
|
||||
|
||||
@@ -667,60 +651,31 @@ function trap -d 'Perform an action when the shell recives a signal'
|
||||
|
||||
end
|
||||
|
||||
function __fish_type_help -d "Help for the type shellscript function"
|
||||
|
||||
set bullet \*
|
||||
if expr "$LANG" : ".*UTF" >/dev/null
|
||||
set bullet \u2022
|
||||
end
|
||||
|
||||
echo \ttype - Indicate how a name would be interpreted if used as a \n\tcommand name
|
||||
echo
|
||||
echo (__bold Synopsis)
|
||||
echo
|
||||
echo \t(set_color $fish_color_command)type(set_color normal) [OPTIONS] name [name ...]
|
||||
echo
|
||||
echo (__bold Description)
|
||||
echo
|
||||
echo \tWith no options, indicate how each name would be interpreted if \n\tused as a command name.
|
||||
echo
|
||||
echo \t$bullet (__bold -h) or (__bold --help) print this message
|
||||
echo \t$bullet (__bold -a) or (__bold --all) print all possible definitions of the specified \n\t\ \ names
|
||||
echo \t$bullet (__bold -f) or (__bold --no-functions) supresses function and builtin lookup
|
||||
echo \t$bullet (__bold -t) or (__bold --type) print a string which is one of alias, keyword, \n\t\ \ function, builtin, or file if name is an alias, shell \n\t\ \ reserved word, function, builtin, or disk file, respectively
|
||||
echo \t$bullet (__bold -p) or (__bold --path) either return the name of the disk file that would \n\t\ \ be executed if name were specified as a command name, or nothing \n\t\ \ if (__bold "type -t name") would not return file
|
||||
echo \t$bullet (__bold -P) or (__bold --force-path) either return the name of the disk file that \n\t\ \ would be executed if name were specified as a command name, \n\t\ \ or nothing no file with the spacified name could be found \n\t\ \ in the PATH
|
||||
echo
|
||||
echo (__bold Example)
|
||||
echo
|
||||
echo \t\'(set_color $fish_color_command)type(set_color normal) fg\' outputs the string \'fg is a shell builtin\'.
|
||||
echo
|
||||
|
||||
end
|
||||
|
||||
function type -d "Print the type of a command"
|
||||
|
||||
# Initialize
|
||||
set status 1
|
||||
set mode normal
|
||||
set selection all
|
||||
set -l status 1
|
||||
set -l mode normal
|
||||
set -l 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 -l shortopt -o tpPafh
|
||||
set -l longopt
|
||||
if not getopt -T >/dev/null
|
||||
set longopt -l type,path,force-path,all,no-functions,help
|
||||
end
|
||||
|
||||
if not getopt -n type -Q $shortopt $longopt -- $argv
|
||||
return 1
|
||||
end
|
||||
|
||||
set -- tmp (getopt $shortopt $longopt -- $argv)
|
||||
set -l tmp (getopt $shortopt $longopt -- $argv)
|
||||
|
||||
eval set -- opt $tmp
|
||||
set -l opt
|
||||
eval set opt $tmp
|
||||
|
||||
for i in $opt
|
||||
switch $i
|
||||
@@ -741,7 +696,7 @@ function type -d "Print the type of a command"
|
||||
set selection files
|
||||
|
||||
case -h --help
|
||||
__fish_type_help
|
||||
help type
|
||||
return 0
|
||||
|
||||
case --
|
||||
@@ -833,7 +788,7 @@ end
|
||||
function __fish_umask_parse -d "Parses a file permission specification as into an octal version"
|
||||
# Test if already a valid octal mask, and pad it with zeros
|
||||
if echo $argv | grep -E '^(0|)[0-7]{1,3}$' >/dev/null
|
||||
for i in (seq (echo 5-(echo $argv|wc -c)|bc)); set -- argv 0$argv; end
|
||||
for i in (seq (echo 5-(echo $argv|wc -c)|bc)); set argv 0$argv; end
|
||||
echo $argv
|
||||
else
|
||||
# Test if argument really is a valid symbolic mask
|
||||
@@ -842,34 +797,38 @@ function __fish_umask_parse -d "Parses a file permission specification as into a
|
||||
return 1
|
||||
end
|
||||
|
||||
set -e implicit_all
|
||||
set -l implicit_all
|
||||
|
||||
# Insert inverted umask into res variable
|
||||
|
||||
set tmp $umask
|
||||
set -l mode
|
||||
set -l val
|
||||
set -l tmp $umask
|
||||
set -l res
|
||||
|
||||
for i in 1 2 3
|
||||
set -- tmp (echo $tmp|cut -c 2-)
|
||||
set -- res[$i] (echo 7-(echo $tmp|cut -c 1)|bc)
|
||||
set tmp (echo $tmp|cut -c 2-)
|
||||
set res[$i] (echo 7-(echo $tmp|cut -c 1)|bc)
|
||||
end
|
||||
|
||||
set -- el (echo $argv|tr , \n)
|
||||
set -l el (echo $argv|tr , \n)
|
||||
for i in $el
|
||||
switch $i
|
||||
case 'u*'
|
||||
set idx 1
|
||||
set -- i (echo $i| cut -c 2-)
|
||||
set i (echo $i| cut -c 2-)
|
||||
|
||||
case 'g*'
|
||||
set idx 2
|
||||
set -- i (echo $i| cut -c 2-)
|
||||
set i (echo $i| cut -c 2-)
|
||||
|
||||
case 'o*'
|
||||
set idx 3
|
||||
set -- i (echo $i| cut -c 2-)
|
||||
set i (echo $i| cut -c 2-)
|
||||
|
||||
case 'a*'
|
||||
set idx 1 2 3
|
||||
set -- i (echo $i| cut -c 2-)
|
||||
set i (echo $i| cut -c 2-)
|
||||
|
||||
case '*'
|
||||
set implicit_all 1
|
||||
@@ -879,26 +838,26 @@ function __fish_umask_parse -d "Parses a file permission specification as into a
|
||||
switch $i
|
||||
case '=*'
|
||||
set mode set
|
||||
set -- i (echo $i| cut -c 2-)
|
||||
set i (echo $i| cut -c 2-)
|
||||
|
||||
case '+*'
|
||||
set mode add
|
||||
set -- i (echo $i| cut -c 2-)
|
||||
set i (echo $i| cut -c 2-)
|
||||
|
||||
case '-*'
|
||||
set mode remove
|
||||
set -- i (echo $i| cut -c 2-)
|
||||
set i (echo $i| cut -c 2-)
|
||||
|
||||
case '*'
|
||||
if not set -q implicit_all
|
||||
echo umask: Invalid mask $argv >&2
|
||||
if not count $implicit_all >/dev/null
|
||||
printf (_ "%s: Invalid mask %s\n") umask $argv >&2
|
||||
return
|
||||
end
|
||||
set mode set
|
||||
end
|
||||
|
||||
if not echo $perm|grep -E '^(r|w|x)*$' >/dev/null
|
||||
echo umask: Invalid mask $argv >&2
|
||||
printf (_ "%s: Invalid mask %s\n") umask $argv >&2
|
||||
return
|
||||
end
|
||||
|
||||
@@ -964,20 +923,19 @@ function umask -d "Set default file permission mask"
|
||||
set -l as_command 0
|
||||
set -l symbolic 0
|
||||
|
||||
set -- shortopt -o pSh
|
||||
if getopt -T >/dev/null
|
||||
set longopt
|
||||
else
|
||||
set -- longopt -l as-command,symbolic,help
|
||||
set -l shortopt -o pSh
|
||||
set -l longopt
|
||||
if not getopt -T >/dev/null
|
||||
set longopt -l as-command,symbolic,help
|
||||
end
|
||||
|
||||
if not getopt -n umask -Q $shortopt $longopt -- $argv
|
||||
return 1
|
||||
end
|
||||
|
||||
set tmp -- (getopt $shortopt $longopt -- $argv)
|
||||
set -l tmp (getopt $shortopt $longopt -- $argv)
|
||||
|
||||
eval set -- opt $tmp
|
||||
eval set opt $tmp
|
||||
|
||||
while count $opt >/dev/null
|
||||
|
||||
@@ -1022,7 +980,9 @@ function umask -d "Set default file permission mask"
|
||||
set -l parsed (__fish_umask_parse $opt)
|
||||
if test (count $parsed) -eq 1
|
||||
set -g umask $parsed
|
||||
return 0
|
||||
end
|
||||
return 1
|
||||
|
||||
case '*'
|
||||
printf (_ '%s: Too many arguments\n') umask >&2
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#
|
||||
# Initializations that should only be performed when in interactive mode
|
||||
#
|
||||
# @configure_input@
|
||||
|
||||
if not status --is-interactive
|
||||
exit
|
||||
@@ -26,7 +27,19 @@ end
|
||||
# long it is.
|
||||
|
||||
function fish_prompt -d (_ "Write out the prompt")
|
||||
printf '%s@%s %s%s%s> \n' (whoami) (hostname|cut -d . -f 1) (set_color $fish_color_cwd) (prompt_pwd) (set_color normal)
|
||||
|
||||
# Just calculate these once, to save a few cycles when displaying the prompt
|
||||
if not set -q __fish_prompt_hostname
|
||||
set -g __fish_prompt_hostname (hostname|cut -d . -f 1)
|
||||
end
|
||||
|
||||
if not set -q __fish_prompt_normal
|
||||
set -g __fish_prompt_normal (set_color normal)
|
||||
end
|
||||
|
||||
set -l prompt_color (set_color $fish_color_cwd)
|
||||
|
||||
printf '%s@%s %s%s%s> \n' $USER $__fish_prompt_hostname "$prompt_color" (prompt_pwd) "$__fish_prompt_normal"
|
||||
end
|
||||
|
||||
#
|
||||
@@ -52,15 +65,10 @@ end
|
||||
# Set various color values
|
||||
#
|
||||
|
||||
function set_default_color -d "Set an universal variable, unless it has already been set. If set, verify that it is a valid color name"
|
||||
if not set -q $argv[1]
|
||||
set -U -- $argv
|
||||
return
|
||||
function set_default -d "Set an exported universal variable, unless it has already been set"
|
||||
if not set -q $argv[1]
|
||||
set -Ux -- $argv
|
||||
end
|
||||
if contains -- $$argv[1] (set_color -c)
|
||||
return
|
||||
end
|
||||
set -U -- $argv
|
||||
end
|
||||
|
||||
function set_exported_default -d "Set an exported universal variable, unless it has already been set"
|
||||
@@ -71,35 +79,35 @@ end
|
||||
|
||||
|
||||
# Regular syntax highlighting colors
|
||||
set_default_color fish_color_normal normal
|
||||
set_default_color fish_color_command green
|
||||
set_default_color fish_color_redirection normal
|
||||
set_default_color fish_color_comment brown
|
||||
set_default_color fish_color_error red
|
||||
set_default fish_color_normal normal
|
||||
set_default fish_color_command green
|
||||
set_default fish_color_redirection normal
|
||||
set_default fish_color_comment brown
|
||||
set_default fish_color_error red
|
||||
|
||||
set_default_color fish_color_cwd green
|
||||
set_default fish_color_cwd green
|
||||
|
||||
# Background color for matching quotes and parenthesis
|
||||
set_default_color fish_color_match cyan
|
||||
set_default fish_color_match cyan
|
||||
|
||||
# Background color for search matches
|
||||
set_default_color fish_color_search_match purple
|
||||
set_default fish_color_search_match purple
|
||||
|
||||
# Pager colors
|
||||
set_default_color fish_pager_color_prefix cyan
|
||||
set_default_color fish_pager_color_completion normal
|
||||
set_default_color fish_pager_color_description normal
|
||||
set_default_color fish_pager_color_progress cyan
|
||||
set_default fish_pager_color_prefix cyan
|
||||
set_default fish_pager_color_completion normal
|
||||
set_default fish_pager_color_description normal
|
||||
set_default fish_pager_color_progress cyan
|
||||
|
||||
# Directory history colors
|
||||
set_default_color fish_color_history_current cyan
|
||||
set_default fish_color_history_current cyan
|
||||
|
||||
|
||||
#
|
||||
# Setup the CDPATH variable
|
||||
#
|
||||
|
||||
set_exported_default CDPATH . ~
|
||||
set_default CDPATH . ~
|
||||
|
||||
#
|
||||
# Match colors for grep, if supported
|
||||
@@ -115,7 +123,46 @@ end
|
||||
#
|
||||
|
||||
if command ls --color=auto --help 1>/dev/null 2>/dev/null
|
||||
set_exported_default LS_COLORS $LS_COLORS '*.jar=01;31' '*.doc=35' '*.pdf=35' '*.ps=35' '*.xls=35' '*.swf=35' '*~=37'
|
||||
|
||||
set -l color_document 35
|
||||
set -l color_image '01;35'
|
||||
set -l color_sound '01;35'
|
||||
set -l color_video '01;35'
|
||||
set -l color_archive '01;31'
|
||||
set -l color_command '01;32'
|
||||
set -l color_backup 37
|
||||
|
||||
set -l default no=00 fi=00 'di=01;34' 'ln=01;36' 'pi=40;33' 'so=01;35' 'bd=40;33;01' 'cd=40;33;01' 'or=01;05;37;41' 'mi=01;05;37;41' ex=$color_command
|
||||
|
||||
for i in .cmd .exe .com .btm .bat .sh .csh .fish
|
||||
set default $default "*$i=$color_command"
|
||||
end
|
||||
|
||||
for i in .tar .tgz .arj .taz .lhz .zip .z .Z .gz .bz2 .bz .tz .rpm .cpio .jar .deb .rar .bin .hqx
|
||||
set default $default "*$i=$color_archive"
|
||||
end
|
||||
|
||||
for i in .jpg .jpeg .gif .bmp .xbm .xpm .png .tif
|
||||
set default $default "*$i=$color_image"
|
||||
end
|
||||
|
||||
for i in .mp3 .au .wav .aiff .ogg .wma
|
||||
set default $default "*$i=$color_sound"
|
||||
end
|
||||
|
||||
for i in .avi .mpeg .mpg .divx .mov .qt .wmv .rm
|
||||
set default $default "*$i=$color_video"
|
||||
end
|
||||
|
||||
for i in .htm .html .rtf .wpd .doc .pdf .ps .xls .swf .txt .tex .sxw .dvi INSTALL README ChangeLog
|
||||
set default $default "*$i=$color_document"
|
||||
end
|
||||
|
||||
for i in '~' .bak
|
||||
set default $default "*$i=$color_backup"
|
||||
end
|
||||
|
||||
set -gx LS_COLORS $default
|
||||
end
|
||||
|
||||
|
||||
@@ -123,5 +170,5 @@ end
|
||||
# Remove temporary functions
|
||||
#
|
||||
|
||||
functions -e set_default_color
|
||||
functions -e set_exported_default
|
||||
functions -e set_default
|
||||
|
||||
11
intern.c
11
intern.c
@@ -25,14 +25,6 @@ static hash_table_t *intern_table=0;
|
||||
*/
|
||||
static hash_table_t *intern_static_table=0;
|
||||
|
||||
/**
|
||||
Load static strings that are universally common. Currently only loads the empty string.
|
||||
*/
|
||||
static void intern_load_common_static()
|
||||
{
|
||||
intern_static( L"" );
|
||||
}
|
||||
|
||||
const wchar_t *intern( const wchar_t *in )
|
||||
{
|
||||
const wchar_t *res=0;
|
||||
@@ -40,9 +32,6 @@ const wchar_t *intern( const wchar_t *in )
|
||||
if( !in )
|
||||
return 0;
|
||||
|
||||
intern_load_common_static();
|
||||
|
||||
|
||||
if( !intern_table )
|
||||
{
|
||||
intern_table = malloc( sizeof( hash_table_t ) );
|
||||
|
||||
8
io.c
8
io.c
@@ -37,7 +37,7 @@ Utilities for io redirection.
|
||||
#include "common.h"
|
||||
#include "io.h"
|
||||
#include "translate.h"
|
||||
|
||||
#include "halloc.h"
|
||||
|
||||
|
||||
void io_buffer_read( io_data_t *d )
|
||||
@@ -175,14 +175,14 @@ io_data_t *io_remove( io_data_t *list, io_data_t *element )
|
||||
return list;
|
||||
}
|
||||
|
||||
io_data_t *io_duplicate( io_data_t *l )
|
||||
io_data_t *io_duplicate( void *context, io_data_t *l )
|
||||
{
|
||||
io_data_t *res;
|
||||
|
||||
if( l == 0 )
|
||||
return 0;
|
||||
|
||||
res = malloc( sizeof( io_data_t) );
|
||||
res = halloc( context, sizeof( io_data_t) );
|
||||
|
||||
if( !res )
|
||||
{
|
||||
@@ -191,7 +191,7 @@ io_data_t *io_duplicate( io_data_t *l )
|
||||
}
|
||||
|
||||
memcpy( res, l, sizeof(io_data_t ));
|
||||
res->next=io_duplicate( l->next );
|
||||
res->next=io_duplicate( context, l->next );
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
4
io.h
4
io.h
@@ -62,9 +62,9 @@ io_data_t *io_add( io_data_t *first_chain, io_data_t *decond_chain );
|
||||
io_data_t *io_remove( io_data_t *list, io_data_t *element );
|
||||
|
||||
/**
|
||||
Make a copy of the specified chain of redirections
|
||||
Make a copy of the specified chain of redirections. Uses halloc.
|
||||
*/
|
||||
io_data_t *io_duplicate( io_data_t *l );
|
||||
io_data_t *io_duplicate( void *context, io_data_t *l );
|
||||
|
||||
/**
|
||||
Return the last io redirection in ht e chain for the specified file descriptor.
|
||||
|
||||
5
kill.c
5
kill.c
@@ -25,7 +25,6 @@
|
||||
#include "sanity.h"
|
||||
#include "common.h"
|
||||
#include "env.h"
|
||||
#include "expand.h"
|
||||
#include "exec.h"
|
||||
#include "parser.h"
|
||||
|
||||
@@ -95,7 +94,7 @@ void kill_add( wchar_t *str )
|
||||
wchar_t *disp;
|
||||
if( (disp = env_get( L"DISPLAY" )) )
|
||||
{
|
||||
wchar_t *escaped_str = expand_escape( str, 1 );
|
||||
wchar_t *escaped_str = escape( str, 1 );
|
||||
wchar_t *cmd = wcsdupcat2(L"echo ", escaped_str, L"|xsel -b",0);
|
||||
exec_subshell( cmd, 0 );
|
||||
free( cut_buffer );
|
||||
@@ -137,7 +136,7 @@ static void kill_check_x_buffer()
|
||||
|
||||
for( i=0; i<al_get_count( &list ); i++ )
|
||||
{
|
||||
wchar_t *next_line = expand_escape( (wchar_t *)al_get( &list, i ), 0);
|
||||
wchar_t *next_line = escape( (wchar_t *)al_get( &list, i ), 0);
|
||||
if( i==0 )
|
||||
{
|
||||
new_cut_buffer = next_line;
|
||||
|
||||
41
main.c
41
main.c
@@ -124,6 +124,10 @@ int main( int argc, char **argv )
|
||||
"interactive", no_argument, 0, 'i'
|
||||
}
|
||||
,
|
||||
{
|
||||
"login", no_argument, 0, 'l'
|
||||
}
|
||||
,
|
||||
{
|
||||
"profile", required_argument, 0, 'p'
|
||||
}
|
||||
@@ -146,14 +150,14 @@ int main( int argc, char **argv )
|
||||
|
||||
int opt = getopt_long( argc,
|
||||
argv,
|
||||
"hivc:p:",
|
||||
"hilvc:p:",
|
||||
long_options,
|
||||
&opt_index );
|
||||
|
||||
#else
|
||||
int opt = getopt( argc,
|
||||
argv,
|
||||
"hivc:p:" );
|
||||
"hilvc:p:" );
|
||||
#endif
|
||||
if( opt == -1 )
|
||||
break;
|
||||
@@ -170,14 +174,16 @@ int main( int argc, char **argv )
|
||||
|
||||
case 'h':
|
||||
cmd = "help";
|
||||
//interactive=0;
|
||||
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
force_interactive = 1;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
is_login=1;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
profile = optarg;
|
||||
break;
|
||||
@@ -198,16 +204,11 @@ int main( int argc, char **argv )
|
||||
my_optind = optind;
|
||||
|
||||
is_login |= strcmp( argv[0], "-fish") == 0;
|
||||
// fwprintf( stderr, L"%s\n", argv[0] );
|
||||
|
||||
is_interactive_session &= (cmd == 0);
|
||||
is_interactive_session &= (my_optind == argc);
|
||||
is_interactive_session &= isatty(STDIN_FILENO);
|
||||
|
||||
// fwprintf( stderr, L"%d %d %d\n", cmd==0, my_optind == argc, isatty(STDIN_FILENO) );
|
||||
|
||||
if( force_interactive )
|
||||
is_interactive_session=1;
|
||||
is_interactive_session |= force_interactive;
|
||||
|
||||
translate_init();
|
||||
proc_init();
|
||||
@@ -244,7 +245,8 @@ int main( int argc, char **argv )
|
||||
int i;
|
||||
string_buffer_t sb;
|
||||
int fd;
|
||||
|
||||
wchar_t *rel_filename, *abs_filename;
|
||||
|
||||
if( ( fd = open(file, O_RDONLY) ) == -1 )
|
||||
{
|
||||
wperror( L"open" );
|
||||
@@ -267,8 +269,15 @@ int main( int argc, char **argv )
|
||||
env_set( L"argv", (wchar_t *)sb.buff, 0 );
|
||||
sb_destroy( &sb );
|
||||
}
|
||||
|
||||
reader_push_current_filename( str2wcs( file ) );
|
||||
|
||||
rel_filename = str2wcs( file );
|
||||
abs_filename = wrealpath( rel_filename, 0 );
|
||||
if( !abs_filename )
|
||||
abs_filename = wcsdup(rel_filename);
|
||||
reader_push_current_filename( intern( abs_filename ) );
|
||||
free( rel_filename );
|
||||
free( abs_filename );
|
||||
|
||||
res = reader_read( fd );
|
||||
|
||||
if( res )
|
||||
@@ -277,13 +286,13 @@ int main( int argc, char **argv )
|
||||
_(L"Error while reading file %ls\n"),
|
||||
reader_current_filename()?reader_current_filename(): _(L"Standard input") );
|
||||
}
|
||||
free(reader_pop_current_filename());
|
||||
reader_pop_current_filename();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proc_fire_event( L"PROCESS_EXIT", EVENT_EXIT, getpid(), res );
|
||||
|
||||
|
||||
proc_destroy();
|
||||
env_destroy();
|
||||
builtin_destroy();
|
||||
@@ -297,7 +306,7 @@ int main( int argc, char **argv )
|
||||
event_destroy();
|
||||
output_destroy();
|
||||
translate_destroy();
|
||||
|
||||
|
||||
intern_free_all();
|
||||
|
||||
return res;
|
||||
|
||||
422
parse_util.c
Normal file
422
parse_util.c
Normal file
@@ -0,0 +1,422 @@
|
||||
/** \file parse_util.c
|
||||
|
||||
Various utility functions for parsing a command
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <wctype.h>
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "wutil.h"
|
||||
#include "common.h"
|
||||
#include "tokenizer.h"
|
||||
#include "parse_util.h"
|
||||
|
||||
int parse_util_lineno( const wchar_t *str, int len )
|
||||
{
|
||||
static int res = 1;
|
||||
static int i=0;
|
||||
static const wchar_t *prev_str = 0;
|
||||
|
||||
static const wchar_t *prev_str2 = 0;
|
||||
static int i2 = 0;
|
||||
static int res2 = 1;
|
||||
|
||||
if( str != prev_str || i>len )
|
||||
{
|
||||
if( prev_str2 == str && i2 <= len )
|
||||
{
|
||||
const wchar_t *tmp_str = prev_str;
|
||||
int tmp_i = i;
|
||||
int tmp_res = res;
|
||||
prev_str = prev_str2;
|
||||
i=i2;
|
||||
res=res2;
|
||||
|
||||
prev_str2 = tmp_str;
|
||||
i2 = tmp_i;
|
||||
res2 = tmp_res;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev_str2 = prev_str;
|
||||
i2 = i;
|
||||
res2=res;
|
||||
|
||||
prev_str = str;
|
||||
i=0;
|
||||
res=1;
|
||||
}
|
||||
}
|
||||
|
||||
for( ; str[i] && i<len; i++ )
|
||||
{
|
||||
if( str[i] == L'\n' )
|
||||
res++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int parse_util_locate_cmdsubst( const wchar_t *in,
|
||||
const wchar_t **begin,
|
||||
const wchar_t **end,
|
||||
int allow_incomplete )
|
||||
{
|
||||
const wchar_t *pos;
|
||||
wchar_t prev=0;
|
||||
int syntax_error=0;
|
||||
int paran_count=0;
|
||||
|
||||
const wchar_t *paran_begin=0, *paran_end=0;
|
||||
|
||||
for( pos=in; *pos; pos++ )
|
||||
{
|
||||
if( prev != '\\' )
|
||||
{
|
||||
if( wcschr( L"\'\"", *pos ) )
|
||||
{
|
||||
wchar_t *end = quote_end( pos );
|
||||
if( end && *end)
|
||||
{
|
||||
pos=end;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( *pos == '(' )
|
||||
{
|
||||
if(( paran_count == 0)&&(paran_begin==0))
|
||||
paran_begin = pos;
|
||||
|
||||
paran_count++;
|
||||
}
|
||||
else if( *pos == ')' )
|
||||
{
|
||||
paran_count--;
|
||||
if( (paran_count == 0) && (paran_end == 0) )
|
||||
{
|
||||
paran_end = pos;
|
||||
break;
|
||||
}
|
||||
|
||||
if( paran_count < 0 )
|
||||
{
|
||||
syntax_error = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
prev = *pos;
|
||||
}
|
||||
|
||||
syntax_error |= (paran_count < 0 );
|
||||
syntax_error |= ((paran_count>0)&&(!allow_incomplete));
|
||||
|
||||
if( syntax_error )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( paran_begin == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
*begin = paran_begin;
|
||||
*end = paran_count?in+wcslen(in):paran_end;
|
||||
|
||||
/* assert( *begin >= in );
|
||||
assert( *begin < (in+wcslen(in) ) );
|
||||
assert( *end >= *begin );
|
||||
assert( *end < (in+wcslen(in) ) );
|
||||
*/
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void parse_util_cmdsubst_extent( const wchar_t *buff,
|
||||
int cursor_pos,
|
||||
const wchar_t **a,
|
||||
const wchar_t **b )
|
||||
{
|
||||
const wchar_t *begin, *end;
|
||||
const wchar_t *pos;
|
||||
|
||||
if( a )
|
||||
*a=0;
|
||||
if( b )
|
||||
*b = 0;
|
||||
|
||||
if( !buff )
|
||||
return;
|
||||
|
||||
pos = buff;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
int bc, ec;
|
||||
|
||||
if( parse_util_locate_cmdsubst( pos,
|
||||
&begin,
|
||||
&end,
|
||||
1 ) <= 0)
|
||||
{
|
||||
begin=buff;
|
||||
end = buff + wcslen(buff);
|
||||
break;
|
||||
}
|
||||
|
||||
if( !end )
|
||||
{
|
||||
end = buff + wcslen(buff);
|
||||
}
|
||||
|
||||
bc = begin-buff;
|
||||
ec = end-buff;
|
||||
|
||||
if(( bc < cursor_pos ) && (ec >= cursor_pos) )
|
||||
{
|
||||
begin++;
|
||||
break;
|
||||
}
|
||||
pos = end+1;
|
||||
}
|
||||
if( a )
|
||||
*a = begin;
|
||||
if( b )
|
||||
*b = end;
|
||||
}
|
||||
|
||||
/**
|
||||
Get the beginning and end of the job or process definition under the cursor
|
||||
*/
|
||||
static void job_or_process_extent( const wchar_t *buff,
|
||||
int cursor_pos,
|
||||
const wchar_t **a,
|
||||
const wchar_t **b,
|
||||
int process )
|
||||
{
|
||||
const wchar_t *begin, *end;
|
||||
int pos;
|
||||
wchar_t *buffcpy;
|
||||
int finished=0;
|
||||
|
||||
tokenizer tok;
|
||||
|
||||
if( a )
|
||||
*a=0;
|
||||
if( b )
|
||||
*b = 0;
|
||||
|
||||
parse_util_cmdsubst_extent( buff, cursor_pos, &begin, &end );
|
||||
if( !end || !begin )
|
||||
return;
|
||||
|
||||
pos = cursor_pos - (begin - buff);
|
||||
// fwprintf( stderr, L"Subshell extent: %d %d %d\n", begin-buff, end-buff, pos );
|
||||
|
||||
if( a )
|
||||
{
|
||||
*a = begin;
|
||||
}
|
||||
|
||||
if( b )
|
||||
{
|
||||
*b = end;
|
||||
}
|
||||
|
||||
buffcpy = wcsndup( begin, end-begin );
|
||||
|
||||
if( !buffcpy )
|
||||
{
|
||||
die_mem();
|
||||
}
|
||||
// fwprintf( stderr, L"Strlen: %d\n", wcslen(buffcpy ) );
|
||||
|
||||
for( tok_init( &tok, buffcpy, TOK_ACCEPT_UNFINISHED );
|
||||
tok_has_next( &tok ) && !finished;
|
||||
tok_next( &tok ) )
|
||||
{
|
||||
int tok_begin = tok_get_pos( &tok );
|
||||
// fwprintf( stderr, L".");
|
||||
|
||||
switch( tok_last_type( &tok ) )
|
||||
{
|
||||
case TOK_PIPE:
|
||||
if( !process )
|
||||
break;
|
||||
|
||||
case TOK_END:
|
||||
case TOK_BACKGROUND:
|
||||
{
|
||||
|
||||
// fwprintf( stderr, L"New cmd at %d\n", tok_begin );
|
||||
|
||||
if( tok_begin >= pos )
|
||||
{
|
||||
finished=1;
|
||||
if( b )
|
||||
*b = buff + tok_begin;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( a )
|
||||
*a = buff + tok_begin+1;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fwprintf( stderr, L"Res: %d %d\n", *a-buff, *b-buff );
|
||||
free( buffcpy);
|
||||
|
||||
tok_destroy( &tok );
|
||||
|
||||
}
|
||||
|
||||
void parse_util_process_extent( const wchar_t *buff,
|
||||
int pos,
|
||||
const wchar_t **a,
|
||||
const wchar_t **b )
|
||||
{
|
||||
job_or_process_extent( buff, pos, a, b, 1 );
|
||||
}
|
||||
|
||||
void parse_util_job_extent( const wchar_t *buff,
|
||||
int pos,
|
||||
const wchar_t **a,
|
||||
const wchar_t **b )
|
||||
{
|
||||
job_or_process_extent( buff,pos,a, b, 0 );
|
||||
}
|
||||
|
||||
|
||||
void parse_util_token_extent( const wchar_t *buff,
|
||||
int cursor_pos,
|
||||
const wchar_t **tok_begin,
|
||||
const wchar_t **tok_end,
|
||||
const wchar_t **prev_begin,
|
||||
const wchar_t **prev_end )
|
||||
{
|
||||
const wchar_t *begin, *end;
|
||||
int pos;
|
||||
wchar_t *buffcpy;
|
||||
|
||||
tokenizer tok;
|
||||
|
||||
const wchar_t *a, *b, *pa, *pb;
|
||||
|
||||
|
||||
a = b = pa = pb = 0;
|
||||
|
||||
parse_util_cmdsubst_extent( buff, cursor_pos, &begin, &end );
|
||||
|
||||
if( !end || !begin )
|
||||
return;
|
||||
|
||||
pos = cursor_pos - (begin - buff);
|
||||
|
||||
a = buff + pos;
|
||||
b = a;
|
||||
pa = buff + pos;
|
||||
pb = pa;
|
||||
|
||||
assert( begin >= buff );
|
||||
assert( begin <= (buff+wcslen(buff) ) );
|
||||
assert( end >= begin );
|
||||
assert( end <= (buff+wcslen(buff) ) );
|
||||
|
||||
buffcpy = wcsndup( begin, end-begin );
|
||||
|
||||
if( !buffcpy )
|
||||
{
|
||||
die_mem();
|
||||
}
|
||||
|
||||
for( tok_init( &tok, buffcpy, TOK_ACCEPT_UNFINISHED );
|
||||
tok_has_next( &tok );
|
||||
tok_next( &tok ) )
|
||||
{
|
||||
int tok_begin = tok_get_pos( &tok );
|
||||
int tok_end=tok_begin;
|
||||
|
||||
/*
|
||||
Calculate end of token
|
||||
*/
|
||||
if( tok_last_type( &tok ) == TOK_STRING )
|
||||
tok_end +=wcslen(tok_last(&tok));
|
||||
|
||||
/*
|
||||
Cursor was before beginning of this token, means that the
|
||||
cursor is between two tokens, so we set it to a zero element
|
||||
string and break
|
||||
*/
|
||||
if( tok_begin > pos )
|
||||
{
|
||||
a = b = buff + pos;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
If cursor is inside the token, this is the token we are
|
||||
looking for. If so, set a and b and break
|
||||
*/
|
||||
if( tok_end >= pos )
|
||||
{
|
||||
a = begin + tok_get_pos( &tok );
|
||||
b = a + wcslen(tok_last(&tok));
|
||||
|
||||
// fwprintf( stderr, L"Whee %ls\n", *a );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
Remember previous string token
|
||||
*/
|
||||
if( tok_last_type( &tok ) == TOK_STRING )
|
||||
{
|
||||
pa = begin + tok_get_pos( &tok );
|
||||
pb = pa + wcslen(tok_last(&tok));
|
||||
}
|
||||
}
|
||||
|
||||
free( buffcpy);
|
||||
|
||||
tok_destroy( &tok );
|
||||
|
||||
if( tok_begin )
|
||||
*tok_begin = a;
|
||||
if( tok_end )
|
||||
*tok_end = b;
|
||||
if( prev_begin )
|
||||
*prev_begin = pa;
|
||||
if( prev_end )
|
||||
*prev_end = pb;
|
||||
|
||||
assert( pa >= buff );
|
||||
assert( pa <= (buff+wcslen(buff) ) );
|
||||
assert( pb >= pa );
|
||||
assert( pb <= (buff+wcslen(buff) ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
53
parse_util.h
Normal file
53
parse_util.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/** \file parse_util.h
|
||||
|
||||
Various utility functions for parsing a command
|
||||
*/
|
||||
|
||||
#ifndef FISH_PARSE_UTIL_H
|
||||
#define FISH_PARSE_UTIL_H
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
/**
|
||||
Locate the first subshell in the specified string.
|
||||
|
||||
\param in the string to search for subshells
|
||||
\param begin the starting paranthesis of the subshell
|
||||
\param end the ending paranthesis of the subshell
|
||||
\param flags set this variable to ACCEPT_INCOMPLETE if in tab_completion mode
|
||||
\return -1 on syntax error, 0 if no subshells exist and 1 on sucess
|
||||
*/
|
||||
|
||||
int parse_util_locate_cmdsubst( const wchar_t *in,
|
||||
const wchar_t **begin,
|
||||
const wchar_t **end,
|
||||
int allow_incomplete );
|
||||
|
||||
|
||||
void parse_util_cmdsubst_extent( const wchar_t *buff,
|
||||
int cursor_pos,
|
||||
const wchar_t **a,
|
||||
const wchar_t **b );
|
||||
|
||||
void parse_util_process_extent( const wchar_t *buff,
|
||||
int pos,
|
||||
const wchar_t **a,
|
||||
const wchar_t **b );
|
||||
|
||||
|
||||
void parse_util_job_extent( const wchar_t *buff,
|
||||
int pos,
|
||||
const wchar_t **a,
|
||||
const wchar_t **b );
|
||||
|
||||
void parse_util_token_extent( const wchar_t *buff,
|
||||
int cursor_pos,
|
||||
const wchar_t **tok_begin,
|
||||
const wchar_t **tok_end,
|
||||
const wchar_t **prev_begin,
|
||||
const wchar_t **prev_end );
|
||||
|
||||
int parse_util_lineno( const wchar_t *str, int len );
|
||||
|
||||
|
||||
#endif
|
||||
24
parser.h
24
parser.h
@@ -10,6 +10,7 @@
|
||||
#include "proc.h"
|
||||
#include "util.h"
|
||||
#include "parser.h"
|
||||
#include "event.h"
|
||||
|
||||
/**
|
||||
event_block_t represents a block on events of the specified type
|
||||
@@ -64,6 +65,8 @@ typedef struct block
|
||||
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 or the function called*/
|
||||
const wchar_t *source_dest; /**< The name of the file to source*/
|
||||
event_t *event; /**<The event that triggered this block */
|
||||
} param1;
|
||||
|
||||
/**
|
||||
@@ -74,7 +77,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 */
|
||||
process_t *function_call_process; /**< The process representing this function call */
|
||||
} param2;
|
||||
|
||||
/**
|
||||
@@ -83,7 +86,6 @@ typedef struct block
|
||||
union
|
||||
{
|
||||
int function_is_binding; /**< Whether a function is a keybinding */
|
||||
int function_lineno; /**< Function invocation line number */
|
||||
} param3;
|
||||
|
||||
/**
|
||||
@@ -92,8 +94,17 @@ typedef struct block
|
||||
union
|
||||
{
|
||||
array_list_t *function_events;
|
||||
wchar_t *function_filename;
|
||||
} param4;
|
||||
|
||||
/**
|
||||
Name of file that created this block
|
||||
*/
|
||||
const wchar_t *src_filename;
|
||||
|
||||
/**
|
||||
Line number where this block was created
|
||||
*/
|
||||
int src_lineno;
|
||||
|
||||
/**
|
||||
Some naming confusion. This is a pointer to the first element in the list of all event blocks.
|
||||
@@ -121,6 +132,8 @@ enum block_type
|
||||
SUBST, /**< Command substitution scope */
|
||||
TOP, /**< Outermost block */
|
||||
BEGIN, /**< Unconditional block */
|
||||
SOURCE, /**< Block created by the . (source) builtin */
|
||||
EVENT, /**< Block created on event notifier invocation */
|
||||
}
|
||||
;
|
||||
|
||||
@@ -346,5 +359,10 @@ int parser_is_help( wchar_t *s, int min_match );
|
||||
*/
|
||||
const wchar_t *parser_current_filename();
|
||||
|
||||
/**
|
||||
Write a stack trace starting at the specified block to the specified string_buffer_t
|
||||
*/
|
||||
void parser_stack_trace( block_t *b, string_buffer_t *buff);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
144
proc.c
144
proc.c
@@ -53,6 +53,7 @@ Some of the code in this file is based on code from the Glibc manual.
|
||||
#include "signal.h"
|
||||
#include "event.h"
|
||||
#include "translate.h"
|
||||
#include "halloc.h"
|
||||
|
||||
/**
|
||||
Size of message buffer
|
||||
@@ -83,6 +84,7 @@ int is_login=0;
|
||||
int is_event=0;
|
||||
int proc_had_barrier;
|
||||
pid_t proc_last_bg_pid = 0;
|
||||
int job_control_mode = JOB_CONTROL_INTERACTIVE;
|
||||
|
||||
/**
|
||||
The event variable used to send all process event
|
||||
@@ -107,35 +109,6 @@ void proc_init()
|
||||
sb_init( &event_status );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Recursively free a process and those following it
|
||||
*/
|
||||
static void free_process( process_t *p )
|
||||
{
|
||||
wchar_t **arg;
|
||||
|
||||
if( p==0 )
|
||||
return;
|
||||
|
||||
|
||||
|
||||
free_process( p->next );
|
||||
debug( 3, L"Free process %ls", p->actual_cmd );
|
||||
free( p->actual_cmd );
|
||||
if( p->argv != 0 )
|
||||
{
|
||||
debug( 3, L"Process has argument vector" );
|
||||
for( arg=p->argv; *arg; arg++ )
|
||||
{
|
||||
debug( 3, L"Free argument %ls", *arg );
|
||||
free( *arg );
|
||||
}
|
||||
free(p->argv );
|
||||
}
|
||||
free( p );
|
||||
}
|
||||
|
||||
/**
|
||||
Remove job from list of jobs
|
||||
*/
|
||||
@@ -169,30 +142,8 @@ static int job_remove( job_t *j )
|
||||
*/
|
||||
void job_free( job_t * j )
|
||||
{
|
||||
io_data_t *io, *ionext;
|
||||
|
||||
// fwprintf( stderr, L"Remove job %d (%ls)\n", j->job_id, j->command );
|
||||
|
||||
job_remove( j );
|
||||
|
||||
/* Then free ourselves */
|
||||
free_process( j->first_process);
|
||||
|
||||
if( j->command != 0 )
|
||||
free( j->command );
|
||||
|
||||
for( io=j->io; io; io=ionext )
|
||||
{
|
||||
ionext = io->next;
|
||||
// fwprintf( stderr, L"Kill redirect %d of type %d\n", ionext, io->io_mode );
|
||||
if( io->io_mode == IO_FILE )
|
||||
{
|
||||
free( io->param1.filename );
|
||||
}
|
||||
free( io );
|
||||
}
|
||||
|
||||
free( j );
|
||||
halloc_free( j );
|
||||
}
|
||||
|
||||
void proc_destroy()
|
||||
@@ -225,10 +176,14 @@ job_t *job_create()
|
||||
|
||||
while( job_get( free_id ) != 0 )
|
||||
free_id++;
|
||||
res = calloc( 1, sizeof(job_t) );
|
||||
res = halloc( 0, sizeof(job_t) );
|
||||
res->next = first_job;
|
||||
res->job_id = free_id;
|
||||
first_job = res;
|
||||
|
||||
res->job_control = (job_control_mode==JOB_CONTROL_ALL) ||
|
||||
((job_control_mode == JOB_CONTROL_INTERACTIVE) && (is_interactive));
|
||||
|
||||
// if( res->job_id > 2 )
|
||||
// fwprintf( stderr, L"Create job %d\n", res->job_id );
|
||||
return res;
|
||||
@@ -388,7 +343,7 @@ static void handle_child_status( pid_t pid, int status )
|
||||
"Process %d is %ls from job %ls\n",
|
||||
(int) pid, p->actual_cmd, j->command );
|
||||
write( 2, mess, strlen(mess ));
|
||||
*/
|
||||
*/
|
||||
|
||||
mark_process_status ( j, p, status);
|
||||
if( p->completed && prev != 0 )
|
||||
@@ -583,7 +538,7 @@ int job_reap( int interactive )
|
||||
j->job_id,
|
||||
j->command,
|
||||
sig2wcs(WTERMSIG(p->status)),
|
||||
sig_description( WTERMSIG(p->status) ) );
|
||||
signal_get_desc( WTERMSIG(p->status) ) );
|
||||
else
|
||||
fwprintf( stdout,
|
||||
_( L"%ls: Process %d, \'%ls\' from job %d, \'%ls\' terminated by signal %ls (%ls)" ),
|
||||
@@ -593,7 +548,7 @@ int job_reap( int interactive )
|
||||
j->job_id,
|
||||
j->command,
|
||||
sig2wcs(WTERMSIG(p->status)),
|
||||
sig_description( WTERMSIG(p->status) ) );
|
||||
signal_get_desc( WTERMSIG(p->status) ) );
|
||||
tputs(clr_eol,1,&writeb);
|
||||
fwprintf (stdout, L"\n" );
|
||||
found=1;
|
||||
@@ -875,37 +830,33 @@ void job_continue (job_t *j, int cont)
|
||||
|
||||
if( !job_is_completed( j ) )
|
||||
{
|
||||
if( j->terminal )
|
||||
{
|
||||
|
||||
if( j->terminal && j->fg )
|
||||
{
|
||||
/* Put the job into the foreground. */
|
||||
if( j->fg )
|
||||
signal_block();
|
||||
if( tcsetpgrp (0, j->pgid) )
|
||||
{
|
||||
signal_block();
|
||||
if( tcsetpgrp (0, j->pgid) )
|
||||
{
|
||||
debug( 1,
|
||||
_( L"Could not send job %d ('%ls') to foreground" ),
|
||||
j->job_id,
|
||||
j->command );
|
||||
wperror( L"tcsetpgrp" );
|
||||
return;
|
||||
}
|
||||
|
||||
if( cont )
|
||||
{
|
||||
if( tcsetattr (0, TCSADRAIN, &j->tmodes))
|
||||
{
|
||||
debug( 1,
|
||||
_( L"Could not send job %d ('%ls') to foreground" ),
|
||||
j->job_id,
|
||||
j->command );
|
||||
wperror( L"tcsetattr" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
signal_unblock();
|
||||
debug( 1,
|
||||
_( L"Could not send job %d ('%ls') to foreground" ),
|
||||
j->job_id,
|
||||
j->command );
|
||||
wperror( L"tcsetpgrp" );
|
||||
return;
|
||||
}
|
||||
|
||||
if( cont )
|
||||
{
|
||||
if( tcsetattr (0, TCSADRAIN, &j->tmodes))
|
||||
{
|
||||
debug( 1,
|
||||
_( L"Could not send job %d ('%ls') to foreground" ),
|
||||
j->job_id,
|
||||
j->command );
|
||||
wperror( L"tcsetattr" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
signal_unblock();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -914,15 +865,28 @@ void job_continue (job_t *j, int cont)
|
||||
if( cont )
|
||||
{
|
||||
process_t *p;
|
||||
|
||||
for( p=j->first_process; p; p=p->next )
|
||||
p->stopped=0;
|
||||
for( p=j->first_process; p; p=p->next )
|
||||
|
||||
if( j->job_control )
|
||||
{
|
||||
if (kill ( p->pid, SIGCONT) < 0)
|
||||
if( killpg( j->pgid, SIGCONT ) )
|
||||
{
|
||||
wperror (L"kill (SIGCONT)");
|
||||
wperror( L"killpg (SIGCONT)" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( p=j->first_process; p; p=p->next )
|
||||
{
|
||||
if (kill ( p->pid, SIGCONT) < 0)
|
||||
{
|
||||
wperror (L"kill (SIGCONT)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -979,7 +943,7 @@ void job_continue (job_t *j, int cont)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( j->fg )
|
||||
{
|
||||
|
||||
@@ -1005,7 +969,7 @@ void job_continue (job_t *j, int cont)
|
||||
/*
|
||||
Put the shell back in the foreground.
|
||||
*/
|
||||
if( j->terminal )
|
||||
if( j->terminal && j->fg )
|
||||
{
|
||||
signal_block();
|
||||
if( tcsetpgrp (0, getpid()) )
|
||||
|
||||
23
proc.h
23
proc.h
@@ -48,6 +48,13 @@ enum
|
||||
}
|
||||
;
|
||||
|
||||
enum
|
||||
{
|
||||
JOB_CONTROL_ALL,
|
||||
JOB_CONTROL_INTERACTIVE,
|
||||
JOB_CONTROL_NONE,
|
||||
}
|
||||
;
|
||||
|
||||
/**
|
||||
A structure representing a single fish process. Contains variables
|
||||
@@ -156,9 +163,12 @@ 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 */
|
||||
/** Whether the job is under job control */
|
||||
int job_control;
|
||||
|
||||
/** Whether the job wants to own the terminal when in the foreground */
|
||||
int terminal;
|
||||
|
||||
|
||||
/** Pointer to the next job */
|
||||
struct job *next;
|
||||
}
|
||||
@@ -216,6 +226,11 @@ extern int proc_had_barrier;
|
||||
*/
|
||||
extern pid_t proc_last_bg_pid;
|
||||
|
||||
/**
|
||||
Can be one of JOB_CONTROL_ALL, JOB_CONTROL_INTERACTIVE and JOB_CONTROL_NONE
|
||||
*/
|
||||
extern int job_control_mode;
|
||||
|
||||
/**
|
||||
Sets the status of the last process to exit
|
||||
*/
|
||||
@@ -232,7 +247,9 @@ int proc_get_last_status();
|
||||
void job_free( job_t* j );
|
||||
|
||||
/**
|
||||
Create a new job
|
||||
Create a new job. Job struct is allocated using halloc, so anything
|
||||
that should be freed with the job can uset it as a halloc context
|
||||
when allocating.
|
||||
*/
|
||||
job_t *job_create();
|
||||
|
||||
|
||||
23
reader.h
23
reader.h
@@ -48,7 +48,7 @@ wchar_t *reader_current_filename();
|
||||
|
||||
\param fn The fileanme to push
|
||||
*/
|
||||
void reader_push_current_filename( wchar_t *fn );
|
||||
void reader_push_current_filename( const wchar_t *fn );
|
||||
/**
|
||||
Pop the current filename from the stack of read files
|
||||
*/
|
||||
@@ -152,27 +152,6 @@ void reader_set_prompt( wchar_t *prompt );
|
||||
*/
|
||||
int exit_status();
|
||||
|
||||
/**
|
||||
Find the beginning and the end of the current subshell
|
||||
*/
|
||||
void reader_current_subshell_extent( wchar_t **a, wchar_t **b );
|
||||
|
||||
/**
|
||||
Find the beginning and the end of the job under the cursor
|
||||
*/
|
||||
void reader_current_job_extent( wchar_t **a, wchar_t **b );
|
||||
|
||||
/**
|
||||
Find the beginning and the end of the process under the cursor
|
||||
*/
|
||||
void reader_current_process_extent( wchar_t **a, wchar_t **b );
|
||||
|
||||
/**
|
||||
Find the beginning and the end of the token under the curor and the token before the cursor
|
||||
*/
|
||||
|
||||
void reader_current_token_extent( wchar_t **a, wchar_t **b, wchar_t **pa, wchar_t **pb );
|
||||
|
||||
/**
|
||||
Replace the current token with the specified string
|
||||
*/
|
||||
|
||||
15
seq.in
15
seq.in
@@ -1,9 +1,24 @@
|
||||
#!@prefix@/bin/fish
|
||||
#
|
||||
# Fallback implementation of the seq command
|
||||
#
|
||||
# @configure_input@
|
||||
|
||||
set -l from 1
|
||||
set -l step 1
|
||||
set -l to 1
|
||||
|
||||
function _ -d "Alias for the gettext command"
|
||||
printf "%s" $argv
|
||||
end
|
||||
if test 1 = "@HAVE_GETTEXT@"
|
||||
if which gettext ^/dev/null >/dev/null
|
||||
function _ -d "Alias for the gettext command"
|
||||
gettext fish $argv
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
switch (count $argv)
|
||||
case 1
|
||||
set to $argv[1]
|
||||
|
||||
13
set_color.c
13
set_color.c
@@ -125,8 +125,13 @@ void print_colors()
|
||||
}
|
||||
}
|
||||
|
||||
static void locale_init()
|
||||
static void check_locale_init()
|
||||
{
|
||||
static int is_init = 0;
|
||||
if( is_init )
|
||||
return;
|
||||
|
||||
is_init = 1;
|
||||
setlocale( LC_ALL, "" );
|
||||
#if HAVE_GETTEXT
|
||||
bindtextdomain( PACKAGE_NAME, LOCALEDIR );
|
||||
@@ -142,7 +147,6 @@ int main( int argc, char **argv )
|
||||
int fg, bg;
|
||||
int bold=0;
|
||||
|
||||
locale_init();
|
||||
|
||||
|
||||
while( 1 )
|
||||
@@ -209,6 +213,7 @@ int main( int argc, char **argv )
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
check_locale_init();
|
||||
fprintf( stderr, _("%s, version %s\n"), SET_COLOR, PACKAGE_VERSION );
|
||||
exit( 0 );
|
||||
|
||||
@@ -235,12 +240,14 @@ int main( int argc, char **argv )
|
||||
break;
|
||||
|
||||
default:
|
||||
check_locale_init();
|
||||
printf( _("%s: Too many arguments\n"), SET_COLOR );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( !fgcolor && !bgcolor && !bold )
|
||||
{
|
||||
check_locale_init();
|
||||
fprintf( stderr, _("%s: Expected an argument\n"), SET_COLOR );
|
||||
print_help();
|
||||
return 1;
|
||||
@@ -249,6 +256,7 @@ int main( int argc, char **argv )
|
||||
fg = translate_color(fgcolor);
|
||||
if( fgcolor && (fg==-1))
|
||||
{
|
||||
check_locale_init();
|
||||
fprintf( stderr, _("%s: Unknown color '%s'\n"), SET_COLOR, fgcolor );
|
||||
return 1;
|
||||
}
|
||||
@@ -256,6 +264,7 @@ int main( int argc, char **argv )
|
||||
bg = translate_color(bgcolor);
|
||||
if( bgcolor && (bg==-1))
|
||||
{
|
||||
check_locale_init();
|
||||
fprintf( stderr, _("%s: Unknown color '%s'\n"), SET_COLOR, bgcolor );
|
||||
return 1;
|
||||
}
|
||||
|
||||
26
signal.c
26
signal.c
@@ -342,7 +342,7 @@ const wchar_t *sig2wcs( int sig )
|
||||
return L"Unknown";
|
||||
}
|
||||
|
||||
const wchar_t *sig_description( int sig )
|
||||
const wchar_t *signal_get_desc( int sig )
|
||||
{
|
||||
int i;
|
||||
for( i=0; lookup[i].desc ; i++ )
|
||||
@@ -405,7 +405,7 @@ void signal_reset_handlers()
|
||||
sigemptyset( & act.sa_mask );
|
||||
act.sa_flags=0;
|
||||
act.sa_handler=SIG_DFL;
|
||||
|
||||
|
||||
for( i=0; lookup[i].desc ; i++ )
|
||||
{
|
||||
sigaction( lookup[i].signal, &act, 0);
|
||||
@@ -433,7 +433,7 @@ void signal_set_handlers()
|
||||
sigaction( SIGTTIN, &act, 0);
|
||||
sigaction( SIGTTOU, &act, 0);
|
||||
sigaction( SIGCHLD, &act, 0);
|
||||
|
||||
|
||||
/*
|
||||
Ignore sigpipe, it is generated if fishd dies, but we can
|
||||
recover.
|
||||
@@ -448,7 +448,7 @@ void signal_set_handlers()
|
||||
*/
|
||||
|
||||
act.sa_handler=SIG_IGN;
|
||||
|
||||
|
||||
sigaction( SIGINT, &act, 0);
|
||||
sigaction( SIGQUIT, &act, 0);
|
||||
sigaction( SIGTSTP, &act, 0);
|
||||
@@ -535,28 +535,14 @@ void signal_handle( int sig, int do_handle )
|
||||
|
||||
void signal_block()
|
||||
{
|
||||
int i;
|
||||
sigset_t chldset;
|
||||
sigemptyset( &chldset );
|
||||
|
||||
for( i=0; lookup[i].desc ; i++ )
|
||||
{
|
||||
sigaddset( &chldset, lookup[i].signal );
|
||||
}
|
||||
|
||||
sigfillset( &chldset );
|
||||
sigprocmask(SIG_BLOCK, &chldset, 0);
|
||||
}
|
||||
|
||||
void signal_unblock()
|
||||
{
|
||||
int i;
|
||||
sigset_t chldset;
|
||||
sigemptyset( &chldset );
|
||||
|
||||
for( i=0; lookup[i].desc ; i++ )
|
||||
{
|
||||
sigaddset( &chldset, lookup[i].signal );
|
||||
}
|
||||
|
||||
sigfillset( &chldset );
|
||||
sigprocmask(SIG_UNBLOCK, &chldset, 0);
|
||||
}
|
||||
|
||||
2
signal.h
2
signal.h
@@ -18,7 +18,7 @@ const wchar_t *sig2wcs( int sig );
|
||||
/**
|
||||
Returns a description of the specified signal.
|
||||
*/
|
||||
const wchar_t *sig_description( int sig );
|
||||
const wchar_t *signal_get_desc( int sig );
|
||||
|
||||
/**
|
||||
Set all signal handlers to SIG_DFL
|
||||
|
||||
56
tokenizer.c
56
tokenizer.c
@@ -116,15 +116,15 @@ static void tok_error( tokenizer *tok, const wchar_t *err )
|
||||
void tok_init( tokenizer *tok, const wchar_t *b, int flags )
|
||||
{
|
||||
// fwprintf( stderr, L"CREATE: \'%ls\'\n", b );
|
||||
|
||||
|
||||
|
||||
memset( tok, 0, sizeof( tokenizer) );
|
||||
|
||||
|
||||
tok->accept_unfinished = flags & TOK_ACCEPT_UNFINISHED;
|
||||
tok->show_comments = flags & TOK_SHOW_COMMENTS;
|
||||
tok->has_next=1;
|
||||
tok->has_next=1;
|
||||
|
||||
/*
|
||||
/*
|
||||
Before we copy the buffer we need to check that it is not
|
||||
null. But before that, we need to init the tokenizer far enough
|
||||
so that errors can be properly flagged
|
||||
@@ -137,7 +137,7 @@ void tok_init( tokenizer *tok, const wchar_t *b, int flags )
|
||||
|
||||
tok->has_next = (*b != L'\0');
|
||||
tok->orig_buff = tok->buff = (wchar_t *)(b);
|
||||
|
||||
|
||||
if( tok->accept_unfinished )
|
||||
{
|
||||
int l = wcslen( tok->orig_buff );
|
||||
@@ -149,7 +149,7 @@ void tok_init( tokenizer *tok, const wchar_t *b, int flags )
|
||||
tok->orig_buff = tok->buff = wcsdup( tok->orig_buff );
|
||||
if( !tok->orig_buff )
|
||||
{
|
||||
die_mem();
|
||||
die_mem();
|
||||
}
|
||||
tok->orig_buff[l-1] = L'\0';
|
||||
}
|
||||
@@ -223,7 +223,7 @@ static void read_string( tokenizer *tok )
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
|
||||
|
||||
if( !myal( *tok->buff ) )
|
||||
{
|
||||
// debug(1, L"%lc", *tok->buff );
|
||||
@@ -260,7 +260,7 @@ static void read_string( tokenizer *tok )
|
||||
mode = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case L'[':
|
||||
{
|
||||
if( tok->buff != start )
|
||||
@@ -271,7 +271,7 @@ static void read_string( tokenizer *tok )
|
||||
case L'\'':
|
||||
case L'"':
|
||||
{
|
||||
|
||||
|
||||
wchar_t *end = quote_end( tok->buff );
|
||||
tok->last_quote = *tok->buff;
|
||||
if( end )
|
||||
@@ -281,14 +281,14 @@ static void read_string( tokenizer *tok )
|
||||
else
|
||||
{
|
||||
tok->buff += wcslen( tok->buff );
|
||||
|
||||
|
||||
if( (!tok->accept_unfinished) )
|
||||
{
|
||||
tok_error( tok, EOL_ERROR );
|
||||
return;
|
||||
}
|
||||
do_loop = 0;
|
||||
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -303,7 +303,7 @@ static void read_string( tokenizer *tok )
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 3:
|
||||
case 1:
|
||||
switch( *tok->buff )
|
||||
@@ -355,7 +355,7 @@ static void read_string( tokenizer *tok )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if( !do_loop )
|
||||
break;
|
||||
@@ -408,7 +408,7 @@ static void read_comment( tokenizer *tok )
|
||||
static void read_redirect( tokenizer *tok, int fd )
|
||||
{
|
||||
int mode = -1;
|
||||
|
||||
|
||||
if( (*tok->buff == L'>') ||
|
||||
(*tok->buff == L'^') )
|
||||
{
|
||||
@@ -430,7 +430,7 @@ static void read_redirect( tokenizer *tok, int fd )
|
||||
tok_error( tok, PIPE_ERROR );
|
||||
return;
|
||||
}
|
||||
check_size( tok, FD_STR_MAX_LEN );
|
||||
check_size( tok, FD_STR_MAX_LEN );
|
||||
tok->buff++;
|
||||
swprintf( tok->last, FD_STR_MAX_LEN, L"%d", fd );
|
||||
tok->last_type = TOK_PIPE;
|
||||
@@ -446,14 +446,14 @@ static void read_redirect( tokenizer *tok, int fd )
|
||||
{
|
||||
tok_error( tok, REDIRECT_ERROR);
|
||||
}
|
||||
|
||||
|
||||
if( !check_size( tok, 2 ))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
swprintf( tok->last, tok->last_len, L"%d", fd );
|
||||
|
||||
|
||||
if( *tok->buff == L'&' )
|
||||
{
|
||||
tok->buff++;
|
||||
@@ -496,10 +496,10 @@ void tok_next( tokenizer *tok )
|
||||
|
||||
if( tok_last_type( tok ) == TOK_ERROR )
|
||||
{
|
||||
tok->has_next=0;
|
||||
return;
|
||||
tok->has_next=0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if( !tok->has_next )
|
||||
{
|
||||
/* wprintf( L"EOL\n" );*/
|
||||
@@ -551,9 +551,9 @@ void tok_next( tokenizer *tok )
|
||||
|
||||
case L'|':
|
||||
check_size( tok, 2 );
|
||||
|
||||
|
||||
tok->last[0]=L'1';
|
||||
tok->last[1]=L'\0';
|
||||
tok->last[1]=L'\0';
|
||||
tok->last_type = TOK_PIPE;
|
||||
tok->buff++;
|
||||
break;
|
||||
@@ -567,9 +567,9 @@ void tok_next( tokenizer *tok )
|
||||
|
||||
default:
|
||||
{
|
||||
|
||||
|
||||
if( iswdigit( *tok->buff ) )
|
||||
{
|
||||
{
|
||||
wchar_t *orig = tok->buff;
|
||||
int fd = 0;
|
||||
while( iswdigit( *tok->buff ) )
|
||||
@@ -583,11 +583,11 @@ void tok_next( tokenizer *tok )
|
||||
read_redirect( tok, fd );
|
||||
return;
|
||||
}
|
||||
tok->buff = orig;
|
||||
tok->buff = orig;
|
||||
}
|
||||
read_string( tok );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -603,7 +603,7 @@ wchar_t *tok_first( const wchar_t *str )
|
||||
wchar_t *res=0;
|
||||
|
||||
tok_init( &t, str, 0 );
|
||||
|
||||
|
||||
switch( tok_last_type( &t ) )
|
||||
{
|
||||
case TOK_STRING:
|
||||
|
||||
41
translate.c
41
translate.c
@@ -43,6 +43,22 @@ static char *wcs2str_buff=0;
|
||||
*/
|
||||
static size_t wcs2str_buff_count=0;
|
||||
|
||||
static int is_init = 0;
|
||||
|
||||
static void internal_init()
|
||||
{
|
||||
int i;
|
||||
|
||||
is_init = 1;
|
||||
|
||||
for(i=0; i<BUFF_COUNT; i++ )
|
||||
sb_init( &buff[i] );
|
||||
|
||||
bindtextdomain( PACKAGE_NAME, LOCALEDIR );
|
||||
textdomain( PACKAGE_NAME );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Wide to narrow character conversion. Internal implementation that
|
||||
avoids exessive calls to malloc
|
||||
@@ -70,7 +86,10 @@ const wchar_t *wgettext( const wchar_t *in )
|
||||
{
|
||||
if( !in )
|
||||
return in;
|
||||
|
||||
|
||||
if( !is_init )
|
||||
internal_init();
|
||||
|
||||
char *mbs_in = translate_wcs2str( in );
|
||||
char *out = gettext( mbs_in );
|
||||
wchar_t *wres=0;
|
||||
@@ -81,30 +100,22 @@ const wchar_t *wgettext( const wchar_t *in )
|
||||
wres = (wchar_t *)buff[curr_buff].buff;
|
||||
curr_buff = (curr_buff+1)%BUFF_COUNT;
|
||||
|
||||
/*
|
||||
write( 2, res, strlen(res) );
|
||||
*/
|
||||
// debug( 1, L"%ls -> %s (%d) -> %ls (%d)\n", in, out, strlen(out) , wres, wcslen(wres) );
|
||||
|
||||
return wres;
|
||||
}
|
||||
|
||||
|
||||
void translate_init()
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<BUFF_COUNT; i++ )
|
||||
sb_init( &buff[i] );
|
||||
|
||||
bindtextdomain( PACKAGE_NAME, LOCALEDIR );
|
||||
textdomain( PACKAGE_NAME );
|
||||
|
||||
}
|
||||
|
||||
void translate_destroy()
|
||||
{
|
||||
int i;
|
||||
|
||||
if( !is_init )
|
||||
return;
|
||||
|
||||
is_init = 0;
|
||||
|
||||
for(i=0; i<BUFF_COUNT; i++ )
|
||||
sb_destroy( &buff[i] );
|
||||
@@ -114,8 +125,6 @@ void translate_destroy()
|
||||
|
||||
#else
|
||||
|
||||
int _nl_msg_cat_cntr=0;
|
||||
|
||||
const wchar_t *wgettext( const wchar_t *in )
|
||||
{
|
||||
return in;
|
||||
|
||||
25
util.c
25
util.c
@@ -511,6 +511,20 @@ int hash_wcs_cmp( const void *a, const void *b )
|
||||
return wcscmp((wchar_t *)a,(wchar_t *)b) == 0;
|
||||
}
|
||||
|
||||
int hash_ptr_func( const void *data )
|
||||
{
|
||||
return (int)(long) data;
|
||||
}
|
||||
|
||||
/**
|
||||
Hash comparison function suitable for direct pointer comparison
|
||||
*/
|
||||
int hash_ptr_cmp( const void *a,
|
||||
const void *b )
|
||||
{
|
||||
return a == b;
|
||||
}
|
||||
|
||||
void pq_init( priority_queue_t *q,
|
||||
int (*compare)(void *e1, void *e2) )
|
||||
{
|
||||
@@ -893,19 +907,16 @@ void sb_append_substring( string_buffer_t *b, const wchar_t *s, size_t l )
|
||||
|
||||
void sb_append_char( string_buffer_t *b, wchar_t c )
|
||||
{
|
||||
wchar_t buff[2]=
|
||||
{
|
||||
c, 0
|
||||
}
|
||||
;
|
||||
wchar_t tmp=0;
|
||||
|
||||
if( !b )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sb_append( b, buff );
|
||||
|
||||
b_append( b, &c, sizeof(wchar_t) );
|
||||
b_append( b, &tmp, sizeof(wchar_t) );
|
||||
b->used -= sizeof(wchar_t);
|
||||
}
|
||||
|
||||
void sb_append2( string_buffer_t *b, ... )
|
||||
|
||||
16
util.h
16
util.h
@@ -232,7 +232,7 @@ const void *hash_get_key( hash_table_t *h,
|
||||
*/
|
||||
int hash_get_count( hash_table_t *h);
|
||||
/**
|
||||
Remove the specified key from the hash table
|
||||
Remove the specified key from the hash table if it exists. Do nothing if it does not exist.
|
||||
|
||||
\param h The hashtable
|
||||
\param key The key
|
||||
@@ -298,6 +298,20 @@ int hash_wcs_func( const void *data );
|
||||
int hash_wcs_cmp( const void *a,
|
||||
const void *b );
|
||||
|
||||
/**
|
||||
Hash function suitable for direct pointer comparison
|
||||
*/
|
||||
int hash_ptr_func( const void *data );
|
||||
|
||||
|
||||
/**
|
||||
Hash comparison function suitable for direct pointer comparison
|
||||
*/
|
||||
int hash_ptr_cmp( const void *a,
|
||||
const void *b );
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Initialize the priority queue
|
||||
|
||||
|
||||
768
wgetopt.c
768
wgetopt.c
@@ -29,25 +29,25 @@
|
||||
before changing it!
|
||||
|
||||
Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94
|
||||
Free Software Foundation, Inc.
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU C Library. Its master source is NOT part of
|
||||
the C library, however. The master source lives in /gd/gnu/lib.
|
||||
This file is part of the GNU C Library. Its master source is NOT part of
|
||||
the C library, however. The master source lives in /gd/gnu/lib.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
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. */
|
||||
You should have received a copy of the GNU Library General Public
|
||||
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. */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
@@ -139,41 +139,51 @@ int woptopt = '?';
|
||||
|
||||
/* Describe how to deal with options that follow non-option ARGV-elements.
|
||||
|
||||
If the caller did not specify anything,
|
||||
the default is REQUIRE_ORDER if the environment variable
|
||||
POSIXLY_CORRECT is defined, PERMUTE otherwise.
|
||||
If the caller did not specify anything,
|
||||
the default is REQUIRE_ORDER if the environment variable
|
||||
POSIXLY_CORRECT is defined, PERMUTE otherwise.
|
||||
|
||||
REQUIRE_ORDER means don't recognize them as options;
|
||||
stop option processing when the first non-option is seen.
|
||||
This is what Unix does.
|
||||
This mode of operation is selected by either setting the environment
|
||||
variable POSIXLY_CORRECT, or using `+' as the first character
|
||||
of the list of option characters.
|
||||
REQUIRE_ORDER means don't recognize them as options;
|
||||
stop option processing when the first non-option is seen.
|
||||
This is what Unix does.
|
||||
This mode of operation is selected by either setting the environment
|
||||
variable POSIXLY_CORRECT, or using `+' as the first character
|
||||
of the list of option characters.
|
||||
|
||||
PERMUTE is the default. We permute the contents of ARGV as we scan,
|
||||
so that eventually all the non-options are at the end. This allows options
|
||||
to be given in any order, even with programs that were not written to
|
||||
expect this.
|
||||
PERMUTE is the default. We permute the contents of ARGV as we scan,
|
||||
so that eventually all the non-options are at the end. This allows options
|
||||
to be given in any order, even with programs that were not written to
|
||||
expect this.
|
||||
|
||||
RETURN_IN_ORDER is an option available to programs that were written
|
||||
to expect options and other ARGV-elements in any order and that care about
|
||||
the ordering of the two. We describe each non-option ARGV-element
|
||||
as if it were the argument of an option with character code 1.
|
||||
Using `-' as the first character of the list of option characters
|
||||
selects this mode of operation.
|
||||
RETURN_IN_ORDER is an option available to programs that were written
|
||||
to expect options and other ARGV-elements in any order and that care about
|
||||
the ordering of the two. We describe each non-option ARGV-element
|
||||
as if it were the argument of an option with character code 1.
|
||||
Using `-' as the first character of the list of option characters
|
||||
selects this mode of operation.
|
||||
|
||||
The special argument `--' forces an end of option-scanning regardless
|
||||
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
|
||||
`--' can cause `getopt' to return EOF with `woptind' != ARGC. */
|
||||
The special argument `--' forces an end of option-scanning regardless
|
||||
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
|
||||
`--' can cause `getopt' to return EOF with `woptind' != ARGC. */
|
||||
|
||||
static enum
|
||||
{
|
||||
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
||||
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
||||
} ordering;
|
||||
|
||||
/* Value of POSIXLY_CORRECT environment variable. */
|
||||
static char *posixly_correct;
|
||||
|
||||
/**
|
||||
Use translation functions if available
|
||||
*/
|
||||
#ifdef HAVE_TRANSLATE_H
|
||||
#include "translate.h"
|
||||
#define _(wstr) wgettext(wstr)
|
||||
#else
|
||||
#define _(wstr) wstr
|
||||
#endif
|
||||
|
||||
#ifdef __GNU_LIBRARY__
|
||||
/* We want to avoid inclusion of string.h with non-GNU libraries
|
||||
because there are many ways it can cause trouble.
|
||||
@@ -190,16 +200,16 @@ char *getenv ();
|
||||
|
||||
static wchar_t *
|
||||
my_index (str, chr)
|
||||
const wchar_t *str;
|
||||
int chr;
|
||||
const wchar_t *str;
|
||||
int chr;
|
||||
{
|
||||
while (*str)
|
||||
while (*str)
|
||||
{
|
||||
if (*str == chr)
|
||||
return (wchar_t *) str;
|
||||
str++;
|
||||
if (*str == chr)
|
||||
return (wchar_t *) str;
|
||||
str++;
|
||||
}
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If using GCC, we can safely declare strlen this way.
|
||||
@@ -236,94 +246,94 @@ static int last_nonopt;
|
||||
|
||||
static void
|
||||
exchange (argv)
|
||||
wchar_t **argv;
|
||||
wchar_t **argv;
|
||||
{
|
||||
int bottom = first_nonopt;
|
||||
int middle = last_nonopt;
|
||||
int top = woptind;
|
||||
wchar_t *tem;
|
||||
int bottom = first_nonopt;
|
||||
int middle = last_nonopt;
|
||||
int top = woptind;
|
||||
wchar_t *tem;
|
||||
|
||||
/* Exchange the shorter segment with the far end of the longer segment.
|
||||
That puts the shorter segment into the right place.
|
||||
It leaves the longer segment in the right place overall,
|
||||
but it consists of two parts that need to be swapped next. */
|
||||
/* Exchange the shorter segment with the far end of the longer segment.
|
||||
That puts the shorter segment into the right place.
|
||||
It leaves the longer segment in the right place overall,
|
||||
but it consists of two parts that need to be swapped next. */
|
||||
|
||||
while (top > middle && middle > bottom)
|
||||
while (top > middle && middle > bottom)
|
||||
{
|
||||
if (top - middle > middle - bottom)
|
||||
{
|
||||
/* Bottom segment is the short one. */
|
||||
int len = middle - bottom;
|
||||
register int i;
|
||||
if (top - middle > middle - bottom)
|
||||
{
|
||||
/* Bottom segment is the short one. */
|
||||
int len = middle - bottom;
|
||||
register int i;
|
||||
|
||||
/* Swap it with the top part of the top segment. */
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
tem = argv[bottom + i];
|
||||
argv[bottom + i] = argv[top - (middle - bottom) + i];
|
||||
argv[top - (middle - bottom) + i] = tem;
|
||||
}
|
||||
/* Exclude the moved bottom segment from further swapping. */
|
||||
top -= len;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Top segment is the short one. */
|
||||
int len = top - middle;
|
||||
register int i;
|
||||
/* Swap it with the top part of the top segment. */
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
tem = argv[bottom + i];
|
||||
argv[bottom + i] = argv[top - (middle - bottom) + i];
|
||||
argv[top - (middle - bottom) + i] = tem;
|
||||
}
|
||||
/* Exclude the moved bottom segment from further swapping. */
|
||||
top -= len;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Top segment is the short one. */
|
||||
int len = top - middle;
|
||||
register int i;
|
||||
|
||||
/* Swap it with the bottom part of the bottom segment. */
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
tem = argv[bottom + i];
|
||||
argv[bottom + i] = argv[middle + i];
|
||||
argv[middle + i] = tem;
|
||||
}
|
||||
/* Exclude the moved top segment from further swapping. */
|
||||
bottom += len;
|
||||
}
|
||||
/* Swap it with the bottom part of the bottom segment. */
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
tem = argv[bottom + i];
|
||||
argv[bottom + i] = argv[middle + i];
|
||||
argv[middle + i] = tem;
|
||||
}
|
||||
/* Exclude the moved top segment from further swapping. */
|
||||
bottom += len;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update records for the slots the non-options now occupy. */
|
||||
/* Update records for the slots the non-options now occupy. */
|
||||
|
||||
first_nonopt += (woptind - last_nonopt);
|
||||
last_nonopt = woptind;
|
||||
first_nonopt += (woptind - last_nonopt);
|
||||
last_nonopt = woptind;
|
||||
}
|
||||
|
||||
/* Initialize the internal data when the first call is made. */
|
||||
|
||||
static const wchar_t *
|
||||
_wgetopt_initialize (optstring)
|
||||
const wchar_t *optstring;
|
||||
const wchar_t *optstring;
|
||||
{
|
||||
/* Start processing options with ARGV-element 1 (since ARGV-element 0
|
||||
is the program name); the sequence of previously skipped
|
||||
non-option ARGV-elements is empty. */
|
||||
/* Start processing options with ARGV-element 1 (since ARGV-element 0
|
||||
is the program name); the sequence of previously skipped
|
||||
non-option ARGV-elements is empty. */
|
||||
|
||||
first_nonopt = last_nonopt = woptind = 1;
|
||||
first_nonopt = last_nonopt = woptind = 1;
|
||||
|
||||
nextchar = NULL;
|
||||
nextchar = NULL;
|
||||
|
||||
posixly_correct = getenv ("POSIXLY_CORRECT");
|
||||
posixly_correct = getenv ("POSIXLY_CORRECT");
|
||||
|
||||
/* Determine how to handle the ordering of options and nonoptions. */
|
||||
/* Determine how to handle the ordering of options and nonoptions. */
|
||||
|
||||
if (optstring[0] == '-')
|
||||
if (optstring[0] == '-')
|
||||
{
|
||||
ordering = RETURN_IN_ORDER;
|
||||
++optstring;
|
||||
ordering = RETURN_IN_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (optstring[0] == '+')
|
||||
else if (optstring[0] == '+')
|
||||
{
|
||||
ordering = REQUIRE_ORDER;
|
||||
++optstring;
|
||||
ordering = REQUIRE_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (posixly_correct != NULL)
|
||||
ordering = REQUIRE_ORDER;
|
||||
else
|
||||
ordering = PERMUTE;
|
||||
else if (posixly_correct != NULL)
|
||||
ordering = REQUIRE_ORDER;
|
||||
else
|
||||
ordering = PERMUTE;
|
||||
|
||||
return optstring;
|
||||
return optstring;
|
||||
}
|
||||
|
||||
/* Scan elements of ARGV (whose length is ARGC) for option characters
|
||||
@@ -384,321 +394,321 @@ _wgetopt_initialize (optstring)
|
||||
|
||||
int
|
||||
_wgetopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
int argc;
|
||||
wchar_t *const *argv;
|
||||
const wchar_t *optstring;
|
||||
const struct woption *longopts;
|
||||
int *longind;
|
||||
int long_only;
|
||||
int argc;
|
||||
wchar_t *const *argv;
|
||||
const wchar_t *optstring;
|
||||
const struct woption *longopts;
|
||||
int *longind;
|
||||
int long_only;
|
||||
{
|
||||
woptarg = NULL;
|
||||
woptarg = NULL;
|
||||
|
||||
if (woptind == 0)
|
||||
optstring = _wgetopt_initialize (optstring);
|
||||
if (woptind == 0)
|
||||
optstring = _wgetopt_initialize (optstring);
|
||||
|
||||
if (nextchar == NULL || *nextchar == '\0')
|
||||
if (nextchar == NULL || *nextchar == '\0')
|
||||
{
|
||||
/* Advance to the next ARGV-element. */
|
||||
/* Advance to the next ARGV-element. */
|
||||
|
||||
if (ordering == PERMUTE)
|
||||
{
|
||||
/* If we have just processed some options following some non-options,
|
||||
exchange them so that the options come first. */
|
||||
if (ordering == PERMUTE)
|
||||
{
|
||||
/* If we have just processed some options following some non-options,
|
||||
exchange them so that the options come first. */
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != woptind)
|
||||
exchange ((wchar_t **) argv);
|
||||
else if (last_nonopt != woptind)
|
||||
first_nonopt = woptind;
|
||||
if (first_nonopt != last_nonopt && last_nonopt != woptind)
|
||||
exchange ((wchar_t **) argv);
|
||||
else if (last_nonopt != woptind)
|
||||
first_nonopt = woptind;
|
||||
|
||||
/* Skip any additional non-options
|
||||
and extend the range of non-options previously skipped. */
|
||||
/* Skip any additional non-options
|
||||
and extend the range of non-options previously skipped. */
|
||||
|
||||
while (woptind < argc
|
||||
&& (argv[woptind][0] != '-' || argv[woptind][1] == '\0'))
|
||||
woptind++;
|
||||
last_nonopt = woptind;
|
||||
}
|
||||
while (woptind < argc
|
||||
&& (argv[woptind][0] != '-' || argv[woptind][1] == '\0'))
|
||||
woptind++;
|
||||
last_nonopt = woptind;
|
||||
}
|
||||
|
||||
/* The special ARGV-element `--' means premature end of options.
|
||||
Skip it like a null option,
|
||||
then exchange with previous non-options as if it were an option,
|
||||
then skip everything else like a non-option. */
|
||||
/* The special ARGV-element `--' means premature end of options.
|
||||
Skip it like a null option,
|
||||
then exchange with previous non-options as if it were an option,
|
||||
then skip everything else like a non-option. */
|
||||
|
||||
if (woptind != argc && !wcscmp (argv[woptind], L"--"))
|
||||
{
|
||||
woptind++;
|
||||
if (woptind != argc && !wcscmp (argv[woptind], L"--"))
|
||||
{
|
||||
woptind++;
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != woptind)
|
||||
exchange ((wchar_t **) argv);
|
||||
else if (first_nonopt == last_nonopt)
|
||||
first_nonopt = woptind;
|
||||
last_nonopt = argc;
|
||||
if (first_nonopt != last_nonopt && last_nonopt != woptind)
|
||||
exchange ((wchar_t **) argv);
|
||||
else if (first_nonopt == last_nonopt)
|
||||
first_nonopt = woptind;
|
||||
last_nonopt = argc;
|
||||
|
||||
woptind = argc;
|
||||
}
|
||||
woptind = argc;
|
||||
}
|
||||
|
||||
/* If we have done all the ARGV-elements, stop the scan
|
||||
and back over any non-options that we skipped and permuted. */
|
||||
/* If we have done all the ARGV-elements, stop the scan
|
||||
and back over any non-options that we skipped and permuted. */
|
||||
|
||||
if (woptind == argc)
|
||||
{
|
||||
/* Set the next-arg-index to point at the non-options
|
||||
that we previously skipped, so the caller will digest them. */
|
||||
if (first_nonopt != last_nonopt)
|
||||
woptind = first_nonopt;
|
||||
return EOF;
|
||||
}
|
||||
if (woptind == argc)
|
||||
{
|
||||
/* Set the next-arg-index to point at the non-options
|
||||
that we previously skipped, so the caller will digest them. */
|
||||
if (first_nonopt != last_nonopt)
|
||||
woptind = first_nonopt;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* If we have come to a non-option and did not permute it,
|
||||
either stop the scan or describe it to the caller and pass it by. */
|
||||
/* If we have come to a non-option and did not permute it,
|
||||
either stop the scan or describe it to the caller and pass it by. */
|
||||
|
||||
if ((argv[woptind][0] != '-' || argv[woptind][1] == '\0'))
|
||||
{
|
||||
if (ordering == REQUIRE_ORDER)
|
||||
return EOF;
|
||||
woptarg = argv[woptind++];
|
||||
return 1;
|
||||
}
|
||||
if ((argv[woptind][0] != '-' || argv[woptind][1] == '\0'))
|
||||
{
|
||||
if (ordering == REQUIRE_ORDER)
|
||||
return EOF;
|
||||
woptarg = argv[woptind++];
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* We have found another option-ARGV-element.
|
||||
Skip the initial punctuation. */
|
||||
/* We have found another option-ARGV-element.
|
||||
Skip the initial punctuation. */
|
||||
|
||||
nextchar = (argv[woptind] + 1
|
||||
+ (longopts != NULL && argv[woptind][1] == '-'));
|
||||
nextchar = (argv[woptind] + 1
|
||||
+ (longopts != NULL && argv[woptind][1] == '-'));
|
||||
}
|
||||
|
||||
/* Decode the current option-ARGV-element. */
|
||||
/* Decode the current option-ARGV-element. */
|
||||
|
||||
/* Check whether the ARGV-element is a long option.
|
||||
/* Check whether the ARGV-element is a long option.
|
||||
|
||||
If long_only and the ARGV-element has the form "-f", where f is
|
||||
a valid short option, don't consider it an abbreviated form of
|
||||
a long option that starts with f. Otherwise there would be no
|
||||
way to give the -f short option.
|
||||
If long_only and the ARGV-element has the form "-f", where f is
|
||||
a valid short option, don't consider it an abbreviated form of
|
||||
a long option that starts with f. Otherwise there would be no
|
||||
way to give the -f short option.
|
||||
|
||||
On the other hand, if there's a long option "fubar" and
|
||||
the ARGV-element is "-fu", do consider that an abbreviation of
|
||||
the long option, just like "--fu", and not "-f" with arg "u".
|
||||
On the other hand, if there's a long option "fubar" and
|
||||
the ARGV-element is "-fu", do consider that an abbreviation of
|
||||
the long option, just like "--fu", and not "-f" with arg "u".
|
||||
|
||||
This distinction seems to be the most useful approach. */
|
||||
This distinction seems to be the most useful approach. */
|
||||
|
||||
if (longopts != NULL
|
||||
&& (argv[woptind][1] == '-'
|
||||
|| (long_only && (argv[woptind][2] || !my_index (optstring, argv[woptind][1])))))
|
||||
if (longopts != NULL
|
||||
&& (argv[woptind][1] == '-'
|
||||
|| (long_only && (argv[woptind][2] || !my_index (optstring, argv[woptind][1])))))
|
||||
{
|
||||
wchar_t *nameend;
|
||||
const struct woption *p;
|
||||
const struct woption *pfound = NULL;
|
||||
int exact = 0;
|
||||
int ambig = 0;
|
||||
int indfound = 0; /* set to zero by Anton */
|
||||
int option_index;
|
||||
wchar_t *nameend;
|
||||
const struct woption *p;
|
||||
const struct woption *pfound = NULL;
|
||||
int exact = 0;
|
||||
int ambig = 0;
|
||||
int indfound = 0; /* set to zero by Anton */
|
||||
int option_index;
|
||||
|
||||
for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
|
||||
/* Do nothing. */ ;
|
||||
for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
|
||||
/* Do nothing. */ ;
|
||||
|
||||
/* Test all long options for either exact match
|
||||
or abbreviated matches. */
|
||||
for (p = longopts, option_index = 0; p->name; p++, option_index++)
|
||||
if (!wcsncmp(p->name, nextchar, nameend - nextchar))
|
||||
{
|
||||
if ((unsigned int)(nameend - nextchar) == (unsigned int)wcslen (p->name))
|
||||
{
|
||||
/* Exact match found. */
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
exact = 1;
|
||||
break;
|
||||
}
|
||||
else if (pfound == NULL)
|
||||
{
|
||||
/* First nonexact match found. */
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
}
|
||||
else
|
||||
/* Second or later nonexact match found. */
|
||||
ambig = 1;
|
||||
}
|
||||
/* Test all long options for either exact match
|
||||
or abbreviated matches. */
|
||||
for (p = longopts, option_index = 0; p->name; p++, option_index++)
|
||||
if (!wcsncmp(p->name, nextchar, nameend - nextchar))
|
||||
{
|
||||
if ((unsigned int)(nameend - nextchar) == (unsigned int)wcslen (p->name))
|
||||
{
|
||||
/* Exact match found. */
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
exact = 1;
|
||||
break;
|
||||
}
|
||||
else if (pfound == NULL)
|
||||
{
|
||||
/* First nonexact match found. */
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
}
|
||||
else
|
||||
/* Second or later nonexact match found. */
|
||||
ambig = 1;
|
||||
}
|
||||
|
||||
if (ambig && !exact)
|
||||
{
|
||||
if (wopterr)
|
||||
fwprintf (stderr, L"%ls: option `%ls' is ambiguous\n",
|
||||
argv[0], argv[woptind]);
|
||||
nextchar += wcslen (nextchar);
|
||||
woptind++;
|
||||
return '?';
|
||||
}
|
||||
|
||||
if (pfound != NULL)
|
||||
{
|
||||
option_index = indfound;
|
||||
woptind++;
|
||||
if (*nameend)
|
||||
{
|
||||
/* Don't test has_arg with >, because some C compilers don't
|
||||
allow it to be used on enums. */
|
||||
if (pfound->has_arg)
|
||||
woptarg = nameend + 1;
|
||||
else
|
||||
if (ambig && !exact)
|
||||
{
|
||||
if (wopterr)
|
||||
{
|
||||
if (argv[woptind - 1][1] == '-')
|
||||
/* --option */
|
||||
fwprintf (stderr,
|
||||
L"%ls: option `--%ls' doesn't allow an argument\n",
|
||||
argv[0], pfound->name);
|
||||
else
|
||||
/* +option or -option */
|
||||
fwprintf (stderr,
|
||||
L"%ls: option `%lc%ls' doesn't allow an argument\n",
|
||||
argv[0], argv[woptind - 1][0], pfound->name);
|
||||
}
|
||||
nextchar += wcslen (nextchar);
|
||||
return '?';
|
||||
if (wopterr)
|
||||
fwprintf (stderr, _(L"%ls: Option `%ls' is ambiguous\n"),
|
||||
argv[0], argv[woptind]);
|
||||
nextchar += wcslen (nextchar);
|
||||
woptind++;
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
else if (pfound->has_arg == 1)
|
||||
{
|
||||
if (woptind < argc)
|
||||
woptarg = argv[woptind++];
|
||||
else
|
||||
{
|
||||
if (wopterr)
|
||||
fwprintf (stderr, L"%ls: option `%ls' requires an argument\n",
|
||||
argv[0], argv[woptind - 1]);
|
||||
nextchar += wcslen (nextchar);
|
||||
return optstring[0] == ':' ? ':' : '?';
|
||||
}
|
||||
}
|
||||
nextchar += wcslen (nextchar);
|
||||
if (longind != NULL)
|
||||
*longind = option_index;
|
||||
if (pfound->flag)
|
||||
{
|
||||
*(pfound->flag) = pfound->val;
|
||||
return 0;
|
||||
}
|
||||
return pfound->val;
|
||||
}
|
||||
|
||||
/* Can't find it as a long option. If this is not getopt_long_only,
|
||||
or the option starts with '--' or is not a valid short
|
||||
option, then it's an error.
|
||||
Otherwise interpret it as a short option. */
|
||||
if (!long_only || argv[woptind][1] == '-'
|
||||
|| my_index (optstring, *nextchar) == NULL)
|
||||
{
|
||||
if (wopterr)
|
||||
{
|
||||
if (argv[woptind][1] == '-')
|
||||
/* --option */
|
||||
fwprintf (stderr, L"%ls: unrecognized option `--%ls'\n",
|
||||
argv[0], nextchar);
|
||||
else
|
||||
/* +option or -option */
|
||||
fwprintf (stderr, L"%ls: unrecognized option `%lc%ls'\n",
|
||||
argv[0], argv[woptind][0], nextchar);
|
||||
}
|
||||
nextchar = (wchar_t *) L"";
|
||||
woptind++;
|
||||
return '?';
|
||||
}
|
||||
if (pfound != NULL)
|
||||
{
|
||||
option_index = indfound;
|
||||
woptind++;
|
||||
if (*nameend)
|
||||
{
|
||||
/* Don't test has_arg with >, because some C compilers don't
|
||||
allow it to be used on enums. */
|
||||
if (pfound->has_arg)
|
||||
woptarg = nameend + 1;
|
||||
else
|
||||
{
|
||||
if (wopterr)
|
||||
{
|
||||
if (argv[woptind - 1][1] == '-')
|
||||
/* --option */
|
||||
fwprintf (stderr,
|
||||
_(L"%ls: Option `--%ls' doesn't allow an argument\n"),
|
||||
argv[0], pfound->name);
|
||||
else
|
||||
/* +option or -option */
|
||||
fwprintf (stderr,
|
||||
_(L"%ls: Option `%lc%ls' doesn't allow an argument\n"),
|
||||
argv[0], argv[woptind - 1][0], pfound->name);
|
||||
}
|
||||
nextchar += wcslen (nextchar);
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
else if (pfound->has_arg == 1)
|
||||
{
|
||||
if (woptind < argc)
|
||||
woptarg = argv[woptind++];
|
||||
else
|
||||
{
|
||||
if (wopterr)
|
||||
fwprintf (stderr, _(L"%ls: Option `%ls' requires an argument\n"),
|
||||
argv[0], argv[woptind - 1]);
|
||||
nextchar += wcslen (nextchar);
|
||||
return optstring[0] == ':' ? ':' : '?';
|
||||
}
|
||||
}
|
||||
nextchar += wcslen (nextchar);
|
||||
if (longind != NULL)
|
||||
*longind = option_index;
|
||||
if (pfound->flag)
|
||||
{
|
||||
*(pfound->flag) = pfound->val;
|
||||
return 0;
|
||||
}
|
||||
return pfound->val;
|
||||
}
|
||||
|
||||
/* Can't find it as a long option. If this is not getopt_long_only,
|
||||
or the option starts with '--' or is not a valid short
|
||||
option, then it's an error.
|
||||
Otherwise interpret it as a short option. */
|
||||
if (!long_only || argv[woptind][1] == '-'
|
||||
|| my_index (optstring, *nextchar) == NULL)
|
||||
{
|
||||
if (wopterr)
|
||||
{
|
||||
if (argv[woptind][1] == '-')
|
||||
/* --option */
|
||||
fwprintf (stderr, _(L"%ls: Unrecognized option `--%ls'\n"),
|
||||
argv[0], nextchar);
|
||||
else
|
||||
/* +option or -option */
|
||||
fwprintf (stderr, _(L"%ls: Unrecognized option `%lc%ls'\n"),
|
||||
argv[0], argv[woptind][0], nextchar);
|
||||
}
|
||||
nextchar = (wchar_t *) L"";
|
||||
woptind++;
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
/* Look at and handle the next short option-character. */
|
||||
/* Look at and handle the next short option-character. */
|
||||
|
||||
{
|
||||
wchar_t c = *nextchar++;
|
||||
wchar_t *temp = my_index (optstring, c);
|
||||
{
|
||||
wchar_t c = *nextchar++;
|
||||
wchar_t *temp = my_index (optstring, c);
|
||||
|
||||
/* Increment `woptind' when we start to process its last character. */
|
||||
if (*nextchar == '\0')
|
||||
++woptind;
|
||||
/* Increment `woptind' when we start to process its last character. */
|
||||
if (*nextchar == '\0')
|
||||
++woptind;
|
||||
|
||||
if (temp == NULL || c == ':')
|
||||
{
|
||||
if (wopterr)
|
||||
{
|
||||
if (posixly_correct)
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fwprintf (stderr, L"%ls: illegal option -- %lc\n", argv[0], c);
|
||||
else
|
||||
fwprintf (stderr, L"%ls: invalid option -- %lc\n", argv[0], c);
|
||||
}
|
||||
woptopt = c;
|
||||
return '?';
|
||||
}
|
||||
if (temp[1] == ':')
|
||||
{
|
||||
if (temp[2] == ':')
|
||||
{
|
||||
/* This is an option that accepts an argument optionally. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
woptarg = nextchar;
|
||||
woptind++;
|
||||
}
|
||||
else
|
||||
woptarg = NULL;
|
||||
nextchar = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is an option that requires an argument. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
woptarg = nextchar;
|
||||
/* If we end this ARGV-element by taking the rest as an arg,
|
||||
we must advance to the next element now. */
|
||||
woptind++;
|
||||
}
|
||||
else if (woptind == argc)
|
||||
{
|
||||
if (wopterr)
|
||||
{
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fwprintf (stderr, L"%ls: option requires an argument -- %lc\n",
|
||||
argv[0], c);
|
||||
}
|
||||
woptopt = c;
|
||||
if (optstring[0] == ':')
|
||||
c = ':';
|
||||
else
|
||||
c = '?';
|
||||
}
|
||||
else
|
||||
/* We already incremented `woptind' once;
|
||||
increment it again when taking next ARGV-elt as argument. */
|
||||
woptarg = argv[woptind++];
|
||||
nextchar = NULL;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
if (temp == NULL || c == ':')
|
||||
{
|
||||
if (wopterr)
|
||||
{
|
||||
if (posixly_correct)
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fwprintf (stderr, _(L"%ls: Illegal option -- %lc\n"), argv[0], c);
|
||||
else
|
||||
fwprintf (stderr, _(L"%ls: Invalid option -- %lc\n"), argv[0], c);
|
||||
}
|
||||
woptopt = c;
|
||||
return '?';
|
||||
}
|
||||
if (temp[1] == ':')
|
||||
{
|
||||
if (temp[2] == ':')
|
||||
{
|
||||
/* This is an option that accepts an argument optionally. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
woptarg = nextchar;
|
||||
woptind++;
|
||||
}
|
||||
else
|
||||
woptarg = NULL;
|
||||
nextchar = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is an option that requires an argument. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
woptarg = nextchar;
|
||||
/* If we end this ARGV-element by taking the rest as an arg,
|
||||
we must advance to the next element now. */
|
||||
woptind++;
|
||||
}
|
||||
else if (woptind == argc)
|
||||
{
|
||||
if (wopterr)
|
||||
{
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fwprintf (stderr, _(L"%ls: Option requires an argument -- %lc\n"),
|
||||
argv[0], c);
|
||||
}
|
||||
woptopt = c;
|
||||
if (optstring[0] == ':')
|
||||
c = ':';
|
||||
else
|
||||
c = '?';
|
||||
}
|
||||
else
|
||||
/* We already incremented `woptind' once;
|
||||
increment it again when taking next ARGV-elt as argument. */
|
||||
woptarg = argv[woptind++];
|
||||
nextchar = NULL;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
wgetopt (argc, argv, optstring)
|
||||
int argc;
|
||||
wchar_t *const *argv;
|
||||
const wchar_t *optstring;
|
||||
int argc;
|
||||
wchar_t *const *argv;
|
||||
const wchar_t *optstring;
|
||||
{
|
||||
return _wgetopt_internal (argc, argv, optstring,
|
||||
(const struct woption *) 0,
|
||||
(int *) 0,
|
||||
0);
|
||||
return _wgetopt_internal (argc, argv, optstring,
|
||||
(const struct woption *) 0,
|
||||
(int *) 0,
|
||||
0);
|
||||
}
|
||||
|
||||
int
|
||||
wgetopt_long (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
wchar_t *const *argv;
|
||||
const wchar_t *options;
|
||||
const struct woption *long_options;
|
||||
int *opt_index;
|
||||
wchar_t *const *argv;
|
||||
const wchar_t *options;
|
||||
const struct woption *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _wgetopt_internal (argc, argv, options, long_options, opt_index, 0);
|
||||
}
|
||||
@@ -706,10 +716,10 @@ wgetopt_long (argc, argv, options, long_options, opt_index)
|
||||
int
|
||||
wgetopt_long_only (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
wchar_t *const *argv;
|
||||
const wchar_t *options;
|
||||
const struct woption *long_options;
|
||||
int *opt_index;
|
||||
wchar_t *const *argv;
|
||||
const wchar_t *options;
|
||||
const struct woption *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _wgetopt_internal (argc, argv, options, long_options, opt_index, 1);
|
||||
}
|
||||
|
||||
105
wutil.c
105
wutil.c
@@ -26,6 +26,14 @@
|
||||
|
||||
#define TMP_LEN_MIN 256
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#ifdef MAXPATHLEN
|
||||
#define PATH_MAX MAXPATHLEN
|
||||
#else
|
||||
#define PATH_MAX 4096
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
Buffer for converting wide arguments to narrow arguments, used by
|
||||
the \c wutil_wcs2str() function.
|
||||
@@ -60,9 +68,16 @@ void wutil_destroy()
|
||||
*/
|
||||
static char *wutil_wcs2str( const wchar_t *in )
|
||||
{
|
||||
size_t res=0;
|
||||
int in_pos=0;
|
||||
int out_pos = 0;
|
||||
mbstate_t state;
|
||||
size_t new_sz;
|
||||
|
||||
wutil_calls++;
|
||||
memset( &state, 0, sizeof(state) );
|
||||
|
||||
size_t new_sz =MAX_UTF8_BYTES*wcslen(in)+1;
|
||||
new_sz =MAX_UTF8_BYTES*wcslen(in)+1;
|
||||
if( tmp_len < new_sz )
|
||||
{
|
||||
new_sz = maxi( new_sz, TMP_LEN_MIN );
|
||||
@@ -74,8 +89,37 @@ static char *wutil_wcs2str( const wchar_t *in )
|
||||
tmp_len = new_sz;
|
||||
}
|
||||
|
||||
wcstombs( tmp, in, tmp_len );
|
||||
return tmp;
|
||||
while( in[in_pos] )
|
||||
{
|
||||
if( ( in[in_pos] >= ENCODE_DIRECT_BASE) &&
|
||||
( in[in_pos] < ENCODE_DIRECT_BASE+256) )
|
||||
{
|
||||
tmp[out_pos++] = in[in_pos]- ENCODE_DIRECT_BASE;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = wcrtomb( &tmp[out_pos], in[in_pos], &state );
|
||||
|
||||
switch( res )
|
||||
{
|
||||
case (size_t)(-1):
|
||||
{
|
||||
debug( 1, L"Wide character has no narrow representation" );
|
||||
memset( &state, 0, sizeof(state) );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
out_pos += res;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
in_pos++;
|
||||
}
|
||||
tmp[out_pos] = 0;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
wchar_t *wgetcwd( wchar_t *buff, size_t sz )
|
||||
@@ -219,6 +263,61 @@ void wperror(const wchar_t *s)
|
||||
fwprintf( stderr, L"%s\n", strerror( errno ) );
|
||||
}
|
||||
|
||||
#ifdef HAVE_REALPATH_NULL
|
||||
|
||||
wchar_t *wrealpath(const wchar_t *pathname, wchar_t *resolved_path)
|
||||
{
|
||||
char *tmp = wutil_wcs2str(pathname);
|
||||
char *narrow_res = realpath( tmp, 0 );
|
||||
wchar_t *res;
|
||||
|
||||
if( !narrow_res )
|
||||
return 0;
|
||||
|
||||
if( resolved_path )
|
||||
{
|
||||
wchar_t *tmp2 = str2wcs( narrow_res );
|
||||
wcslcpy( resolved_path, tmp2, PATH_MAX );
|
||||
free( tmp2 );
|
||||
res = resolved_path;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = str2wcs( narrow_res );
|
||||
}
|
||||
|
||||
free( narrow_res );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
wchar_t *wrealpath(const wchar_t *pathname, wchar_t *resolved_path)
|
||||
{
|
||||
char *tmp =wutil_wcs2str(pathname);
|
||||
char narrow[PATH_MAX];
|
||||
char *narrow_res = realpath( tmp, narrow );
|
||||
wchar_t *res;
|
||||
|
||||
if( !narrow_res )
|
||||
return 0;
|
||||
|
||||
if( resolved_path )
|
||||
{
|
||||
wchar_t *tmp2 = str2wcs( narrow_res );
|
||||
wcslcpy( resolved_path, tmp2, PATH_MAX );
|
||||
free( tmp2 );
|
||||
res = resolved_path;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = str2wcs( narrow_res );
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !HAVE_FWPRINTF
|
||||
|
||||
|
||||
10
wutil.h
10
wutil.h
@@ -7,6 +7,8 @@
|
||||
#ifndef FISH_WUTIL_H
|
||||
#define FISH_WUTIL_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
@@ -81,6 +83,14 @@ wchar_t *wgetcwd( wchar_t *buff, size_t sz );
|
||||
*/
|
||||
int wchdir( const wchar_t * dir );
|
||||
|
||||
/**
|
||||
Wide character version of realpath function. Just like the GNU
|
||||
version of realpath, wrealpath will accept 0 as the value for the
|
||||
second argument, in which case the result will be allocated using
|
||||
malloc, and must be free'd by the user.
|
||||
*/
|
||||
wchar_t *wrealpath(const wchar_t *pathname, wchar_t *resolved_path);
|
||||
|
||||
/*
|
||||
Here follows the prototypes for fallback implementations of various
|
||||
standarcs libc functions relating to wide character support. Some of
|
||||
|
||||
Reference in New Issue
Block a user