mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-24 14:01:15 -03:00
Compare commits
56 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
780ecc46fc | ||
|
|
9b98df8310 | ||
|
|
5a8205ac2b | ||
|
|
2490da31ce | ||
|
|
092bb90569 | ||
|
|
39ca027706 | ||
|
|
22433f2717 | ||
|
|
f6e194447d | ||
|
|
e2ed5d0977 | ||
|
|
fe5bf8f80e | ||
|
|
0a713a7939 | ||
|
|
4ba2709452 | ||
|
|
0c877183b9 | ||
|
|
a46be4cadb | ||
|
|
8b4637e900 | ||
|
|
ab13c4caad | ||
|
|
479696a8ec | ||
|
|
acde745e34 | ||
|
|
064d49215a | ||
|
|
78d3b37e11 | ||
|
|
12aa33fad4 | ||
|
|
e4ade8f41b | ||
|
|
9d7723b330 | ||
|
|
2bc2e0b9ec | ||
|
|
02083a1bd7 | ||
|
|
e534a952b7 | ||
|
|
754d8d3712 | ||
|
|
86230813de | ||
|
|
2faba57e5a | ||
|
|
3789127d28 | ||
|
|
32e833f331 | ||
|
|
9b4c34aa4c | ||
|
|
e2ebc0e443 | ||
|
|
8ff66e718c | ||
|
|
2789da6a1a | ||
|
|
51c345311a | ||
|
|
4a68a34c50 | ||
|
|
9993ff07f2 | ||
|
|
fc8b56da0d | ||
|
|
02981a1750 | ||
|
|
c2e6b07b35 | ||
|
|
8fcacdd5df | ||
|
|
6bf58e44f4 | ||
|
|
bda7948719 | ||
|
|
e800fca499 | ||
|
|
eed4b75389 | ||
|
|
5974dd68b0 | ||
|
|
680c0aff05 | ||
|
|
4a2bdeebef | ||
|
|
dfa251a1ab | ||
|
|
82cb97d3e3 | ||
|
|
7d334914f7 | ||
|
|
27a60f465d | ||
|
|
279159384e | ||
|
|
d748e05cb9 | ||
|
|
d50c051eec |
16
Makefile.in
16
Makefile.in
@@ -134,9 +134,9 @@ MAIN_DIR_FILES := Doxyfile Doxyfile.user Makefile.in configure \
|
|||||||
config.guess fish_tests.c main.c fish_pager.c fishd.c
|
config.guess fish_tests.c main.c fish_pager.c fishd.c
|
||||||
|
|
||||||
# Files in ./init/
|
# Files in ./init/
|
||||||
INIT_DIR_FILES :=init/fish.in init/fish_complete.fish \
|
INIT_DIR_FILES :=init/fish.in init/fish_complete.fish.in \
|
||||||
init/fish_function.fish init/fish_inputrc \
|
init/fish_function.fish init/fish_inputrc \
|
||||||
init/fish_interactive.fish
|
init/fish_interactive.fish.in
|
||||||
|
|
||||||
# Files in ./tests/
|
# Files in ./tests/
|
||||||
TESTS_DIR_FILES := $(TEST_IN) $(TEST_IN:.in=.out) $(TEST_IN:.in=.err) \
|
TESTS_DIR_FILES := $(TEST_IN) $(TEST_IN:.in=.out) $(TEST_IN:.in=.err) \
|
||||||
@@ -283,7 +283,9 @@ install: all
|
|||||||
$(INSTALL) -m 644 init/fish_inputrc $(DESTDIR)$(sysconfdir)$(fishinputfile);
|
$(INSTALL) -m 644 init/fish_inputrc $(DESTDIR)$(sysconfdir)$(fishinputfile);
|
||||||
$(INSTALL) -m 755 -d $(DESTDIR)$(docdir)
|
$(INSTALL) -m 755 -d $(DESTDIR)$(docdir)
|
||||||
for i in user_doc/html/* ChangeLog; do \
|
for i in user_doc/html/* ChangeLog; do \
|
||||||
$(INSTALL) -m 644 $$i $(DESTDIR)$(docdir); \
|
if test -f $$i; then \
|
||||||
|
$(INSTALL) -m 644 $$i $(DESTDIR)$(docdir); \
|
||||||
|
fi; \
|
||||||
done;
|
done;
|
||||||
$(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man1
|
$(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man1
|
||||||
for i in $(MANUALS); do \
|
for i in $(MANUALS); do \
|
||||||
@@ -374,10 +376,16 @@ rpm: fish-@PACKAGE_VERSION@.tar.bz2
|
|||||||
mv /usr/src/redhat/RPMS/*/fish*@PACKAGE_VERSION@*.rpm .
|
mv /usr/src/redhat/RPMS/*/fish*@PACKAGE_VERSION@*.rpm .
|
||||||
mv /usr/src/redhat/SRPMS/fish*@PACKAGE_VERSION@*.src.rpm .
|
mv /usr/src/redhat/SRPMS/fish*@PACKAGE_VERSION@*.src.rpm .
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
rm -f fish.spec doc_src/fish.1 doc_src/Doxyfile
|
||||||
|
rm -f init/fish init/fish_interactive.fish init/fish_complete.fish
|
||||||
|
rm -f config.status config.log config.h Makefile
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o doc.h doc_src/*.doxygen doc_src/*.c builtin_help.c
|
rm -f *.o doc.h doc_src/*.doxygen doc_src/*.c builtin_help.c
|
||||||
rm -f config.status config.log config.h Makefile
|
rm -f tests/tmp.err tests/tmp.out tests/tmp.status tests/foo.txt
|
||||||
rm -f tokenizer_test fish key_reader set_color tokenize gen_hdr2 mimedb
|
rm -f tokenizer_test fish key_reader set_color tokenize gen_hdr2 mimedb
|
||||||
|
rm -f fishd fish_pager count
|
||||||
rm -f fish-@PACKAGE_VERSION@.tar
|
rm -f fish-@PACKAGE_VERSION@.tar
|
||||||
rm -f fish-@PACKAGE_VERSION@.tar.gz
|
rm -f fish-@PACKAGE_VERSION@.tar.gz
|
||||||
rm -f fish-@PACKAGE_VERSION@.tar.bz2
|
rm -f fish-@PACKAGE_VERSION@.tar.bz2
|
||||||
|
|||||||
38
builtin.c
38
builtin.c
@@ -1321,6 +1321,31 @@ static int builtin_read( wchar_t **argv )
|
|||||||
builtin_print_help( argv[0], sb_err );
|
builtin_print_help( argv[0], sb_err );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Verify all variable names
|
||||||
|
*/
|
||||||
|
for( i=woptind; i<argc; i++ )
|
||||||
|
{
|
||||||
|
wchar_t *src;
|
||||||
|
|
||||||
|
if( !wcslen( argv[i] ) )
|
||||||
|
{
|
||||||
|
sb_printf( sb_err, BUILTIN_ERR_VARNAME_ZERO, argv[0] );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( src=argv[i]; *src; src++ )
|
||||||
|
{
|
||||||
|
if( (!iswalnum(*src)) && (*src != L'_' ) )
|
||||||
|
{
|
||||||
|
sb_printf( sb_err, BUILTIN_ERR_VARCHAR, argv[0], *src );
|
||||||
|
sb_append2(sb_err, parser_current_line(), L"\n", (void *)0 );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The call to reader_readline may change woptind, so we save it away here
|
The call to reader_readline may change woptind, so we save it away here
|
||||||
@@ -1957,22 +1982,13 @@ static int builtin_complete( wchar_t **argv )
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The source builtin. Can be called through either 'source' or
|
The . (dot) builtin, sometimes called source. Evaluates the contents of a file.
|
||||||
'.'. Evaluates the contents of a file.
|
|
||||||
*/
|
*/
|
||||||
static int builtin_source( wchar_t ** argv )
|
static int builtin_source( wchar_t ** argv )
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
/*
|
|
||||||
if( wcsstr( argv[1], L"fish_complete" ) )
|
|
||||||
{
|
|
||||||
fwprintf( stderr, L"Woot\n" );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if( (argv[1] == 0) || (argv[2]!=0) )
|
if( (argv[1] == 0) || (argv[2]!=0) )
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -2331,7 +2347,7 @@ static int builtin_jobs( wchar_t **argv )
|
|||||||
sb_printf( sb_out, L"%d\t%d\t", j->job_id, j->pgid );
|
sb_printf( sb_out, L"%d\t%d\t", j->job_id, j->pgid );
|
||||||
|
|
||||||
#ifdef HAVE__PROC_SELF_STAT
|
#ifdef HAVE__PROC_SELF_STAT
|
||||||
sb_printf( sb_out, L"%d\t", cpu_use(j) );
|
sb_printf( sb_out, L"%d%%\t", cpu_use(j) );
|
||||||
#endif
|
#endif
|
||||||
sb_append2( sb_out, job_is_stopped(j)?L"stopped\t":L"running\t",
|
sb_append2( sb_out, job_is_stopped(j)?L"stopped\t":L"running\t",
|
||||||
// job_is_completed(j)?L"completed\t":L"unfinished\t",
|
// job_is_completed(j)?L"completed\t":L"unfinished\t",
|
||||||
|
|||||||
@@ -42,6 +42,10 @@ enum
|
|||||||
*/
|
*/
|
||||||
#define BUILTIN_ERR_UNKNOWN L": Unknown option"
|
#define BUILTIN_ERR_UNKNOWN L": Unknown option"
|
||||||
|
|
||||||
|
#define BUILTIN_ERR_VARCHAR L"%ls: Invalid character in variable name: '%lc'. Only alphanumerical characters and underscores are valid in a variable name.\n"
|
||||||
|
|
||||||
|
#define BUILTIN_ERR_VARNAME_ZERO L"%ls: Variable name can not be the empty string\n"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Stringbuffer used to represent standard output
|
Stringbuffer used to represent standard output
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -40,10 +40,8 @@ static int parse_fill_name( string_buffer_t *name,
|
|||||||
|
|
||||||
if (*src != L'[' && *src != L'\0')
|
if (*src != L'[' && *src != L'\0')
|
||||||
{
|
{
|
||||||
|
sb_printf( sb_err, BUILTIN_ERR_VARCHAR, L"set", *src );
|
||||||
sb_append(sb_err, L"set: Invalid character in variable name: ");
|
sb_append2(sb_err, parser_current_line(), L"\n", (void *)0 );
|
||||||
sb_append_char(sb_err, *src);
|
|
||||||
sb_append2(sb_err, L"\n", parser_current_line(), L"\n", (void *)0 );
|
|
||||||
// builtin_print_help( L"set", sb_err );
|
// builtin_print_help( L"set", sb_err );
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@@ -83,7 +81,7 @@ static int parse_fill_indexes( array_list_t *indexes,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (iswblank(*src))
|
while (iswspace(*src))
|
||||||
{
|
{
|
||||||
src++;
|
src++;
|
||||||
}
|
}
|
||||||
@@ -105,7 +103,7 @@ static int parse_fill_indexes( array_list_t *indexes,
|
|||||||
al_push(indexes, ind);
|
al_push(indexes, ind);
|
||||||
src = end;
|
src = end;
|
||||||
count++;
|
count++;
|
||||||
while (iswblank(*src)) src++;
|
while (iswspace(*src)) src++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
@@ -435,6 +433,13 @@ int builtin_set( wchar_t **argv )
|
|||||||
{
|
{
|
||||||
dest = wcsdup(argv[woptind++]);
|
dest = wcsdup(argv[woptind++]);
|
||||||
//fwprintf(stderr, L"Dest: %ls\n", dest);
|
//fwprintf(stderr, L"Dest: %ls\n", dest);
|
||||||
|
|
||||||
|
if( !wcslen( dest ) )
|
||||||
|
{
|
||||||
|
free( dest );
|
||||||
|
sb_printf( sb_err, BUILTIN_ERR_VARNAME_ZERO, argv[0] );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse values */
|
/* Parse values */
|
||||||
|
|||||||
@@ -35,6 +35,10 @@ struct resource_t
|
|||||||
Switch used on commandline to specify resource
|
Switch used on commandline to specify resource
|
||||||
*/
|
*/
|
||||||
wchar_t switch_char;
|
wchar_t switch_char;
|
||||||
|
/**
|
||||||
|
The implicit multiplier used when setting getting values
|
||||||
|
*/
|
||||||
|
int multiplier;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -44,49 +48,55 @@ struct resource_t
|
|||||||
const static struct resource_t resource_arr[] =
|
const static struct resource_t resource_arr[] =
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
RLIMIT_CORE, L"Maximum size of core files created", L'c'
|
RLIMIT_CORE, L"Maximum size of core files created", L'c', 1024
|
||||||
}
|
}
|
||||||
,
|
,
|
||||||
{
|
{
|
||||||
RLIMIT_DATA, L"Maximum size of a process’s data segment", L'd'
|
RLIMIT_DATA, L"Maximum size of a process’s data segment", L'd', 1024
|
||||||
}
|
}
|
||||||
,
|
,
|
||||||
{
|
{
|
||||||
RLIMIT_FSIZE, L"Maximum size of files created by the shell", L'f'
|
RLIMIT_FSIZE, L"Maximum size of files created by the shell", L'f', 1024
|
||||||
|
}
|
||||||
|
,
|
||||||
|
#if HAVE_RLIMIT_MEMLOCK
|
||||||
|
{
|
||||||
|
RLIMIT_MEMLOCK, L"Maximum size that may be locked into memory", L'l', 1024
|
||||||
|
}
|
||||||
|
,
|
||||||
|
#endif
|
||||||
|
#if HAVE_RLIMIT_RSS
|
||||||
|
{
|
||||||
|
RLIMIT_RSS, L"Maximum resident set size", L'm', 1024
|
||||||
|
}
|
||||||
|
,
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
RLIMIT_NOFILE, L"Maximum number of open file descriptors", L'n', 1
|
||||||
}
|
}
|
||||||
,
|
,
|
||||||
{
|
{
|
||||||
RLIMIT_MEMLOCK, L"Maximum size that may be locked into memory", L'l'
|
RLIMIT_STACK, L"Maximum stack size", L's', 1024
|
||||||
}
|
}
|
||||||
,
|
,
|
||||||
{
|
{
|
||||||
RLIMIT_RSS, L"Maximum resident set size", L'm'
|
RLIMIT_CPU, L"Maximum amount of cpu time in seconds", L't', 1
|
||||||
}
|
}
|
||||||
,
|
,
|
||||||
|
#if HAVE_RLIMIT_NPROC
|
||||||
{
|
{
|
||||||
RLIMIT_NOFILE, L"Maximum number of open file descriptors", L'n'
|
RLIMIT_NPROC, L"Maximum number of processes available to a single user", L'u', 1
|
||||||
}
|
|
||||||
,
|
|
||||||
{
|
|
||||||
RLIMIT_STACK, L"Maximum stack size", L's'
|
|
||||||
}
|
|
||||||
,
|
|
||||||
{
|
|
||||||
RLIMIT_CPU, L"Maximum amount of cpu time in seconds", L't'
|
|
||||||
}
|
|
||||||
,
|
|
||||||
{
|
|
||||||
RLIMIT_NPROC, L"Maximum number of processes available to a single user", L'u'
|
|
||||||
}
|
}
|
||||||
,
|
,
|
||||||
|
#endif
|
||||||
#if HAVE_RLIMIT_AS
|
#if HAVE_RLIMIT_AS
|
||||||
{
|
{
|
||||||
RLIMIT_AS, L"Maximum amount of virtual memory available to the shell", L'v'
|
RLIMIT_AS, L"Maximum amount of virtual memory available to the shell", L'v', 1024
|
||||||
}
|
}
|
||||||
,
|
,
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
0, 0
|
0, 0, 0, 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@@ -96,13 +106,16 @@ const static struct resource_t resource_arr[] =
|
|||||||
*/
|
*/
|
||||||
static int get_multiplier( int what )
|
static int get_multiplier( int what )
|
||||||
{
|
{
|
||||||
if( ( what == RLIMIT_NPROC ) ||
|
int i;
|
||||||
( what == RLIMIT_NOFILE ) ||
|
|
||||||
( what == RLIMIT_CPU ) )
|
for( i=0; resource_arr[i].desc; i++ )
|
||||||
{
|
{
|
||||||
return 1;
|
if( resource_arr[i].resource == what )
|
||||||
|
{
|
||||||
|
return resource_arr[i].multiplier;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 1024;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -365,14 +378,17 @@ int builtin_ulimit( wchar_t ** argv )
|
|||||||
case L'f':
|
case L'f':
|
||||||
what=RLIMIT_FSIZE;
|
what=RLIMIT_FSIZE;
|
||||||
break;
|
break;
|
||||||
|
#if HAVE_RLIMIT_MEMLOCK
|
||||||
case L'l':
|
case L'l':
|
||||||
what=RLIMIT_MEMLOCK;
|
what=RLIMIT_MEMLOCK;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_RLIMIT_RSS
|
||||||
case L'm':
|
case L'm':
|
||||||
what=RLIMIT_RSS;
|
what=RLIMIT_RSS;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case L'n':
|
case L'n':
|
||||||
what=RLIMIT_NOFILE;
|
what=RLIMIT_NOFILE;
|
||||||
@@ -385,10 +401,12 @@ int builtin_ulimit( wchar_t ** argv )
|
|||||||
case L't':
|
case L't':
|
||||||
what=RLIMIT_CPU;
|
what=RLIMIT_CPU;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#if HAVE_RLIMIT_NPROC
|
||||||
case L'u':
|
case L'u':
|
||||||
what=RLIMIT_NPROC;
|
what=RLIMIT_NPROC;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if HAVE_RLIMIT_AS
|
#if HAVE_RLIMIT_AS
|
||||||
case L'v':
|
case L'v':
|
||||||
|
|||||||
585
common.c
585
common.c
@@ -13,6 +13,7 @@ parts of fish.
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <wctype.h>
|
#include <wctype.h>
|
||||||
@@ -314,8 +315,7 @@ char **wcsv2strv( const wchar_t **in )
|
|||||||
char **res = malloc( sizeof( char *)*(count+1));
|
char **res = malloc( sizeof( char *)*(count+1));
|
||||||
if( res == 0 )
|
if( res == 0 )
|
||||||
{
|
{
|
||||||
die_mem();
|
die_mem();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for( i=0; i<count; i++ )
|
for( i=0; i<count; i++ )
|
||||||
@@ -353,8 +353,10 @@ wchar_t *wcsdupcat2( const wchar_t *a, ... )
|
|||||||
|
|
||||||
wchar_t *res = malloc( sizeof(wchar_t)*(len +1 ));
|
wchar_t *res = malloc( sizeof(wchar_t)*(len +1 ));
|
||||||
if( res == 0 )
|
if( res == 0 )
|
||||||
return 0;
|
{
|
||||||
|
die_mem();
|
||||||
|
}
|
||||||
|
|
||||||
wcscpy( res, a );
|
wcscpy( res, a );
|
||||||
pos = wcslen(a);
|
pos = wcslen(a);
|
||||||
while( (arg=va_arg(va2, wchar_t *) )!= 0 )
|
while( (arg=va_arg(va2, wchar_t *) )!= 0 )
|
||||||
@@ -489,17 +491,6 @@ long wcstol(const wchar_t *nptr,
|
|||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
Appends src to string dst of size siz (unlike wcsncat, siz is the
|
|
||||||
full size of dst, not space left). At most siz-1 characters will be
|
|
||||||
copied. Always NUL terminates (unless siz <= wcslen(dst)). Returns
|
|
||||||
wcslen(src) + MIN(siz, wcslen(initial dst)). If retval >= siz,
|
|
||||||
truncation occurred.
|
|
||||||
|
|
||||||
This is the OpenBSD strlcat function, modified for wide characters,
|
|
||||||
and renamed to reflect this change.
|
|
||||||
|
|
||||||
*/
|
|
||||||
size_t
|
size_t
|
||||||
wcslcat(wchar_t *dst, const wchar_t *src, size_t siz)
|
wcslcat(wchar_t *dst, const wchar_t *src, size_t siz)
|
||||||
{
|
{
|
||||||
@@ -552,14 +543,6 @@ wcslcat(wchar_t *dst, const wchar_t *src, size_t siz)
|
|||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
Copy src to string dst of size siz. At most siz-1 characters will
|
|
||||||
be copied. Always NUL terminates (unless siz == 0). Returns
|
|
||||||
wcslen(src); if retval >= siz, truncation occurred.
|
|
||||||
|
|
||||||
This is the OpenBSD strlcpy function, modified for wide characters,
|
|
||||||
and renamed to reflect this change.
|
|
||||||
*/
|
|
||||||
size_t
|
size_t
|
||||||
wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz)
|
wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz)
|
||||||
{
|
{
|
||||||
@@ -591,9 +574,6 @@ wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz)
|
|||||||
/* count does not include NUL */
|
/* count does not include NUL */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Fallback implementation if missing from libc
|
|
||||||
*/
|
|
||||||
wchar_t *wcsdup( const wchar_t *in )
|
wchar_t *wcsdup( const wchar_t *in )
|
||||||
{
|
{
|
||||||
size_t len=wcslen(in);
|
size_t len=wcslen(in);
|
||||||
@@ -601,7 +581,6 @@ wchar_t *wcsdup( const wchar_t *in )
|
|||||||
if( out == 0 )
|
if( out == 0 )
|
||||||
{
|
{
|
||||||
die_mem();
|
die_mem();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy( out, in, sizeof( wchar_t)*(len+1));
|
memcpy( out, in, sizeof( wchar_t)*(len+1));
|
||||||
@@ -706,43 +685,25 @@ int my_wcswidth( const wchar_t *c )
|
|||||||
|
|
||||||
wchar_t *quote_end( const wchar_t *in )
|
wchar_t *quote_end( const wchar_t *in )
|
||||||
{
|
{
|
||||||
int level=1;
|
switch( *in )
|
||||||
int offset = (*in != L'\"');
|
|
||||||
|
|
||||||
in++;
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
{
|
||||||
/* fwprintf( stderr, L"Check %c\n", *tok->buff );*/
|
case '"':
|
||||||
switch( *in )
|
|
||||||
{
|
{
|
||||||
case L'\\':
|
while(1)
|
||||||
in++;
|
{
|
||||||
if( *in == L'\0' )
|
in = wcschr( in+1, L'"' );
|
||||||
{
|
if( !in )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
if( *(in-1) != L'\\' )
|
||||||
break;
|
return (wchar_t *)in;
|
||||||
case L'\"':
|
}
|
||||||
case L'\'':
|
}
|
||||||
if( (((level+offset) % 2)?L'\"':L'\'') == *in )
|
case '\'':
|
||||||
{
|
{
|
||||||
level--;
|
return wcschr( in+1, L'\'' );
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
level++;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if( (*in == L'\0') ||(level==0))
|
|
||||||
break;
|
|
||||||
|
|
||||||
in++;
|
|
||||||
}
|
}
|
||||||
return level?0:(wchar_t *)in;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -962,6 +923,8 @@ wchar_t *escape( const wchar_t *in,
|
|||||||
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'?':
|
||||||
@@ -997,8 +960,10 @@ wchar_t *escape( const wchar_t *in,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
wchar_t *unescape( const wchar_t * orig, int escape_special )
|
wchar_t *unescape( const wchar_t * orig, int unescape_special )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
int mode = 0;
|
||||||
int in_pos, out_pos, len = wcslen( orig );
|
int in_pos, out_pos, len = wcslen( orig );
|
||||||
int c;
|
int c;
|
||||||
int bracket_count=0;
|
int bracket_count=0;
|
||||||
@@ -1007,194 +972,346 @@ wchar_t *unescape( const wchar_t * orig, int escape_special )
|
|||||||
if( !in )
|
if( !in )
|
||||||
die_mem();
|
die_mem();
|
||||||
|
|
||||||
for( in_pos=0, out_pos=0; in_pos<len; prev=in[out_pos], out_pos++, in_pos++ )
|
for( in_pos=0, out_pos=0;
|
||||||
|
in_pos<len;
|
||||||
|
(prev=(out_pos>=0)?in[out_pos]:0), out_pos++, in_pos++ )
|
||||||
{
|
{
|
||||||
c = in[in_pos];
|
c = in[in_pos];
|
||||||
if( c == L'\\' )
|
switch( mode )
|
||||||
{
|
{
|
||||||
switch( in[++in_pos] )
|
|
||||||
|
/*
|
||||||
|
Mode 0 means unquoted string
|
||||||
|
*/
|
||||||
|
case 0:
|
||||||
{
|
{
|
||||||
case L'\0':
|
if( c == L'\\' )
|
||||||
free(in);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case L'n':
|
|
||||||
in[out_pos]=L'\n';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case L'r':
|
|
||||||
in[out_pos]=L'\r';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case L't':
|
|
||||||
in[out_pos]=L'\t';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case L'b':
|
|
||||||
in[out_pos]=L'\b';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case L'e':
|
|
||||||
in[out_pos]=L'\e';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case L'u':
|
|
||||||
case L'U':
|
|
||||||
case L'x':
|
|
||||||
case L'o':
|
|
||||||
{
|
{
|
||||||
int i;
|
switch( in[++in_pos] )
|
||||||
wchar_t res=0;
|
|
||||||
int chars=2;
|
|
||||||
int base=16;
|
|
||||||
|
|
||||||
switch( in[in_pos] )
|
|
||||||
{
|
{
|
||||||
case L'u':
|
case L'\0':
|
||||||
base=16;
|
|
||||||
chars=4;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case L'U':
|
|
||||||
base=16;
|
|
||||||
chars=8;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case L'x':
|
|
||||||
base=16;
|
|
||||||
chars=2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case L'o':
|
|
||||||
base=8;
|
|
||||||
chars=3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
for( i=0; i<chars; i++ )
|
|
||||||
{
|
|
||||||
int d = convert_digit( in[++in_pos],base);
|
|
||||||
if( d < 0 )
|
|
||||||
{
|
{
|
||||||
in_pos--;
|
free(in);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
case L'n':
|
||||||
|
{
|
||||||
|
in[out_pos]=L'\n';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
res=(res*base)|d;
|
case L'r':
|
||||||
|
{
|
||||||
|
in[out_pos]=L'\r';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case L't':
|
||||||
|
{
|
||||||
|
in[out_pos]=L'\t';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case L'b':
|
||||||
|
{
|
||||||
|
in[out_pos]=L'\b';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case L'e':
|
||||||
|
{
|
||||||
|
in[out_pos]=L'\e';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case L'u':
|
||||||
|
case L'U':
|
||||||
|
case L'x':
|
||||||
|
case L'o':
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
wchar_t res=0;
|
||||||
|
int chars=2;
|
||||||
|
int base=16;
|
||||||
|
|
||||||
|
switch( in[in_pos] )
|
||||||
|
{
|
||||||
|
case L'u':
|
||||||
|
{
|
||||||
|
base=16;
|
||||||
|
chars=4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case L'U':
|
||||||
|
{
|
||||||
|
base=16;
|
||||||
|
chars=8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case L'x':
|
||||||
|
{
|
||||||
|
base=16;
|
||||||
|
chars=2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case L'o':
|
||||||
|
{
|
||||||
|
base=8;
|
||||||
|
chars=3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for( i=0; i<chars; i++ )
|
||||||
|
{
|
||||||
|
int d = convert_digit( in[++in_pos],base);
|
||||||
|
if( d < 0 )
|
||||||
|
{
|
||||||
|
in_pos--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
res=(res*base)|d;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
in[out_pos] = res;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
in[out_pos]=in[in_pos];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch( in[in_pos]){
|
||||||
|
case L'~':
|
||||||
|
{
|
||||||
|
if( unescape_special && (in_pos == 0) )
|
||||||
|
{
|
||||||
|
in[out_pos]=HOME_DIRECTORY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
in[out_pos] = L'~';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case L'%':
|
||||||
|
{
|
||||||
|
if( unescape_special && (in_pos == 0) )
|
||||||
|
{
|
||||||
|
in[out_pos]=PROCESS_EXPAND;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
in[out_pos]=in[in_pos];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case L'*':
|
||||||
|
{
|
||||||
|
if( unescape_special )
|
||||||
|
{
|
||||||
|
if( out_pos > 0 && in[out_pos-1]==ANY_STRING )
|
||||||
|
{
|
||||||
|
out_pos--;
|
||||||
|
in[out_pos] = ANY_STRING_RECURSIVE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
in[out_pos]=ANY_STRING;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
in[out_pos]=in[in_pos];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case L'?':
|
||||||
|
{
|
||||||
|
if( unescape_special )
|
||||||
|
{
|
||||||
|
in[out_pos]=ANY_CHAR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
in[out_pos]=in[in_pos];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case L'$':
|
||||||
|
{
|
||||||
|
if( unescape_special )
|
||||||
|
{
|
||||||
|
in[out_pos]=VARIABLE_EXPAND;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
in[out_pos]=in[in_pos];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case L'{':
|
||||||
|
{
|
||||||
|
if( unescape_special )
|
||||||
|
{
|
||||||
|
bracket_count++;
|
||||||
|
in[out_pos]=BRACKET_BEGIN;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
in[out_pos]=in[in_pos];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case L'}':
|
||||||
|
{
|
||||||
|
if( unescape_special )
|
||||||
|
{
|
||||||
|
bracket_count--;
|
||||||
|
in[out_pos]=BRACKET_END;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
in[out_pos]=in[in_pos];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case L',':
|
||||||
|
{
|
||||||
|
if( unescape_special && bracket_count && prev!=BRACKET_SEP)
|
||||||
|
{
|
||||||
|
in[out_pos]=BRACKET_SEP;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
in[out_pos]=in[in_pos];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case L'\'':
|
||||||
|
{
|
||||||
|
mode = 1;
|
||||||
|
in[out_pos] = INTERNAL_SEPARATOR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case L'\"':
|
||||||
|
{
|
||||||
|
mode = 2;
|
||||||
|
in[out_pos] = INTERNAL_SEPARATOR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
in[out_pos] = in[in_pos];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Mode 1 means single quoted string, i.e 'foo'
|
||||||
|
*/
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
if( c == L'\'' )
|
||||||
|
{
|
||||||
|
in[out_pos] = INTERNAL_SEPARATOR;
|
||||||
|
mode = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
in[out_pos] = in[in_pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Mode 2 means double quoted string, i.e. "foo"
|
||||||
|
*/
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
switch( c )
|
||||||
|
{
|
||||||
|
case '"':
|
||||||
|
{
|
||||||
|
mode = 0;
|
||||||
|
in[out_pos] = INTERNAL_SEPARATOR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case '\\':
|
||||||
|
{
|
||||||
|
switch( in[++in_pos] )
|
||||||
|
{
|
||||||
|
case L'\0':
|
||||||
|
{
|
||||||
|
free(in);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
case L'$':
|
||||||
|
{
|
||||||
|
in[out_pos]=in[in_pos];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
in[out_pos++] = L'\\';
|
||||||
|
in[out_pos] = in[in_pos];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
in[out_pos] = res;
|
case '$':
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
in[out_pos]=in[in_pos];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch( in[in_pos]){
|
|
||||||
case L'~':
|
|
||||||
if( escape_special && (in_pos == 0) )
|
|
||||||
in[out_pos]=HOME_DIRECTORY;
|
|
||||||
else
|
|
||||||
in[out_pos] = L'~';
|
|
||||||
break;
|
|
||||||
case L'%':
|
|
||||||
if( escape_special && (in_pos == 0) )
|
|
||||||
in[out_pos]=PROCESS_EXPAND;
|
|
||||||
else
|
|
||||||
in[out_pos]=in[in_pos];
|
|
||||||
break;
|
|
||||||
case L'*':
|
|
||||||
if( escape_special )
|
|
||||||
{
|
{
|
||||||
if( out_pos > 0 && in[out_pos-1]==ANY_STRING )
|
if( unescape_special )
|
||||||
{
|
{
|
||||||
out_pos--;
|
in[out_pos]=VARIABLE_EXPAND_SINGLE;
|
||||||
in[out_pos] = ANY_STRING_RECURSIVE;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
in[out_pos]=ANY_STRING;
|
{
|
||||||
|
in[out_pos]=in[in_pos];
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
in[out_pos]=in[in_pos];
|
default:
|
||||||
break;
|
|
||||||
case L'?':
|
|
||||||
if( escape_special )
|
|
||||||
in[out_pos]=ANY_CHAR;
|
|
||||||
else
|
|
||||||
in[out_pos]=in[in_pos];
|
|
||||||
break;
|
|
||||||
case L'$':
|
|
||||||
if( escape_special )
|
|
||||||
in[out_pos]=VARIABLE_EXPAND;
|
|
||||||
else
|
|
||||||
in[out_pos]=in[in_pos];
|
|
||||||
break;
|
|
||||||
case L'{':
|
|
||||||
if( escape_special )
|
|
||||||
{
|
{
|
||||||
bracket_count++;
|
in[out_pos] = in[in_pos];
|
||||||
in[out_pos]=BRACKET_BEGIN;
|
break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
in[out_pos]=in[in_pos];
|
}
|
||||||
break;
|
break;
|
||||||
case L'}':
|
|
||||||
if( escape_special )
|
|
||||||
{
|
|
||||||
bracket_count--;
|
|
||||||
in[out_pos]=BRACKET_END;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
in[out_pos]=in[in_pos];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case L',':
|
|
||||||
if( escape_special && bracket_count && prev!=BRACKET_SEP)
|
|
||||||
{
|
|
||||||
in[out_pos]=BRACKET_SEP;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
in[out_pos]=in[in_pos];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case L'\'':
|
|
||||||
case L'\"':
|
|
||||||
{
|
|
||||||
wchar_t *end = quote_end( &in[in_pos] );
|
|
||||||
int len;
|
|
||||||
|
|
||||||
if( end == 0 )
|
|
||||||
{
|
|
||||||
free(in);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = end- &in[in_pos]-1;
|
|
||||||
|
|
||||||
if( escape_special)
|
|
||||||
in[out_pos++]=INTERNAL_SEPARATOR;
|
|
||||||
|
|
||||||
memmove( &in[out_pos], &in[in_pos+1], sizeof(wchar_t)*(len) );
|
|
||||||
in_pos += len+1;
|
|
||||||
out_pos += len-1;
|
|
||||||
|
|
||||||
if( escape_special)
|
|
||||||
in[++out_pos]=INTERNAL_SEPARATOR;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
in[out_pos] = in[in_pos];
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
in[out_pos]=L'\0';
|
in[out_pos]=L'\0';
|
||||||
return in;
|
return in;
|
||||||
@@ -1310,13 +1427,13 @@ static char *gen_unique_nfs_filename( const char *filename )
|
|||||||
pidlen = sprint_pid_t( getpid(), newname + orglen + 1 + hnlen + 1 );
|
pidlen = sprint_pid_t( getpid(), newname + orglen + 1 + hnlen + 1 );
|
||||||
newname[orglen + 1 + hnlen + 1 + pidlen] = '\0';
|
newname[orglen + 1 + hnlen + 1 + pidlen] = '\0';
|
||||||
/* debug( 1, L"gen_unique_nfs_filename returning with: newname = \"%s\"; "
|
/* debug( 1, L"gen_unique_nfs_filename returning with: newname = \"%s\"; "
|
||||||
L"HOST_NAME_MAX = %d; hnlen = %d; orglen = %d; "
|
L"HOST_NAME_MAX = %d; hnlen = %d; orglen = %d; "
|
||||||
L"sizeof(pid_t) = %d; maxpiddigits = %d; malloc'd size: %d",
|
L"sizeof(pid_t) = %d; maxpiddigits = %d; malloc'd size: %d",
|
||||||
newname, (int)HOST_NAME_MAX, hnlen, orglen,
|
newname, (int)HOST_NAME_MAX, hnlen, orglen,
|
||||||
(int)sizeof(pid_t),
|
(int)sizeof(pid_t),
|
||||||
(int)(0.31 * sizeof(pid_t) * CHAR_BIT + 1),
|
(int)(0.31 * sizeof(pid_t) * CHAR_BIT + 1),
|
||||||
(int)(orglen + 1 + hnlen + 1 +
|
(int)(orglen + 1 + hnlen + 1 +
|
||||||
(int)(0.31 * sizeof(pid_t) * CHAR_BIT + 1) + 1) ); */
|
(int)(0.31 * sizeof(pid_t) * CHAR_BIT + 1) + 1) ); */
|
||||||
return newname;
|
return newname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
91
common.h
91
common.h
@@ -14,7 +14,10 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Under curses, tputs expects an int (*func)(char) as its last parameter, but in ncurses, tputs expects a int (*func)(int) as its last parameter. tputs_arg_t is defined to always be what tputs expects. Hopefully.
|
Under curses, tputs expects an int (*func)(char) as its last
|
||||||
|
parameter, but in ncurses, tputs expects a int (*func)(int) as its
|
||||||
|
last parameter. tputs_arg_t is defined to always be what tputs
|
||||||
|
expects. Hopefully.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef NCURSES_VERSION
|
#ifdef NCURSES_VERSION
|
||||||
@@ -24,7 +27,7 @@ typedef char tputs_arg_t;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Maximum number of bytes in a utf-8 character
|
Maximum number of bytes used by a single utf-8 character
|
||||||
*/
|
*/
|
||||||
#define MAX_UTF8_BYTES 6
|
#define MAX_UTF8_BYTES 6
|
||||||
|
|
||||||
@@ -39,11 +42,14 @@ typedef char tputs_arg_t;
|
|||||||
*/
|
*/
|
||||||
#define FISH_COLOR_RESET -2
|
#define FISH_COLOR_RESET -2
|
||||||
|
|
||||||
/** Save the shell mode on startup so we can restore them on exit */
|
/**
|
||||||
|
Save the shell mode on startup so we can restore them on exit
|
||||||
|
*/
|
||||||
extern struct termios shell_modes;
|
extern struct termios shell_modes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The character to use where the text has been truncated. Is an ellipsis on unicode system and a $ on other systems.
|
The character to use where the text has been truncated. Is an
|
||||||
|
ellipsis on unicode system and a $ on other systems.
|
||||||
*/
|
*/
|
||||||
extern wchar_t ellipsis_char;
|
extern wchar_t ellipsis_char;
|
||||||
|
|
||||||
@@ -69,7 +75,8 @@ extern char *profile;
|
|||||||
extern wchar_t *program_name;
|
extern wchar_t *program_name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Take an array_list_t containing wide strings and converts them to a wchar_t **.
|
Take an array_list_t containing wide strings and converts them to a
|
||||||
|
single null-terminated wchar_t **.
|
||||||
*/
|
*/
|
||||||
wchar_t **list_to_char_arr( array_list_t *l );
|
wchar_t **list_to_char_arr( array_list_t *l );
|
||||||
|
|
||||||
@@ -87,22 +94,26 @@ wchar_t **list_to_char_arr( array_list_t *l );
|
|||||||
int fgetws2( wchar_t **buff, int *len, FILE *f );
|
int fgetws2( wchar_t **buff, int *len, FILE *f );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Sorts a list of wide strings according to the wcsfilecmp-function from the util library
|
Sorts a list of wide strings according to the wcsfilecmp-function
|
||||||
|
from the util library
|
||||||
*/
|
*/
|
||||||
void sort_list( array_list_t *comp );
|
void sort_list( array_list_t *comp );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns a newly allocated wide character string equivalent of the specified multibyte character string
|
Returns a newly allocated wide character string equivalent of the
|
||||||
|
specified multibyte character string
|
||||||
*/
|
*/
|
||||||
wchar_t *str2wcs( const char *in );
|
wchar_t *str2wcs( const char *in );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns a newly allocated multibyte character string equivalent of the specified wide character string
|
Returns a newly allocated multibyte character string equivalent of
|
||||||
|
the specified wide character string
|
||||||
*/
|
*/
|
||||||
char *wcs2str( const wchar_t *in );
|
char *wcs2str( const wchar_t *in );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns a newly allocated wide character string array equivalent of the specified multibyte character string array
|
Returns a newly allocated wide character string array equivalent of
|
||||||
|
the specified multibyte character string array
|
||||||
*/
|
*/
|
||||||
char **wcsv2strv( const wchar_t **in );
|
char **wcsv2strv( const wchar_t **in );
|
||||||
|
|
||||||
@@ -112,17 +123,22 @@ char **wcsv2strv( const wchar_t **in );
|
|||||||
wchar_t **strv2wcsv( const char **in );
|
wchar_t **strv2wcsv( const char **in );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns a newly allocated concatenation of the specified wide character strings
|
Returns a newly allocated concatenation of the specified wide
|
||||||
|
character strings
|
||||||
*/
|
*/
|
||||||
wchar_t *wcsdupcat( const wchar_t *a, const wchar_t *b );
|
wchar_t *wcsdupcat( const wchar_t *a, const wchar_t *b );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns a newly allocated concatenation of the specified wide character strings. The last argument must be a null pointer.
|
Returns a newly allocated concatenation of the specified wide
|
||||||
|
character strings. The last argument must be a null pointer.
|
||||||
*/
|
*/
|
||||||
wchar_t *wcsdupcat2( const wchar_t *a, ... );
|
wchar_t *wcsdupcat2( const wchar_t *a, ... );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns a newly allocated wide character string wich is a copy of the string in, but of length c or shorter. The returned string is always null terminated, and the null is not included in the string length.
|
Returns a newly allocated wide character string wich is a copy of
|
||||||
|
the string in, but of length c or shorter. The returned string is
|
||||||
|
always null terminated, and the null is not included in the string
|
||||||
|
length.
|
||||||
*/
|
*/
|
||||||
wchar_t *wcsndup( const wchar_t *in, int c );
|
wchar_t *wcsndup( const wchar_t *in, int c );
|
||||||
|
|
||||||
@@ -144,14 +160,32 @@ long wcstol(const wchar_t *nptr,
|
|||||||
wchar_t **endptr,
|
wchar_t **endptr,
|
||||||
int base);
|
int base);
|
||||||
|
|
||||||
size_t
|
/**
|
||||||
wcslcat(wchar_t *dst, const wchar_t *src, size_t siz);
|
Appends src to string dst of size siz (unlike wcsncat, siz is the
|
||||||
|
full size of dst, not space left). At most siz-1 characters will be
|
||||||
|
copied. Always NUL terminates (unless siz <= wcslen(dst)). Returns
|
||||||
|
wcslen(src) + MIN(siz, wcslen(initial dst)). If retval >= siz,
|
||||||
|
truncation occurred.
|
||||||
|
|
||||||
size_t
|
This is the OpenBSD strlcat function, modified for wide characters,
|
||||||
wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz);
|
and renamed to reflect this change.
|
||||||
|
|
||||||
|
*/
|
||||||
|
size_t wcslcat( wchar_t *dst, const wchar_t *src, size_t siz );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Create a dublicate string. Wide string version of strdup.
|
Copy src to string dst of size siz. At most siz-1 characters will
|
||||||
|
be copied. Always NUL terminates (unless siz == 0). Returns
|
||||||
|
wcslen(src); if retval >= siz, truncation occurred.
|
||||||
|
|
||||||
|
This is the OpenBSD strlcpy function, modified for wide characters,
|
||||||
|
and renamed to reflect this change.
|
||||||
|
*/
|
||||||
|
size_t wcslcpy( wchar_t *dst, const wchar_t *src, size_t siz );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Create a dublicate string. Wide string version of strdup. Will
|
||||||
|
automatically exit if out of memory.
|
||||||
*/
|
*/
|
||||||
wchar_t *wcsdup(const wchar_t *in);
|
wchar_t *wcsdup(const wchar_t *in);
|
||||||
|
|
||||||
@@ -163,9 +197,22 @@ wchar_t *wcsdup(const wchar_t *in);
|
|||||||
esoteric locales where uppercase and lowercase do not cleanly
|
esoteric locales where uppercase and lowercase do not cleanly
|
||||||
transform between each other. Hopefully this should be fine since
|
transform between each other. Hopefully this should be fine since
|
||||||
fish only uses this function with one of the strings supplied by
|
fish only uses this function with one of the strings supplied by
|
||||||
fish and guaranteed to be a sane, english word.
|
fish and guaranteed to be a sane, english word. Using wcscasecmp on
|
||||||
|
a user-supplied string should be considered a bug.
|
||||||
*/
|
*/
|
||||||
int wcscasecmp( const wchar_t *a, const wchar_t *b );
|
int wcscasecmp( const wchar_t *a, const wchar_t *b );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Case insensitive string compare function. Wide string version of
|
||||||
|
strncasecmp.
|
||||||
|
|
||||||
|
This implementation of wcsncasecmp does not take into account
|
||||||
|
esoteric locales where uppercase and lowercase do not cleanly
|
||||||
|
transform between each other. Hopefully this should be fine since
|
||||||
|
fish only uses this function with one of the strings supplied by
|
||||||
|
fish and guaranteed to be a sane, english word. Using wcsncasecmp on
|
||||||
|
a user-supplied string should be considered a bug.
|
||||||
|
*/
|
||||||
int wcsncasecmp( const wchar_t *a, const wchar_t *b, int count );
|
int wcsncasecmp( const wchar_t *a, const wchar_t *b, int count );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -188,7 +235,11 @@ int wcwidth( wchar_t c );
|
|||||||
int my_wcswidth( const wchar_t *c );
|
int my_wcswidth( const wchar_t *c );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This functions returns the end of a quoted substring. It can handle nested single and double quotes.
|
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.
|
||||||
|
|
||||||
|
\param in the position of the opening quote
|
||||||
*/
|
*/
|
||||||
wchar_t *quote_end( const wchar_t *in );
|
wchar_t *quote_end( const wchar_t *in );
|
||||||
|
|
||||||
@@ -205,7 +256,7 @@ void error_reset();
|
|||||||
/**
|
/**
|
||||||
Set the locale, also change the ellipsis character
|
Set the locale, also change the ellipsis character
|
||||||
*/
|
*/
|
||||||
void fish_setlocale(int category, const wchar_t *locale);
|
void fish_setlocale( int category, const wchar_t *locale );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Checks if \c needle is included in the list of strings specified
|
Checks if \c needle is included in the list of strings specified
|
||||||
|
|||||||
60
complete.c
60
complete.c
@@ -1213,10 +1213,12 @@ static void complete_cmd( const wchar_t *cmd,
|
|||||||
array_list_t tmp;
|
array_list_t tmp;
|
||||||
al_init( &tmp );
|
al_init( &tmp );
|
||||||
|
|
||||||
expand_string( wcsdup(cmd),
|
if( expand_string( wcsdup(cmd),
|
||||||
comp,
|
comp,
|
||||||
ACCEPT_INCOMPLETE | EXECUTABLES_ONLY );
|
ACCEPT_INCOMPLETE | EXECUTABLES_ONLY ) != EXPAND_ERROR )
|
||||||
complete_cmd_desc( cmd, comp );
|
{
|
||||||
|
complete_cmd_desc( cmd, comp );
|
||||||
|
}
|
||||||
al_destroy( &tmp );
|
al_destroy( &tmp );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1237,14 +1239,15 @@ static void complete_cmd( const wchar_t *cmd,
|
|||||||
|
|
||||||
al_init( &tmp );
|
al_init( &tmp );
|
||||||
|
|
||||||
expand_string( nxt_completion,
|
if( expand_string( nxt_completion,
|
||||||
&tmp,
|
&tmp,
|
||||||
ACCEPT_INCOMPLETE |
|
ACCEPT_INCOMPLETE |
|
||||||
EXECUTABLES_ONLY );
|
EXECUTABLES_ONLY ) != EXPAND_ERROR )
|
||||||
|
|
||||||
for( i=0; i<al_get_count(&tmp); i++ )
|
|
||||||
{
|
{
|
||||||
al_push( comp, al_get( &tmp, i ) );
|
for( i=0; i<al_get_count(&tmp); i++ )
|
||||||
|
{
|
||||||
|
al_push( comp, al_get( &tmp, i ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
al_destroy( &tmp );
|
al_destroy( &tmp );
|
||||||
@@ -1290,24 +1293,26 @@ static void complete_cmd( const wchar_t *cmd,
|
|||||||
|
|
||||||
al_init( &tmp );
|
al_init( &tmp );
|
||||||
|
|
||||||
expand_string( nxt_completion,
|
if( expand_string( nxt_completion,
|
||||||
&tmp,
|
&tmp,
|
||||||
ACCEPT_INCOMPLETE | DIRECTORIES_ONLY );
|
ACCEPT_INCOMPLETE | DIRECTORIES_ONLY ) != EXPAND_ERROR )
|
||||||
|
|
||||||
for( i=0; i<al_get_count(&tmp); i++ )
|
|
||||||
{
|
{
|
||||||
wchar_t *nxt = (wchar_t *)al_get( &tmp, i );
|
|
||||||
|
for( i=0; i<al_get_count(&tmp); i++ )
|
||||||
wchar_t *desc = wcsrchr( nxt, COMPLETE_SEP );
|
|
||||||
int is_valid = (desc && (wcscmp(desc,
|
|
||||||
COMPLETE_DIRECTORY_DESC)==0));
|
|
||||||
if( is_valid )
|
|
||||||
{
|
{
|
||||||
al_push( comp, nxt );
|
wchar_t *nxt = (wchar_t *)al_get( &tmp, i );
|
||||||
}
|
|
||||||
else
|
wchar_t *desc = wcsrchr( nxt, COMPLETE_SEP );
|
||||||
{
|
int is_valid = (desc && (wcscmp(desc,
|
||||||
free(nxt);
|
COMPLETE_DIRECTORY_DESC)==0));
|
||||||
|
if( is_valid )
|
||||||
|
{
|
||||||
|
al_push( comp, nxt );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free(nxt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1766,7 +1771,10 @@ static void complete_param_expand( wchar_t *str,
|
|||||||
else
|
else
|
||||||
comp_str = str;
|
comp_str = str;
|
||||||
|
|
||||||
// fwprintf( stderr, L"expand_string( \"%ls\", [list], EXPAND_SKIP_SUBSHELL | ACCEPT_INCOMPLETE | %ls )\n", comp_str, do_file?L"0":L"EXPAND_SKIP_WILDCARDS" );
|
debug( 2,
|
||||||
|
L"expand_string( \"%ls\", comp_out, EXPAND_SKIP_SUBSHELL | ACCEPT_INCOMPLETE | %ls );",
|
||||||
|
comp_str,
|
||||||
|
do_file?L"0":L"EXPAND_SKIP_WILDCARDS" );
|
||||||
|
|
||||||
expand_string( wcsdup(comp_str), comp_out, EXPAND_SKIP_SUBSHELL | ACCEPT_INCOMPLETE | (do_file?0:EXPAND_SKIP_WILDCARDS) );
|
expand_string( wcsdup(comp_str), comp_out, EXPAND_SKIP_SUBSHELL | ACCEPT_INCOMPLETE | (do_file?0:EXPAND_SKIP_WILDCARDS) );
|
||||||
}
|
}
|
||||||
@@ -1963,7 +1971,7 @@ void complete( const wchar_t *cmd,
|
|||||||
error_max=0;
|
error_max=0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
If we are completing a variable name or a tilde expantion user
|
If we are completing a variable name or a tilde expansion user
|
||||||
name, we do that and return. No need for any other competions.
|
name, we do that and return. No need for any other competions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
97
config.h.in
97
config.h.in
@@ -1,97 +0,0 @@
|
|||||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
|
||||||
|
|
||||||
/* CPU type */
|
|
||||||
#undef CPU
|
|
||||||
|
|
||||||
/* Documentation directory */
|
|
||||||
#undef DOCDIR
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `futimes' function. */
|
|
||||||
#undef HAVE_FUTIMES
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <getopt.h> header file. */
|
|
||||||
#undef HAVE_GETOPT_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
|
||||||
#undef HAVE_INTTYPES_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `rt' library (-lrt). */
|
|
||||||
#undef HAVE_LIBRT
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `socket' library (-lsocket). */
|
|
||||||
#undef HAVE_LIBSOCKET
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <memory.h> header file. */
|
|
||||||
#undef HAVE_MEMORY_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <ncurses.h> header file. */
|
|
||||||
#undef HAVE_NCURSES_H
|
|
||||||
|
|
||||||
/* Define to 1 if HAVE_RLIMIT_AS is defined in <sys/resource.h>. */
|
|
||||||
#undef HAVE_RLIMIT_AS
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <stdint.h> header file. */
|
|
||||||
#undef HAVE_STDINT_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
|
||||||
#undef HAVE_STDLIB_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <strings.h> header file. */
|
|
||||||
#undef HAVE_STRINGS_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <string.h> header file. */
|
|
||||||
#undef HAVE_STRING_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/resource.h> header file. */
|
|
||||||
#undef HAVE_SYS_RESOURCE_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
|
||||||
#undef HAVE_SYS_STAT_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
|
||||||
#undef HAVE_SYS_TYPES_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <termio.h> header file. */
|
|
||||||
#undef HAVE_TERMIO_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <unistd.h> header file. */
|
|
||||||
#undef HAVE_UNISTD_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `wcswidth' function. */
|
|
||||||
#undef HAVE_WCSWIDTH
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `wcwidth' function. */
|
|
||||||
#undef HAVE_WCWIDTH
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `wprintf' function. */
|
|
||||||
#undef HAVE_WPRINTF
|
|
||||||
|
|
||||||
/* Define to 1 if you have the file `AC_File'. */
|
|
||||||
#undef HAVE__PROC_SELF_STAT
|
|
||||||
|
|
||||||
/* Define to the address where bug reports for this package should be sent. */
|
|
||||||
#undef PACKAGE_BUGREPORT
|
|
||||||
|
|
||||||
/* Define to the full name of this package. */
|
|
||||||
#undef PACKAGE_NAME
|
|
||||||
|
|
||||||
/* Define to the full name and version of this package. */
|
|
||||||
#undef PACKAGE_STRING
|
|
||||||
|
|
||||||
/* Define to the one symbol short name of this package. */
|
|
||||||
#undef PACKAGE_TARNAME
|
|
||||||
|
|
||||||
/* Define to the version of this package. */
|
|
||||||
#undef PACKAGE_VERSION
|
|
||||||
|
|
||||||
/* Installation directory */
|
|
||||||
#undef PREFIX
|
|
||||||
|
|
||||||
/* Define to 1 if you have the ANSI C header files. */
|
|
||||||
#undef STDC_HEADERS
|
|
||||||
|
|
||||||
/* System configuration directory */
|
|
||||||
#undef SYSCONFDIR
|
|
||||||
|
|
||||||
/* Evil kludge to get Power based machines to work */
|
|
||||||
#undef TPUTS_KLUDGE
|
|
||||||
44
configure.ac
44
configure.ac
@@ -1,5 +1,5 @@
|
|||||||
# Process this file with autoconf to produce a configure script.
|
# Process this file with autoconf to produce a configure script.
|
||||||
AC_INIT(fish,1.16.2,axel@liljencrantz.se)
|
AC_INIT(fish,1.18.1,fish-users@lists.sf.net)
|
||||||
|
|
||||||
AC_CANONICAL_TARGET
|
AC_CANONICAL_TARGET
|
||||||
|
|
||||||
@@ -56,6 +56,7 @@ fi
|
|||||||
|
|
||||||
AC_DEFINE_UNQUOTED( DOCDIR, [L"$(eval echo $docdir)"], [Documentation directory] )
|
AC_DEFINE_UNQUOTED( DOCDIR, [L"$(eval echo $docdir)"], [Documentation directory] )
|
||||||
AC_DEFINE_UNQUOTED( SYSCONFDIR, [L"$(eval echo $sysconfdir)"], [System configuration directory] )
|
AC_DEFINE_UNQUOTED( SYSCONFDIR, [L"$(eval echo $sysconfdir)"], [System configuration directory] )
|
||||||
|
AC_SUBST( SYSCONFDIR, ["$(eval echo $sysconfdir)"] )
|
||||||
|
|
||||||
# See if Linux procfs is present
|
# See if Linux procfs is present
|
||||||
AC_CHECK_FILES([/proc/self/stat])
|
AC_CHECK_FILES([/proc/self/stat])
|
||||||
@@ -64,7 +65,7 @@ AC_CHECK_FILES([/proc/self/stat])
|
|||||||
AC_CHECK_FILE([/usr/pkg/lib],[AC_SUBST(LIBDIR,[-L/usr/pkg/lib\ -R/usr/pkg/lib])])
|
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])])
|
AC_CHECK_FILE([/usr/pkg/include],[AC_SUBST(INCLUDEDIR,[-I/usr/pkg/include])])
|
||||||
|
|
||||||
AC_CHECK_FUNCS( [wprintf futimes wcwidth wcswidth] )
|
AC_CHECK_FUNCS( [wprintf futimes wcwidth wcswidth getopt_long] )
|
||||||
AC_CHECK_HEADERS([getopt.h termio.h sys/resource.h])
|
AC_CHECK_HEADERS([getopt.h termio.h sys/resource.h])
|
||||||
|
|
||||||
# Check for RLIMIT_AS in sys/resource.h.
|
# Check for RLIMIT_AS in sys/resource.h.
|
||||||
@@ -79,6 +80,43 @@ else
|
|||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Check for RLIMIT_MEMLOCK in sys/resource.h.
|
||||||
|
AC_MSG_CHECKING([for RLIMIT_MEMLOCK in sys/resource.h])
|
||||||
|
AC_TRY_COMPILE([#include <sys/resource.h>],
|
||||||
|
[int tmp; tmp=RLIMIT_MEMLOCK;], have_rlimit_as=yes, have_rlimit_as=no)
|
||||||
|
if test "$have_rlimit_as" = yes; then
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE([HAVE_RLIMIT_MEMLOCK], [1],
|
||||||
|
[Define to 1 if HAVE_RLIMIT_MEMLOCK is defined in <sys/resource.h>.])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for RLIMIT_RSS in sys/resource.h.
|
||||||
|
AC_MSG_CHECKING([for RLIMIT_RSS in sys/resource.h])
|
||||||
|
AC_TRY_COMPILE([#include <sys/resource.h>],
|
||||||
|
[int tmp; tmp=RLIMIT_RSS;], have_rlimit_as=yes, have_rlimit_as=no)
|
||||||
|
if test "$have_rlimit_as" = yes; then
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE([HAVE_RLIMIT_RSS], [1],
|
||||||
|
[Define to 1 if HAVE_RLIMIT_RSS is defined in <sys/resource.h>.])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for RLIMIT_NPROC in sys/resource.h.
|
||||||
|
AC_MSG_CHECKING([for RLIMIT_NPROC in sys/resource.h])
|
||||||
|
AC_TRY_COMPILE([#include <sys/resource.h>],
|
||||||
|
[int tmp; tmp=RLIMIT_NPROC;], have_rlimit_as=yes, have_rlimit_as=no)
|
||||||
|
if test "$have_rlimit_as" = yes; then
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE([HAVE_RLIMIT_NPROC], [1],
|
||||||
|
[Define to 1 if HAVE_RLIMIT_NPROC is defined in <sys/resource.h>.])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
AC_CHECK_LIB(socket, connect)
|
AC_CHECK_LIB(socket, connect)
|
||||||
AC_CHECK_LIB(rt, nanosleep)
|
AC_CHECK_LIB(rt, nanosleep)
|
||||||
|
|
||||||
@@ -90,5 +128,5 @@ AC_CHECK_HEADERS([ncurses.h],[AC_SUBST(CURSESLIB,[ncurses]) AC_DEFINE(HAVE_NCURS
|
|||||||
#does not properly support terminfo.
|
#does not properly support terminfo.
|
||||||
AC_CHECK_FILE([/usr/pkg/include/ncurses.h],[AC_SUBST(CURSESLIB,[ncurses]) AC_DEFINE(HAVE_NCURSES_H)])
|
AC_CHECK_FILE([/usr/pkg/include/ncurses.h],[AC_SUBST(CURSESLIB,[ncurses]) AC_DEFINE(HAVE_NCURSES_H)])
|
||||||
|
|
||||||
AC_CONFIG_FILES([Makefile fish.spec doc_src/fish.1 doc_src/Doxyfile init/fish])
|
AC_CONFIG_FILES([Makefile fish.spec doc_src/fish.1 doc_src/Doxyfile init/fish init/fish_interactive.fish init/fish_complete.fish])
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
|||||||
@@ -4,6 +4,11 @@
|
|||||||
<tt>complete (-c|--command|-p|--path) COMMAND [(-s|--short-option) SHORT_OPTION] [(-l|--long-option|-o|--old-option) LONG_OPTION [(-a||--arguments) OPTION_ARGUMENTS] [(-d|--description) DESCRIPTION] </tt>
|
<tt>complete (-c|--command|-p|--path) COMMAND [(-s|--short-option) SHORT_OPTION] [(-l|--long-option|-o|--old-option) LONG_OPTION [(-a||--arguments) OPTION_ARGUMENTS] [(-d|--description) DESCRIPTION] </tt>
|
||||||
|
|
||||||
\subsection complete-description Description
|
\subsection complete-description Description
|
||||||
|
|
||||||
|
For an introduction to how to specify completions, see the section <a
|
||||||
|
href='index.html#completions-own'>Writing your own completions</a> of
|
||||||
|
the fish manual.
|
||||||
|
|
||||||
- <tt>COMMAND</tt> is the name of the command for which to add a completion
|
- <tt>COMMAND</tt> is the name of the command for which to add a completion
|
||||||
- <tt>SHORT_OPTION</tt> is a one character option for the command
|
- <tt>SHORT_OPTION</tt> is a one character option for the command
|
||||||
- <tt>LONG_OPTION</tt> is a multi character option for the command
|
- <tt>LONG_OPTION</tt> is a multi character option for the command
|
||||||
@@ -61,7 +66,9 @@ are valid, like the \c nodeps switch.
|
|||||||
|
|
||||||
This can be written as:
|
This can be written as:
|
||||||
|
|
||||||
<tt>complete -c rpm -n "__fish_contains_opt -s e erase" -l nodeps -d 'Dont check dependencies'</tt>
|
<tt>complete -c rpm -n "__fish_contains_opt -s e erase" -l nodeps -d
|
||||||
|
"Don't check dependencies"</tt>
|
||||||
|
|
||||||
where \c __fish_contains_opt is a function that checks the commandline buffer for the presense of a specified set of options.
|
where \c __fish_contains_opt is a function that checks the commandline
|
||||||
|
buffer for the presense of a specified set of options.
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ the user does not have to worry about an array containing elements
|
|||||||
such as dashes. \c fish performs a special check when invoking the
|
such as dashes. \c fish performs a special check when invoking the
|
||||||
count program, and if the user uses a help option, this help page is
|
count program, and if the user uses a help option, this help page is
|
||||||
displayed, but if a help option is contained inside of a variable or
|
displayed, but if a help option is contained inside of a variable or
|
||||||
is the result of expantion, it will be passed on to the count program.
|
is the result of expansion, it will be passed on to the count program.
|
||||||
|
|
||||||
\subsection count-example Example
|
\subsection count-example Example
|
||||||
|
|
||||||
|
|||||||
333
doc_src/doc.hdr
333
doc_src/doc.hdr
@@ -1,15 +1,20 @@
|
|||||||
/** \mainpage fish
|
/** \mainpage Fish user documentation
|
||||||
|
|
||||||
\c fish is a user friendly shell intended mostly for interactive use.
|
\section introduction The friendly interactive shell
|
||||||
A shell is a program which allows you to execute other programs by
|
|
||||||
typing their names. For updates on \c fish, go to the <a
|
This is the documentation for \c fish, the friendly interactive
|
||||||
|
shell. \c fish is a user friendly commandline shell 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/"><tt>fish</tt> homepage</a>.
|
||||||
|
|
||||||
\section syntax Syntax overview
|
\section syntax Syntax overview
|
||||||
|
|
||||||
Shells like \c fish are used by giving them commands. Every \c fish command follows the same simple syntax.
|
Shells like fish are used by giving them commands. Every \c fish
|
||||||
|
command follows the same simple syntax.
|
||||||
|
|
||||||
A command is executed by writing the name of the command followed by any arguments.
|
A command is executed by writing the name of the command followed by
|
||||||
|
any arguments.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@@ -61,11 +66,13 @@ written on the same line by separating them with semicolons.
|
|||||||
Sometimes features such as <a href="#globbing">parameter expansion</a>
|
Sometimes features such as <a href="#globbing">parameter expansion</a>
|
||||||
and <a href="#escapes">character escapes</a> get in the way. When that
|
and <a href="#escapes">character escapes</a> get in the way. When that
|
||||||
happens, the user can write a parameter within quotes, either '
|
happens, the user can write a parameter within quotes, either '
|
||||||
(single quote) or " (double quote). There is no difference between
|
(single quote) or " (double quote). There is one important difference
|
||||||
single quoted and double quoted strings. A quoted parameter will not
|
between single quoted and double quoted strings: When using double
|
||||||
be parameter expanded, may contain spaces, and the only escape
|
quoted string, <a href='#expand-variable'>variable expansion</a> still
|
||||||
sequences allowed is the corresponding quote character. Single and
|
takes place. Other than that, a quoted parameter will not be
|
||||||
double quotes may be nested.
|
parameter expanded, may contain spaces, and escape sequences are
|
||||||
|
ignored. Single quotes have no special meaning withing double quotes
|
||||||
|
and vice versa.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@@ -210,7 +217,7 @@ This is a short explanation of some of the commonly used words in fish.
|
|||||||
- argument, a parameter given to a command
|
- argument, a parameter given to a command
|
||||||
- builtin, a command that is implemented as part of the shell
|
- builtin, a command that is implemented as part of the shell
|
||||||
- command, a program
|
- command, a program
|
||||||
- function, a command that is implemented as a set of fish commands
|
- 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
|
- job, a running pipeline or command
|
||||||
- pipeline, a set of commands stringed together so that the output of one command is the input of the next command
|
- pipeline, a set of commands stringed together so that the output of one command is the input of the next command
|
||||||
- redirection, a operation that changes one of the input/output streams associated with a job
|
- redirection, a operation that changes one of the input/output streams associated with a job
|
||||||
@@ -264,31 +271,59 @@ in the known_hosts file. (see the ssh documentation for more information)
|
|||||||
- The 'su' command complete using all users on the system
|
- The 'su' command complete using all users on the system
|
||||||
- The \c apt-get, \c rpm and \c tym commands complete using all installed packages.
|
- The \c apt-get, \c rpm and \c tym commands complete using all installed packages.
|
||||||
|
|
||||||
Specifying your own completions is easy. If the command 'myprog' has
|
\subsection completion-own Writing your own completions
|
||||||
an option '-o' which can also be written as '--output', which requires
|
|
||||||
an additional value of either 'yes' or 'no' and decides if the program
|
|
||||||
should write anything, this can be specified by writing:
|
|
||||||
|
|
||||||
<tt>complete -c myprog -s o -l output -r -a "yes no" -d "Write output"</tt>
|
Specifying your own completions is not complicated. To specify a
|
||||||
|
completion, one simply uses 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
|
||||||
|
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
|
||||||
|
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.
|
||||||
|
|
||||||
For a more complete description of how to specify your own
|
Fish has a special syntax to support specifying switches accepted by a
|
||||||
completions, go <a href="builtins.html#complete">here</a> or write 'complete --help' in the \c fish shell.
|
command. The switches \c -s, \c -l and \c -o are used to specify a
|
||||||
|
short switch (single character, such as -l), a gnu style long switch (such as
|
||||||
|
--color) and an old-style long switch (like -shuffle),
|
||||||
|
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>
|
||||||
|
|
||||||
|
There are also special switches for specifying that a switch requires
|
||||||
|
an argument, to disable filename completion, to create completions
|
||||||
|
that are only available in some combinations, etc.. For a complete
|
||||||
|
description of the various switches accepted by the \c complete
|
||||||
|
command, see the documentation for the <a
|
||||||
|
href="builtins.html#complete">complete</a> builtin, or write 'complete
|
||||||
|
--help' inside the \c fish shell.
|
||||||
|
|
||||||
|
For examples of how to write your own complex completions, study the
|
||||||
|
completions in /etc/fish.d/completions (or ~/etc/fish.d/completions if
|
||||||
|
you installed fish in your home directory).
|
||||||
|
|
||||||
If you wish to use a completion, you should consider adding it to your
|
If you wish to use a completion, you should consider adding it to your
|
||||||
startup files. When completion has been requested for a command \c
|
startup files. When completion has been requested for a command \c
|
||||||
COMMAND, fish will automatically look for the file
|
COMMAND, fish will automatically look for the file
|
||||||
~/.fish.d/completions/COMMAND.fish. If it exists, it will be
|
~/.fish.d/completions/COMMAND.fish. If it exists, it will be
|
||||||
automatically loaded. For examples of how to write your own complex
|
automatically loaded. If you have written new completions for a common
|
||||||
completions, study the completions in /etc/fish.d/completions (or ~/etc/fish.d/completions if you installed fish in your home directory).
|
Unix command, please consider sharing your work by sending it to <a
|
||||||
|
href='mailto: fish-users@lists.sf.net'>the fish mailinglist</a>.
|
||||||
|
|
||||||
\section expand Parameter expansion (Globbing)
|
\section expand Parameter expansion (Globbing)
|
||||||
|
|
||||||
When an argument for a program is given on the commandline, it
|
When an argument for a program is given on the commandline, it
|
||||||
undergoes the process of parameter expantion before it is sent on to
|
undergoes the process of parameter expansion before it is sent on to
|
||||||
the command. There are many ways in which the user can specify a
|
the command. There are many ways in which the user can specify a
|
||||||
parameter to be expanded. These include:
|
parameter to be expanded. These include:
|
||||||
|
|
||||||
\subsection expand-wildcards Wildcards
|
\subsection expand-wildcard Wildcards
|
||||||
|
|
||||||
If a star (*) or a question mark (?) is present in the parameter, \c
|
If a star (*) or a question mark (?) is present in the parameter, \c
|
||||||
fish attempts to mach the given parameter to any files in such a
|
fish attempts to mach the given parameter to any files in such a
|
||||||
@@ -300,17 +335,24 @@ Example:
|
|||||||
|
|
||||||
<code>???</code> matches any file in the current directory whose name is exactly three characters long.
|
<code>???</code> matches any file in the current directory whose name is exactly three characters long.
|
||||||
|
|
||||||
|
If no matches are founf for a specific wildcard, it will expand intto
|
||||||
|
zero arguments, i.e. to nothing. If none of the wildcarded arguments
|
||||||
|
sent to a command result in any matches, the command will not be
|
||||||
|
executed. If this happens when using the shell interactively, a
|
||||||
|
warning will also be printed.
|
||||||
|
|
||||||
\subsection expand-command-substitution Command substitution
|
\subsection expand-command-substitution Command substitution
|
||||||
|
|
||||||
If a parameter contains a set of parenthesis, the text enclosed by the
|
If a parameter contains a set of parenthesis, the text enclosed by the
|
||||||
parentesis will be interpreted as a list of commands. Om expantion,
|
parentesis will be interpreted as a list of commands. Om expansion,
|
||||||
this list is executed, and substituted by the output. If the output is
|
this list is executed, and substituted by the output. If the output is
|
||||||
more than one line long, each line will be expanded to a new
|
more than one line long, each line will be expanded to a new
|
||||||
parameter.
|
parameter.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
The command <code>echo (basename image.jpg .jpg).png</code> will output 'image.png'.
|
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;
|
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
|
end</tt> will convert all Jpeg files in the current directory to the
|
||||||
@@ -339,11 +381,44 @@ href="#variables"> Environment variables</a> section.
|
|||||||
Example:
|
Example:
|
||||||
|
|
||||||
<tt> echo \$HOME</tt> prints the home directory of the current
|
<tt> echo \$HOME</tt> prints the home directory of the current
|
||||||
user. If you wish to combine environment variables with text, you can
|
user.
|
||||||
|
|
||||||
|
If you wish to combine environment variables with text, you can
|
||||||
encase the variables within braces to embed a variable inside running
|
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 <tt>echo Konnichiwa {$USER}san</tt>, which will print a
|
||||||
personalized Japanese greeting.
|
personalized Japanese greeting.
|
||||||
|
|
||||||
|
The {$USER}san syntax might need a bit of an elaboration. Posix
|
||||||
|
shells allow you to specify a variable name using '$VARNAME' or
|
||||||
|
'${VARNAME}'. Fish only supports the former, but has no support
|
||||||
|
whatsoever for the latter or anything remotely like it. So what is
|
||||||
|
'{$VARNAME}' then? Well, '{WHATEVER}' is <a href='#brace'>brace
|
||||||
|
expansion</a>, the same as supported by Posix shells, i.e. 'a{b,c}d'
|
||||||
|
-> 'abd acd' works both in bash and on fish. So '{$VARNAME}' is a
|
||||||
|
bracket-expansion with only a single element, i.e. it becomes
|
||||||
|
expanded to '$VARNAME', which will be variable expanded to the value
|
||||||
|
of the variable 'VARNAME'. So you might think that the brackets don't
|
||||||
|
actually do anything, and that is nearly the truth. The snag is that
|
||||||
|
there once along the way was a '}' in there somewhere, and } is not a
|
||||||
|
valid character in a variable name. So anything after the otherwise
|
||||||
|
pointless bracket expansion becomes NOT a part of the variable name,
|
||||||
|
even if it happens to be a legal variable name character. That's why
|
||||||
|
'{$USER}san' works. A case of one syntax just lending itself so nicely
|
||||||
|
to solving an unrelated problem in it's spare time.
|
||||||
|
|
||||||
|
Variable expansion is the only type of expansion performed on double
|
||||||
|
quoted strings. There is, however, an important difference in how
|
||||||
|
variables are expanded when quoted and when unquoted. An unquoted
|
||||||
|
variable expansion will result in a variable number of arguments. For
|
||||||
|
example, if the variable $foo has zero elements or is undefined, the
|
||||||
|
argument $foo will expand to zero elements. If the variable $foo is an
|
||||||
|
array of five elements, the argument $foo will expand to five
|
||||||
|
elements. When quoted, like "$foo", a variable expansion will always
|
||||||
|
result in exactly one argument. Undefined variables will expand to the
|
||||||
|
empty string, and array variables will be concatenated using the space
|
||||||
|
character.
|
||||||
|
|
||||||
|
|
||||||
\subsection expand-home Home directory expansion
|
\subsection expand-home Home directory expansion
|
||||||
|
|
||||||
The ~ (tilde) character at the beginning of a parameter, followed by a
|
The ~ (tilde) character at the beginning of a parameter, followed by a
|
||||||
@@ -354,7 +429,7 @@ directory of the process owner.
|
|||||||
\subsection expand-process Process expansion
|
\subsection expand-process Process expansion
|
||||||
|
|
||||||
The \% (percent) character at the beginning of a parameter followed by
|
The \% (percent) character at the beginning of a parameter followed by
|
||||||
a string is expanded into a process id. The following expantions are
|
a string is expanded into a process id. The following expansions are
|
||||||
performed:
|
performed:
|
||||||
|
|
||||||
- If the string is the entire word \c self, the shells pid is the result
|
- If the string is the entire word \c self, the shells pid is the result
|
||||||
@@ -394,7 +469,9 @@ will output 'abar1 abar2 abar3 afoo1 afoo2 afoo3'.
|
|||||||
|
|
||||||
The concept of environment variables are central to any
|
The concept of environment variables are central to any
|
||||||
shell. Environment variables are variables, whose values can be set
|
shell. Environment variables are variables, whose values can be set
|
||||||
and used by the user.
|
and used by the user. For information on how to use the current value
|
||||||
|
of a variable, see the section on <a href='#expand-variable'>variable
|
||||||
|
expansion</a>.
|
||||||
|
|
||||||
To set a variable value, use the <a href="builtins.html#set"> \c set
|
To set a variable value, use the <a href="builtins.html#set"> \c set
|
||||||
command</a>.
|
command</a>.
|
||||||
@@ -409,25 +486,25 @@ the shell through <a href="expand-variable">variable expansion</a>.
|
|||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
To use the value of a the variable \c smurf, use the command <tt>echo
|
To use the value of a the variable \c smurf, write $ (dollar synbol)
|
||||||
Smurfs are $smurf</tt>, which would print the result 'Smurfs are
|
followed by the name of the variable, like <tt>echo Smurfs are
|
||||||
blue'.
|
$smurf</tt>, which would print the result 'Smurfs are blue'.
|
||||||
|
|
||||||
\subsection variables-scope Variable scope
|
\subsection variables-scope Variable scope
|
||||||
|
|
||||||
There are three kinds of variables in fish, universal, global and
|
There are three kinds of variables in fish, universal, global and
|
||||||
local variables. Universal variables are shared between all fish
|
local variables. Universal variables are shared between all fish
|
||||||
sessions a user is running on one computer. Global variables are
|
sessions a user is running on one computer. Global variables are
|
||||||
specific to the current fish session, and will never be erased unless
|
specific to the current fish session, but are not associated with any
|
||||||
the user explicitly requests it using <tt>set -e</tt>. Local variables
|
soecific block scope, and will never be erased unless the user
|
||||||
are specific to the current fish session, and associated with a
|
explicitly requests it using <tt>set -e</tt>. Local variables are
|
||||||
specific block of commands, and is automatically erased when a
|
specific to the current fish session, and associated with a specific
|
||||||
specific block goes out of scope. A block of commands is a series of
|
block of commands, and is automatically erased when a specific block
|
||||||
commands that begins with one of the commands \c 'for, \c 'while' , \c
|
goes out of scope. A block of commands is a series of commands that
|
||||||
'if', \c 'function', \c 'begin' or \c 'switch', and ends with the
|
begins with one of the commands \c 'for, \c 'while' , \c 'if', \c
|
||||||
command \c 'end'. The user can specify that a variable should have
|
'function', \c 'begin' or \c 'switch', and ends with the command \c
|
||||||
either global or local scope using the \c -g/--global or \c -l/--local
|
'end'. The user can specify that a variable should have either global
|
||||||
switches.
|
or local scope using the \c -g/--global or \c -l/--local switches.
|
||||||
|
|
||||||
Variables can be explicitly set to be universal with the \c -U or \c
|
Variables can be explicitly set to be universal with the \c -U or \c
|
||||||
--universal switch, global with the \c -g or \c --global switch, or
|
--universal switch, global with the \c -g or \c --global switch, or
|
||||||
@@ -436,21 +513,24 @@ creating or updating a variable are:
|
|||||||
|
|
||||||
-# If a variable is explicitly set to either universal, global or local, that setting will be honored
|
-# If a variable is explicitly set to either universal, global or local, that setting will be honored
|
||||||
-# If a variable is not explicitly set to be either universal, global or local, but has been previously defined, the variable scope is not changed
|
-# If a variable is not explicitly set to be either universal, global or local, but has been previously defined, the variable scope is not changed
|
||||||
-# If a variable is not explicitly set to be either universal, global or local and has never befor been defined, the variable will be local to the current scope
|
-# If a variable is not explicitly set to be either universal, global or local and has never befor been defined, the variable will be local to the currently executing functions. If no function is executing, the variable will be global.
|
||||||
|
|
||||||
|
There may be many variables with the same name, but different scopes.
|
||||||
When using a variable, the variable scope will be searched from the
|
When using a variable, the variable scope will be searched from the
|
||||||
inside out, i.e. a local variable will be used rather than a global
|
inside out, i.e. a local variable will be used rather than a global
|
||||||
variable with the same name, a global variable will be used rather
|
variable with the same name, a global variable will be used rather
|
||||||
than a universal variable with the same name.
|
than a universal variable with the same name.
|
||||||
|
|
||||||
For example, the following code will not output anything:
|
Example:
|
||||||
|
|
||||||
|
The following code will not output anything:
|
||||||
<pre>
|
<pre>
|
||||||
if true
|
begin
|
||||||
# This is a nice local scope where all variables will die
|
# This is a nice local scope where all variables will die
|
||||||
set pirate 'There be treasure in them thar hills'
|
set -l pirate 'There be treasure in them thar hills'
|
||||||
end
|
end
|
||||||
|
|
||||||
# This will not output anything, since the pirate is dead
|
# This will not output anything, since the pirate was local
|
||||||
echo $pirate
|
echo $pirate
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
@@ -563,22 +643,25 @@ certain environment variables.
|
|||||||
- \c CDPATH, which is an array of directories in which to search for the new directory for the \c cd builtin.
|
- \c CDPATH, which is an array of directories in which to search for the new directory for the \c cd builtin.
|
||||||
- \c fish_color_normal, \c fish_color_command, \c fish_color_substitution, \c fish_color_redirection, \c fish_color_end, \c fish_color_error, \c fish_color_param, \c fish_color_comment, \c fish_color_match, \c fish_color_search_match, \c fish_color_cwd, \c fish_pager_color_prefix, \c fish_pager_color_completion, \c fish_pager_color_description and \c fish_pager_color_progress are used to change the color of various elements in \c fish. These variables are universal, i.e. when changing them, their new value will be used by all running fish sessions. The new value will also be retained when restarting fish.
|
- \c fish_color_normal, \c fish_color_command, \c fish_color_substitution, \c fish_color_redirection, \c fish_color_end, \c fish_color_error, \c fish_color_param, \c fish_color_comment, \c fish_color_match, \c fish_color_search_match, \c fish_color_cwd, \c fish_pager_color_prefix, \c fish_pager_color_completion, \c fish_pager_color_description and \c fish_pager_color_progress are used to change the color of various elements in \c fish. These variables are universal, i.e. when changing them, their new value will be used by all running fish sessions. The new value will also be retained when restarting fish.
|
||||||
- \c PATH, which is an array of directories in which to search for commands
|
- \c PATH, which is an array of directories in which to search for commands
|
||||||
- \c umask, which is the current file creation mask. The preffered way to change the umask variable is through the <a href="commands.html#umask">umask shellscript function</a>. An attempt to set umask to an invalid value will always fail.
|
- \c umask, which is the current file creation mask. The prefered way to change the umask variable is through the <a href="commands.html#umask">umask shellscript function</a>. An attempt to set umask to an invalid value will always fail.
|
||||||
|
|
||||||
\c fish also sends additional information to the user through the
|
\c fish also sends additional information to the user through the
|
||||||
values of certain environment variables. The user can not change the values of these variables. They are:
|
values of certain environment variables. The user can not change the
|
||||||
|
values of these variables. They are:
|
||||||
|
|
||||||
- \c _, which is the name of the currently running command.
|
- \c _, which is the name of the currently running command.
|
||||||
- \c history, which is an array containing the last commands that where entered
|
- \c history, which is an array containing the last commands that where entered.
|
||||||
- \c HOME, which is the users home directory. This variable can only be changed by the root user.
|
- \c HOME, which is the users home directory. This variable can only be changed by the root user.
|
||||||
- \c PWD, which is the current working directory.
|
- \c PWD, which is the current working directory.
|
||||||
- \c status, which is the exit status of the last foreground job to exit. If a job contains pipelines, the status of the last command in the pipeline is the status for the job.
|
- \c status, which is the exit status of the last foreground job to exit. If a job contains pipelines, the status of the last command in the pipeline is the status for the job.
|
||||||
- \c USER, which is the username. This variable can only be changed by the root user.
|
- \c USER, which is the username. This variable can only be changed by the root user.
|
||||||
|
|
||||||
Variables whose name are in uppercase are exported to the commands
|
Variables whose name are in uppercase are exported to the commands
|
||||||
started by fish. \c fish also uses several variables internally. Such
|
started by fish. This rule is not enfored by fish, but it is good
|
||||||
variables are prefixed with the string __FISH or __fish. These should
|
coding practice to use casing to distinguish between exported and
|
||||||
be ignored by the user.
|
unexported variables. \c fish also uses several variables
|
||||||
|
internally. Such variables are prefixed with the string __FISH or
|
||||||
|
__fish. These should be ignored by the user.
|
||||||
|
|
||||||
\section builtin-overview Builtins
|
\section builtin-overview Builtins
|
||||||
|
|
||||||
@@ -654,14 +737,16 @@ Here are some of the commands available in the editor:
|
|||||||
- End or Ctrl-e moves to the end of line
|
- End or Ctrl-e moves to the end of line
|
||||||
- Left and right moves one character left or right
|
- Left and right moves one character left or right
|
||||||
- Alt-left and Alt-right moves one word left or right, or moves forward/backward in the directory history if the commandline is empty
|
- Alt-left and Alt-right moves one word left or right, or moves forward/backward in the directory history if the commandline is empty
|
||||||
|
- Up and down search the command history for the previous/next command containing the string that was specified on the commandline before the search was started. If the commandline was empty when the search started, all commands match. See the <a href='#history'>history </a>section for more information on history searching.
|
||||||
|
- Alt-up and Alt-down search the command history for the previous/next token containing the token under the cursor before the search was started. If the commandline was not on a token when the search started, all tokens match. See the <a href='#history'>history </a>section for more information on history searching.
|
||||||
- Delete and backspace removes one character forwards or backwards
|
- Delete and backspace removes one character forwards or backwards
|
||||||
- Ctrl-c delete entire line
|
- Ctrl-c delete entire line
|
||||||
- Ctrl-d delete one character to the right of the cursor, unless the buffer is empty, in which case the shell will exit
|
- Ctrl-d delete one character to the right of the cursor, unless the buffer is empty, in which case the shell will exit
|
||||||
- Ctrl-k move contents from cursor to end of line to <a href="#killring">killring</a>
|
- Ctrl-k move contents from the cursor to the end of line to the <a href="#killring">killring</a>
|
||||||
- Ctrl-u move contents from beginning of line to cursor <a href="#killring">killring</a>
|
- Ctrl-u move contents from the beginning of line to the cursor to the <a href="#killring">killring</a>
|
||||||
- Ctrl-l clear and repaint screen
|
- Ctrl-l clear and repaint screen
|
||||||
- Ctrl-w move previous word to <a href="#killring">killring</a>
|
- Ctrl-w move previous word to the <a href="#killring">killring</a>
|
||||||
- Alt-d move next word to <a href="#killring">killring</a>
|
- Alt-d move next word to the <a href="#killring">killring</a>
|
||||||
- Alt-w prints a short description of the command under the cursor
|
- Alt-w prints a short description of the command under the cursor
|
||||||
- Alt-l lists the contents of the current directory, unless the cursor is over a directory argument, in which case the contents of that directory will be listed
|
- Alt-l lists the contents of the current directory, unless the cursor is over a directory argument, in which case the contents of that directory will be listed
|
||||||
- Alt-k prints a list of all key bindings
|
- Alt-k prints a list of all key bindings
|
||||||
@@ -721,24 +806,34 @@ After a command has been entered, it is inserted at the end of a
|
|||||||
history list. Any duplicate history items are automatically
|
history list. Any duplicate history items are automatically
|
||||||
removed. By pressing the up and down keys, the user can search
|
removed. By pressing the up and down keys, the user can search
|
||||||
forwards and backwards in the history. If the current command line is
|
forwards and backwards in the history. If the current command line is
|
||||||
not empty when starting a history search, only the commands starting
|
not empty when starting a history search, only the commands containing
|
||||||
with the string entered into the command line are searched.
|
the string entered into the command line are shown.
|
||||||
|
|
||||||
|
By pressing Alt-up and Alt-down, a history search is also performed,
|
||||||
|
but instead of searching for a complete commandline, each commandline
|
||||||
|
is tokenized into separate elements just like it would be before
|
||||||
|
execution, and each such token is matched agains the token under the
|
||||||
|
cursor when the search began.
|
||||||
|
|
||||||
|
History searches can be aborted by pressing the escape key.
|
||||||
|
|
||||||
The history is stored in the file '.fish_history'. It is automatically
|
The history is stored in the file '.fish_history'. It is automatically
|
||||||
read on startup and merged on program exit.
|
read on startup and merged on program exit.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
To search for previous entries starting with the letter 'l', type 'l'
|
To search for previous entries containing the word 'make', type 'make'
|
||||||
in the console and press the up key.
|
in the console and press the up key.
|
||||||
|
|
||||||
\section job-control Running multiple programs
|
\section job-control Running multiple programs
|
||||||
|
|
||||||
Normally when \c fish starts a program, this program will be put
|
Normally when \c fish starts a program, this program will be put in
|
||||||
in the foreground, meaning it will take control of the terminal and
|
the foreground, meaning it will take control of the terminal and \c
|
||||||
\c fish will be stopped until the program finishes. Sometimes
|
fish will be stopped until the program finishes. Sometimes this is not
|
||||||
this is not desirable. In such cases, there are several ways in which
|
desirable. For example, you may wish to start an application with a
|
||||||
the user can change <tt>fish</tt>'s behaviour.
|
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.
|
||||||
|
|
||||||
-# 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 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.
|
-# 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.
|
||||||
@@ -746,14 +841,29 @@ the user can change <tt>fish</tt>'s behaviour.
|
|||||||
|
|
||||||
\section initialization Initialization files
|
\section initialization Initialization files
|
||||||
|
|
||||||
On startup, \c fish evaluates the file /etc/fish (Or ~/etc/fish if you installed fish in your home directory) and ~/.fish, in that
|
On startup, \c fish evaluates the file /etc/fish (Or ~/etc/fish if you
|
||||||
order. If you want to run a command only on starting an interactive
|
installed fish in your home directory) and ~/.fish, in that order. If
|
||||||
shell, use the output of the 'status --is-interactive' command. If
|
you want to run a command only on starting an interactive shell, use
|
||||||
you want to run a command only on starting a login shell, use 'status --is-login' instead.
|
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 you want to run a set of commands when \c fish exits, redefine the
|
Example:
|
||||||
<a href="#hooks">function hook</a> \c fish_on_exit. If the \c
|
|
||||||
fish_on_exit is defined, it will be execute before the shell exits.
|
If you want to add the directory ~/linux/bin to your PATH variable
|
||||||
|
when loging in, add the following to your ~/.fish file:
|
||||||
|
|
||||||
|
<pre>if status --is-login
|
||||||
|
set PATH $PATH ~/linux/bin
|
||||||
|
end</pre>
|
||||||
|
|
||||||
|
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
|
||||||
|
echo fish is now exiting
|
||||||
|
end</pre>
|
||||||
|
|
||||||
<a href="#variables-universal">Universal variables</a> are stored in
|
<a href="#variables-universal">Universal variables</a> are stored in
|
||||||
the file .fishd.HOSTNAME, where HOSTNAME is the name of your
|
the file .fishd.HOSTNAME, where HOSTNAME is the name of your
|
||||||
@@ -772,7 +882,7 @@ marked red.
|
|||||||
Detected errors include:
|
Detected errors include:
|
||||||
|
|
||||||
- Non existing commands.
|
- Non existing commands.
|
||||||
- Reading or appending from non existing files.
|
- Reading from or appending to a non existing file.
|
||||||
- Incorrect use of output redirects
|
- Incorrect use of output redirects
|
||||||
- Mismatched parenthesis
|
- Mismatched parenthesis
|
||||||
|
|
||||||
@@ -789,7 +899,7 @@ fish_pager_color_description and \c fish_pager_color_progress. Valid
|
|||||||
values are \c black, \c red, \c green, \c brown, \c yellow, \c blue,
|
values are \c black, \c red, \c green, \c brown, \c yellow, \c blue,
|
||||||
\c magenta, \c purple, \c cyan, \c white or \c normal. Setting one of
|
\c magenta, \c purple, \c cyan, \c white or \c normal. Setting one of
|
||||||
the above variables to normal will mean that the text color will be
|
the above variables to normal will mean that the text color will be
|
||||||
set to the default color for the terminal.
|
set to the default foreground color for the terminal.
|
||||||
|
|
||||||
\subsection prompt Programmable prompt
|
\subsection prompt Programmable prompt
|
||||||
|
|
||||||
@@ -835,15 +945,28 @@ end
|
|||||||
</pre>
|
</pre>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
\subsection hooks Event hooks
|
\subsection event Event handlers
|
||||||
|
|
||||||
There are several special function names in fish. If a function is
|
When defining a new function in fish, it is possible to make it into an
|
||||||
given this name, it will be automatically called when a specific event
|
event handler, i.e. a function that is automatically run when a
|
||||||
has occured. These functions are:
|
specific event takes place. Events that can trigger a handler currently are:
|
||||||
|
|
||||||
- \c fish_on_exit, which is called before the shell exits
|
* When a signal is delivered
|
||||||
- \c fish_on_exec, which is called before interactively executing a command
|
* When a process or job exits
|
||||||
- \c fish_on_return, which is called when control returns to the shell after interactively executing a command
|
* When the value of a variable is updated
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
To specify a signal handler for the WINCH signal, write:
|
||||||
|
|
||||||
|
<pre>function --on-signal WINCH my_signal_handler
|
||||||
|
echo Got WINCH signal!
|
||||||
|
end
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
For more information on how to define new event handlers, see the
|
||||||
|
documentation for the <a href='builtins.html#function'>function</a>
|
||||||
|
command.
|
||||||
|
|
||||||
\section issues Common issues with fish
|
\section issues Common issues with fish
|
||||||
|
|
||||||
@@ -860,9 +983,7 @@ directory, or install them in /etc.
|
|||||||
\subsection todo-features Missing features
|
\subsection todo-features Missing features
|
||||||
|
|
||||||
- Complete vi-mode key bindings
|
- Complete vi-mode key bindings
|
||||||
- '**' wildcard for recursive wildcard matching
|
|
||||||
- next-history-complete
|
- next-history-complete
|
||||||
- umask shellscript function
|
|
||||||
- builtin wait command
|
- builtin wait command
|
||||||
- More completions (for example xterm, vim,
|
- More completions (for example xterm, vim,
|
||||||
konsole, gnome-terminal, dcop, cdrecord, cron, xargs
|
konsole, gnome-terminal, dcop, cdrecord, cron, xargs
|
||||||
@@ -871,9 +992,8 @@ bibtex, patch, aspell, xpdf,
|
|||||||
zip, compress, wine, xmms, dig, wine, batch, cron,
|
zip, compress, wine, xmms, dig, wine, batch, cron,
|
||||||
g++, javac, java, gcj, lpr, doxygen, whois, find)
|
g++, javac, java, gcj, lpr, doxygen, whois, find)
|
||||||
- Undo support
|
- Undo support
|
||||||
- Multiple input characters should be inserted in one batch whenever possible, to avoid flickering
|
|
||||||
- Check keybinding commands for output - if non has happened, don't repaint to reduce flicker
|
- Check keybinding commands for output - if non has happened, don't repaint to reduce flicker
|
||||||
- the jobs builtin should be able to give information on a specific job, such as the pids of the processes in the job
|
- The jobs builtin should be able to give information on a specific job, such as the pids of the processes in the job
|
||||||
- Syntax highlighting should mark cd to non-existing directories as an error
|
- Syntax highlighting should mark cd to non-existing directories as an error
|
||||||
|
|
||||||
|
|
||||||
@@ -904,13 +1024,13 @@ g++, javac, java, gcj, lpr, doxygen, whois, find)
|
|||||||
- Many completions are made specifically for the GNU
|
- Many completions are made specifically for the GNU
|
||||||
version of a POSIX command
|
version of a POSIX command
|
||||||
- Yanking weird characters from clipboard prints Unicode escapes
|
- Yanking weird characters from clipboard prints Unicode escapes
|
||||||
- Prefix string in completion display is sometimes incorrect
|
|
||||||
|
|
||||||
If you think you have found a bug not described here, please send a
|
If you think you have found a bug not described here, please send a
|
||||||
report to <a href="mailto:axel@liljencrantz.se"> axel@liljencrantz.se
|
report to <a href="mailto:axel@liljencrantz.se"> axel@liljencrantz.se
|
||||||
</a>.
|
</a>.
|
||||||
|
|
||||||
\subsection Known issues
|
\subsection issues Known issues
|
||||||
|
|
||||||
Older versions of Doxygen has bugs in the man-page generation which
|
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
|
cause the builtin help to render incorrectly. Version 1.2.14 is known
|
||||||
@@ -942,6 +1062,10 @@ Most tradeoffs between power and ease of use can be avoided with careful design.
|
|||||||
-# Whenever possible without breaking the above goals, fish should
|
-# Whenever possible without breaking the above goals, fish should
|
||||||
follow the Posix syntax.
|
follow the Posix syntax.
|
||||||
|
|
||||||
|
To achive these high-level goals, the fish design relies on a number
|
||||||
|
of more specific design principles. These are presented below,
|
||||||
|
together with a rationale and a few examples for each.
|
||||||
|
|
||||||
\subsection ortho The law of orthogonality
|
\subsection ortho The law of orthogonality
|
||||||
|
|
||||||
The shell language should have a small set of orthogonal features. Any
|
The shell language should have a small set of orthogonal features. Any
|
||||||
@@ -958,7 +1082,10 @@ program harder to maintain and update.
|
|||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
- Here documents are too similar to using echo inside of a pipeline.
|
- Here documents are too similar to using echo inside of a pipeline.
|
||||||
- The different quoting styles are silly. ("", '' and \$'')
|
- Subshells, command substitution and process substitution are strongly related. \c fish only supports command substitution, the others can be achived either using a block or the psub shellscript function.
|
||||||
|
- Having both aliases and functions is confusing, especially since both of them have limitations and problems. \c fish sunctions have none of the drawbacks of either syntax.
|
||||||
|
- The many Posix quoting styles are silly, especially \$''.
|
||||||
|
|
||||||
|
|
||||||
\subsection sep The law of minimalism
|
\subsection sep The law of minimalism
|
||||||
|
|
||||||
@@ -990,9 +1117,8 @@ and many other funtions can easily be done in external programs. They
|
|||||||
should not be supported internally by the shell.
|
should not be supported internally by the shell.
|
||||||
|
|
||||||
The law of minimalism does not imply that a large feature set is
|
The law of minimalism does not imply that a large feature set is
|
||||||
bad. So long as a feature is not part of the language itself, but a
|
bad. So long as a feature is not part of the shell itself, but a
|
||||||
separate command or at least a shellscript function, bloat is much
|
separate command or at least a shellscript function, bloat is fine.
|
||||||
more acceptable.
|
|
||||||
|
|
||||||
\subsection conf Configurability is the root of all evil
|
\subsection conf Configurability is the root of all evil
|
||||||
|
|
||||||
@@ -1015,7 +1141,7 @@ enough approximation of it.
|
|||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
- Fish allows the user to set various syntax highlighting colors. This is needed because fish does not know what colors the terminal uses by default, which might make some things unreadable. The proper solution would be for text color preferences to be defined centrally by the user for all programs, and for the terminal emulator to send these color properties to fish.
|
- Fish allows the user to set various syntax highlighting colors. This is needed because fish does not know what colors the terminal uses by default, which might make some things unreadable. The proper solution would be for text color preferences to be defined centrally by the user for all programs, and for the terminal emulator to send these color properties to fish.
|
||||||
- Fish does not allow you to set the history filename, the number of history entries, different language substyles or any number of other common cshell configuration options
|
- Fish does not allow you to set the history filename, the number of history entries, different language substyles or any number of other common shell configuration options.
|
||||||
|
|
||||||
A special note on the evils of configurability is the long list of
|
A special note on the evils of configurability is the long list of
|
||||||
very useful features found in some shells, that are not turned on by
|
very useful features found in some shells, that are not turned on by
|
||||||
@@ -1033,13 +1159,18 @@ considered once a user interface has been designed.
|
|||||||
|
|
||||||
Rationale:
|
Rationale:
|
||||||
|
|
||||||
If too much attention is given to what is easy to implement the law of
|
This design rule is different than the others, since it describes how
|
||||||
orthogonality and the law of minimalism will by necessity be disobeyed.
|
one should go about designing new features, not what the features
|
||||||
|
should be. The problem with focusing on what can be done, and what is
|
||||||
|
easy to do, is that to much of the implementation is exposed. This
|
||||||
|
means that the user must know a great deal about the underlying system
|
||||||
|
to be able to guess how the shell works, it also means that the
|
||||||
|
language will often be rather low-level.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
- There should only be one type of input to the shell, lists of commands. Loops, conditionals and variable assignments are all performed through regular commands.
|
- There should only be one type of input to the shell, lists of commands. Loops, conditionals and variable assignments are all performed through regular commands.
|
||||||
- The differences between builtin commands, shellscript functions and builtin commands should be made as small as possible. Builtins and shellscript functions should have exactly the same types of argument expantion as other commands, should be possible to use in any position in a pipeline, and should support any io redirection.
|
- The differences between builtin commands, shellscript functions and builtin commands should be made as small as possible. Builtins and shellscript functions should have exactly the same types of argument expansion as other commands, should be possible to use in any position in a pipeline, and should support any io redirection.
|
||||||
- Instead of forking when performing command substitution to provide a fake variable scope, all fish commands are performed from the same process, and fish instead supports true scoping
|
- Instead of forking when performing command substitution to provide a fake variable scope, all fish commands are performed from the same process, and fish instead supports true scoping
|
||||||
- All blocks end with the \c end builtin
|
- All blocks end with the \c end builtin
|
||||||
|
|
||||||
@@ -1074,7 +1205,6 @@ Examples:
|
|||||||
/** \page about About fish
|
/** \page about About fish
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
\section about-program About the program
|
\section about-program About the program
|
||||||
|
|
||||||
\c fish is meant to be used for interactive shell tasks on a modern
|
\c fish is meant to be used for interactive shell tasks on a modern
|
||||||
@@ -1255,17 +1385,6 @@ 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 <tt>echo</tt>, <tt>kill</tt>, <tt>printf</tt> and <tt>time</tt>
|
||||||
instead of reimplementing them as builtins.
|
instead of reimplementing them as builtins.
|
||||||
|
|
||||||
The globbing in fish is significantly simplified. Since I can never
|
|
||||||
remember all the subtle differences between single and double quotes,
|
|
||||||
which kind of tick is used for command substitution and all the other
|
|
||||||
strange quirks of of the Posix shell language, that aspect of shells
|
|
||||||
has been significantly simplified. This makes \c fish unsuitable for
|
|
||||||
strange shell scripting, but much more suited to interactive needs
|
|
||||||
than regular shells.
|
|
||||||
|
|
||||||
There is no difference between double and single quotes. They both
|
|
||||||
turn of all globbing and escape sequences. They can be nested.
|
|
||||||
|
|
||||||
Token separation is performed before variable expansion. This means
|
Token separation is performed before variable expansion. This means
|
||||||
that even if a variable contains spaces, it will never be separated
|
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
|
into multiple arguments. If you want to tokenize a string, you can use
|
||||||
|
|||||||
@@ -18,16 +18,12 @@ The <tt>set</tt> builtin causes fish to assign the variable <tt>VARIABLE_NAME</t
|
|||||||
If set is called with no arguments, the names and values of all
|
If set is called with no arguments, the names and values of all
|
||||||
environment variables are printed.
|
environment variables are printed.
|
||||||
|
|
||||||
If set is called with only one argument, the scope of the variable
|
|
||||||
with the given name will be changed as specified, but it's value will
|
|
||||||
remain the same. If the variable did not previously exist, it's value
|
|
||||||
will be an empty string.
|
|
||||||
|
|
||||||
If the \c -e or \c --erase option is specified, the variable
|
If the \c -e or \c --erase option is specified, the variable
|
||||||
specified by the following arguments will be erased
|
specified by the following arguments will be erased
|
||||||
|
|
||||||
If a variable is set to more than one value, the variable will be an
|
If a variable is set to more than one value, the variable will be an
|
||||||
array with the specified elements.
|
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 <tt>PATH[1
|
If the variable name is one or more array elements, such as <tt>PATH[1
|
||||||
3 7]</tt>, only those array elements specified will be changed.
|
3 7]</tt>, only those array elements specified will be changed.
|
||||||
|
|||||||
89
env.c
89
env.c
@@ -45,7 +45,7 @@
|
|||||||
/**
|
/**
|
||||||
Command used to start fishd
|
Command used to start fishd
|
||||||
*/
|
*/
|
||||||
#define FISHD_CMD L"if which fishd >/dev/null; fishd ^/tmp/fish.%s.log; end"
|
#define FISHD_CMD L"if which fishd >/dev/null; fishd ^/tmp/fishd.%s.log; end"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Value denoting a null string
|
Value denoting a null string
|
||||||
@@ -343,43 +343,66 @@ void env_init()
|
|||||||
if( !path )
|
if( !path )
|
||||||
{
|
{
|
||||||
env_set( L"PATH", L"/bin" ARRAY_SEP_STR L"/usr/bin", ENV_EXPORT | ENV_GLOBAL );
|
env_set( L"PATH", L"/bin" ARRAY_SEP_STR L"/usr/bin", ENV_EXPORT | ENV_GLOBAL );
|
||||||
|
path = env_get( L"PATH" );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int i;
|
int i, j;
|
||||||
array_list_t l;
|
array_list_t l;
|
||||||
int has_bin=0, has_usr_bin=0;
|
|
||||||
|
|
||||||
al_init( &l );
|
al_init( &l );
|
||||||
expand_variable_array( path, &l );
|
expand_variable_array( path, &l );
|
||||||
|
|
||||||
|
debug( 3, L"PATH is %ls", path );
|
||||||
|
|
||||||
for( i=0; i<al_get_count( &l); i++ )
|
|
||||||
{
|
const wchar_t *path_el[] =
|
||||||
wchar_t * el = (wchar_t *)al_get( &l, i );
|
|
||||||
if( contains_str( el, L"/bin", L"/bin/", (void *)0) )
|
|
||||||
{
|
{
|
||||||
has_bin = 1;
|
L"/bin",
|
||||||
|
L"/usr/bin",
|
||||||
|
PREFIX L"/bin",
|
||||||
|
0
|
||||||
}
|
}
|
||||||
if( contains_str( el, L"/usr/bin", L"/usr/bin/", (void *)0) )
|
;
|
||||||
|
|
||||||
|
for( j=0; path_el[j]; j++ )
|
||||||
|
{
|
||||||
|
int has_el=0;
|
||||||
|
|
||||||
|
debug( 3, L"Check directory %ls", path_el[j] );
|
||||||
|
|
||||||
|
|
||||||
|
for( i=0; i<al_get_count( &l); i++ )
|
||||||
{
|
{
|
||||||
has_bin = 1;
|
wchar_t * el = (wchar_t *)al_get( &l, i );
|
||||||
|
size_t len = wcslen( el );
|
||||||
|
while( (len > 0) && (el[len-1]==L'/') )
|
||||||
|
len--;
|
||||||
|
if( (wcslen( path_el[j] ) == len) && (wcsncmp( el, path_el[j], len)==0) )
|
||||||
|
{
|
||||||
|
has_el = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !has_el )
|
||||||
|
{
|
||||||
|
string_buffer_t b;
|
||||||
|
debug( 3, L"directory %ls was missing", path_el[j] );
|
||||||
|
sb_init( &b );
|
||||||
|
sb_append2( &b, path,
|
||||||
|
ARRAY_SEP_STR,
|
||||||
|
path_el[j],
|
||||||
|
(void *)0 );
|
||||||
|
|
||||||
|
env_set( L"PATH", (wchar_t *)b.buff, ENV_GLOBAL | ENV_EXPORT );
|
||||||
|
sb_destroy( &b );
|
||||||
|
path = env_get( L"PATH" );
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !( has_bin && has_usr_bin ) )
|
debug( 3, L"After: PATH is %ls", path );
|
||||||
{
|
|
||||||
string_buffer_t b;
|
|
||||||
sb_init( &b );
|
|
||||||
sb_append( &b, path );
|
|
||||||
if( !has_bin )
|
|
||||||
sb_append( &b, ARRAY_SEP_STR L"/bin" );
|
|
||||||
if( !has_usr_bin )
|
|
||||||
sb_append( &b, ARRAY_SEP_STR L"/usr/bin" );
|
|
||||||
|
|
||||||
env_set( L"PATH", (wchar_t *)b.buff, ENV_GLOBAL | ENV_EXPORT );
|
|
||||||
sb_destroy( &b );
|
|
||||||
}
|
|
||||||
|
|
||||||
al_foreach( &l, (void (*)(const void *))&free );
|
al_foreach( &l, (void (*)(const void *))&free );
|
||||||
al_destroy( &l );
|
al_destroy( &l );
|
||||||
|
|
||||||
@@ -569,8 +592,11 @@ void env_set( const wchar_t *key,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( !proc_had_barrier)
|
if( !proc_had_barrier)
|
||||||
|
{
|
||||||
|
proc_had_barrier=1;
|
||||||
env_universal_barrier();
|
env_universal_barrier();
|
||||||
|
}
|
||||||
|
|
||||||
if( env_universal_get( key ) )
|
if( env_universal_get( key ) )
|
||||||
{
|
{
|
||||||
int export = 0;
|
int export = 0;
|
||||||
@@ -785,7 +811,11 @@ wchar_t *env_get( const wchar_t *key )
|
|||||||
env = env->next;
|
env = env->next;
|
||||||
}
|
}
|
||||||
if( !proc_had_barrier)
|
if( !proc_had_barrier)
|
||||||
|
{
|
||||||
|
proc_had_barrier=1;
|
||||||
env_universal_barrier();
|
env_universal_barrier();
|
||||||
|
}
|
||||||
|
|
||||||
item = env_universal_get( key );
|
item = env_universal_get( key );
|
||||||
|
|
||||||
if( !item || (wcscmp( item, ENV_NULL )==0))
|
if( !item || (wcscmp( item, ENV_NULL )==0))
|
||||||
@@ -822,7 +852,11 @@ int env_exist( const wchar_t *key )
|
|||||||
env = env->next;
|
env = env->next;
|
||||||
}
|
}
|
||||||
if( !proc_had_barrier)
|
if( !proc_had_barrier)
|
||||||
|
{
|
||||||
|
proc_had_barrier=1;
|
||||||
env_universal_barrier();
|
env_universal_barrier();
|
||||||
|
}
|
||||||
|
|
||||||
item = env_universal_get( key );
|
item = env_universal_get( key );
|
||||||
|
|
||||||
return item != 0;
|
return item != 0;
|
||||||
@@ -1056,8 +1090,11 @@ static void export_func2( const void *k, const void *v, void *aux )
|
|||||||
char **env_export_arr( int recalc)
|
char **env_export_arr( int recalc)
|
||||||
{
|
{
|
||||||
if( recalc && !proc_had_barrier)
|
if( recalc && !proc_had_barrier)
|
||||||
|
{
|
||||||
|
proc_had_barrier=1;
|
||||||
env_universal_barrier();
|
env_universal_barrier();
|
||||||
|
}
|
||||||
|
|
||||||
if( has_changed )
|
if( has_changed )
|
||||||
{
|
{
|
||||||
array_list_t uni;
|
array_list_t uni;
|
||||||
|
|||||||
@@ -117,19 +117,16 @@ static int get_socket( int fork_ok )
|
|||||||
if( connect( s, (struct sockaddr *)&local, len) == -1 )
|
if( connect( s, (struct sockaddr *)&local, len) == -1 )
|
||||||
{
|
{
|
||||||
close( s );
|
close( s );
|
||||||
if( fork_ok )
|
if( fork_ok && start_fishd )
|
||||||
{
|
{
|
||||||
debug( 2, L"Could not connect to socket %d, starting fishd", s );
|
debug( 2, L"Could not connect to socket %d, starting fishd", s );
|
||||||
|
|
||||||
if( start_fishd )
|
start_fishd();
|
||||||
{
|
|
||||||
start_fishd();
|
|
||||||
}
|
|
||||||
|
|
||||||
return get_socket( 0 );
|
return get_socket( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
debug( 3, L"Could not connect to socket %d, already tried forking, giving up", s );
|
debug( 2, L"Could not connect to socket %d, already tried manual restart (or no command supplied), giving up", s );
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +171,7 @@ static void check_connection()
|
|||||||
|
|
||||||
if( env_universal_server.killme )
|
if( env_universal_server.killme )
|
||||||
{
|
{
|
||||||
debug( 2, L"Lost connection to universal variable server." );
|
debug( 3, L"Lost connection to universal variable server." );
|
||||||
close( env_universal_server.fd );
|
close( env_universal_server.fd );
|
||||||
env_universal_server.fd = -1;
|
env_universal_server.fd = -1;
|
||||||
env_universal_server.killme=0;
|
env_universal_server.killme=0;
|
||||||
@@ -193,7 +190,7 @@ static void reconnect()
|
|||||||
if( get_socket_count >= RECONNECT_COUNT )
|
if( get_socket_count >= RECONNECT_COUNT )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
debug( 2, L"Get new fishd connection" );
|
debug( 3, L"Get new fishd connection" );
|
||||||
|
|
||||||
init = 0;
|
init = 0;
|
||||||
env_universal_server.fd = get_socket(1);
|
env_universal_server.fd = get_socket(1);
|
||||||
@@ -262,6 +259,8 @@ int env_universal_read_all()
|
|||||||
if( !init)
|
if( !init)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
debug( 3, L"env_universal_read_all()" );
|
||||||
|
|
||||||
if( env_universal_server.fd == -1 )
|
if( env_universal_server.fd == -1 )
|
||||||
{
|
{
|
||||||
reconnect();
|
reconnect();
|
||||||
@@ -290,11 +289,13 @@ wchar_t *env_universal_get( const wchar_t *name )
|
|||||||
if( !name )
|
if( !name )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
debug( 3, L"env_universal_get( \"%ls\" )", name );
|
||||||
return env_universal_common_get( name );
|
return env_universal_common_get( name );
|
||||||
}
|
}
|
||||||
|
|
||||||
int env_universal_get_export( const wchar_t *name )
|
int env_universal_get_export( const wchar_t *name )
|
||||||
{
|
{
|
||||||
|
debug( 3, L"env_universal_get_export()" );
|
||||||
return env_universal_common_get_export( name );
|
return env_universal_common_get_export( name );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,7 +306,7 @@ void env_universal_barrier()
|
|||||||
|
|
||||||
if( !init || ( env_universal_server.fd == -1 ))
|
if( !init || ( env_universal_server.fd == -1 ))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
barrier_reply = 0;
|
barrier_reply = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -330,6 +331,7 @@ void env_universal_barrier()
|
|||||||
if( env_universal_server.fd == -1 )
|
if( env_universal_server.fd == -1 )
|
||||||
{
|
{
|
||||||
reconnect();
|
reconnect();
|
||||||
|
debug( 2, L"barrier interrupted, exiting" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,6 +349,7 @@ void env_universal_barrier()
|
|||||||
if( env_universal_server.fd == -1 )
|
if( env_universal_server.fd == -1 )
|
||||||
{
|
{
|
||||||
reconnect();
|
reconnect();
|
||||||
|
debug( 2, L"barrier interrupted, exiting (2)" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
FD_ZERO( &fds );
|
FD_ZERO( &fds );
|
||||||
@@ -365,7 +368,7 @@ void env_universal_set( const wchar_t *name, const wchar_t *value, int export )
|
|||||||
if( !init )
|
if( !init )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
debug( 3, L"env_universal_set( %ls, %ls )", name, value );
|
debug( 3, L"env_universal_set( \"%ls\", \"%ls\" )", name, value );
|
||||||
|
|
||||||
msg = create_message( export?SET_EXPORT:SET,
|
msg = create_message( export?SET_EXPORT:SET,
|
||||||
name,
|
name,
|
||||||
@@ -388,8 +391,8 @@ void env_universal_remove( const wchar_t *name )
|
|||||||
if( !init )
|
if( !init )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
debug( 2,
|
debug( 3,
|
||||||
L"env_universal_remove( %ls )",
|
L"env_universal_remove( \"%ls\" )",
|
||||||
name );
|
name );
|
||||||
|
|
||||||
msg= create_message( ERASE, name, 0);
|
msg= create_message( ERASE, name, 0);
|
||||||
|
|||||||
18
event.c
18
event.c
@@ -273,6 +273,9 @@ static void event_fire_internal( event_t *event, array_list_t *arguments )
|
|||||||
int i, j;
|
int i, j;
|
||||||
string_buffer_t *b=0;
|
string_buffer_t *b=0;
|
||||||
array_list_t *fire=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
|
First we free all events that have been removed
|
||||||
@@ -344,15 +347,22 @@ static void event_fire_internal( event_t *event, array_list_t *arguments )
|
|||||||
|
|
||||||
// debug( 1, L"Event handler fires command '%ls'", (wchar_t *)b->buff );
|
// debug( 1, L"Event handler fires command '%ls'", (wchar_t *)b->buff );
|
||||||
|
|
||||||
|
/*
|
||||||
|
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_subshell=1;
|
||||||
is_interactive=1;
|
is_interactive=0;
|
||||||
|
|
||||||
eval( (wchar_t *)b->buff, 0, TOP );
|
eval( (wchar_t *)b->buff, 0, TOP );
|
||||||
is_subshell=0;
|
|
||||||
is_interactive=1;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Restore interactivity flags
|
||||||
|
*/
|
||||||
|
is_subshell = was_subshell;
|
||||||
|
is_interactive = was_interactive;
|
||||||
|
|
||||||
if( b )
|
if( b )
|
||||||
{
|
{
|
||||||
sb_destroy( b );
|
sb_destroy( b );
|
||||||
|
|||||||
3
event.h
3
event.h
@@ -61,6 +61,9 @@ typedef struct
|
|||||||
|
|
||||||
} param1;
|
} param1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
The name of the event handler function
|
||||||
|
*/
|
||||||
const wchar_t *function_name;
|
const wchar_t *function_name;
|
||||||
}
|
}
|
||||||
event_t;
|
event_t;
|
||||||
|
|||||||
44
exec.c
44
exec.c
@@ -261,17 +261,13 @@ static void handle_child_io( io_data_t *io )
|
|||||||
free_fd( io, io->fd );
|
free_fd( io, io->fd );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
We don't mind if this fails, it is just a speculative close
|
|
||||||
to make sure no unexpected untracked fd causes us to fail
|
|
||||||
*/
|
|
||||||
close(io->fd);
|
|
||||||
|
|
||||||
switch( io->io_mode )
|
switch( io->io_mode )
|
||||||
{
|
{
|
||||||
case IO_CLOSE:
|
case IO_CLOSE:
|
||||||
|
close(io->fd);
|
||||||
break;
|
break;
|
||||||
case IO_FILE:
|
case IO_FILE:
|
||||||
|
{
|
||||||
if( (tmp=wopen( io->param1.filename,
|
if( (tmp=wopen( io->param1.filename,
|
||||||
io->param2.flags, 0777 ) )==-1 )
|
io->param2.flags, 0777 ) )==-1 )
|
||||||
{
|
{
|
||||||
@@ -284,6 +280,8 @@ static void handle_child_io( io_data_t *io )
|
|||||||
}
|
}
|
||||||
else if( tmp != io->fd)
|
else if( tmp != io->fd)
|
||||||
{
|
{
|
||||||
|
close(io->fd);
|
||||||
|
|
||||||
if(dup2( tmp, io->fd ) == -1 )
|
if(dup2( tmp, io->fd ) == -1 )
|
||||||
{
|
{
|
||||||
debug( 1,
|
debug( 1,
|
||||||
@@ -295,7 +293,11 @@ static void handle_child_io( io_data_t *io )
|
|||||||
exec_close( tmp );
|
exec_close( tmp );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case IO_FD:
|
case IO_FD:
|
||||||
|
{
|
||||||
|
close(io->fd);
|
||||||
/* debug( 3, L"Redirect fd %d in process %ls (%d) from fd %d",
|
/* debug( 3, L"Redirect fd %d in process %ls (%d) from fd %d",
|
||||||
io->fd,
|
io->fd,
|
||||||
p->actual_cmd,
|
p->actual_cmd,
|
||||||
@@ -311,10 +313,12 @@ static void handle_child_io( io_data_t *io )
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case IO_BUFFER:
|
case IO_BUFFER:
|
||||||
case IO_PIPE:
|
case IO_PIPE:
|
||||||
{
|
{
|
||||||
|
close(io->fd);
|
||||||
|
|
||||||
/* debug( 3, L"Pipe fd %d in process %ls (%d) (Through fd %d)",
|
/* debug( 3, L"Pipe fd %d in process %ls (%d) (Through fd %d)",
|
||||||
io->fd,
|
io->fd,
|
||||||
@@ -937,15 +941,23 @@ void exec( job_t *j )
|
|||||||
case INTERNAL_FUNCTION:
|
case INTERNAL_FUNCTION:
|
||||||
{
|
{
|
||||||
int status = proc_get_last_status();
|
int status = proc_get_last_status();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Handle output from a block or function. This usually
|
Handle output from a block or function. This usually
|
||||||
means do nothing, but in the case of pipes, we have
|
means do nothing, but in the case of pipes, we have
|
||||||
to buffer such io, since otherwisethe internal pipe
|
to buffer such io, since otherwise the internal pipe
|
||||||
buffer might overflow.
|
buffer might overflow.
|
||||||
*/
|
*/
|
||||||
if( !io_buffer )
|
if( !io_buffer )
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
No buffer, se we exit directly. This means we
|
||||||
|
have to manually set the exit status.
|
||||||
|
*/
|
||||||
|
if( p->next == 0 )
|
||||||
|
{
|
||||||
|
proc_set_last_status( j->negate?(status?0:1):status);
|
||||||
|
}
|
||||||
p->completed = 1;
|
p->completed = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -956,8 +968,6 @@ void exec( job_t *j )
|
|||||||
|
|
||||||
if( io_buffer->param2.out_buffer->used != 0 )
|
if( io_buffer->param2.out_buffer->used != 0 )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
pid = fork();
|
pid = fork();
|
||||||
if( pid == 0 )
|
if( pid == 0 )
|
||||||
{
|
{
|
||||||
@@ -1040,7 +1050,6 @@ void exec( job_t *j )
|
|||||||
{
|
{
|
||||||
debug( 3, L"Set status of %ls to %d using short circut", j->command, p->status );
|
debug( 3, L"Set status of %ls to %d using short circut", j->command, p->status );
|
||||||
|
|
||||||
proc_set_last_status( p->status );
|
|
||||||
proc_set_last_status( j->negate?(p->status?0:1):p->status );
|
proc_set_last_status( j->negate?(p->status?0:1):p->status );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1089,10 +1098,7 @@ void exec( job_t *j )
|
|||||||
|
|
||||||
case EXTERNAL:
|
case EXTERNAL:
|
||||||
{
|
{
|
||||||
|
pid = fork();
|
||||||
// fwprintf( stderr,
|
|
||||||
// L"fork on %ls\n", j->command );
|
|
||||||
pid = fork ();
|
|
||||||
if( pid == 0 )
|
if( pid == 0 )
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@@ -1110,8 +1116,8 @@ void exec( job_t *j )
|
|||||||
{
|
{
|
||||||
/* The fork failed. */
|
/* The fork failed. */
|
||||||
debug( 0, FORK_ERROR );
|
debug( 0, FORK_ERROR );
|
||||||
wperror (L"fork");
|
wperror( L"fork" );
|
||||||
exit (1);
|
exit( 1 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1195,7 +1201,7 @@ int exec_subshell( const wchar_t *cmd,
|
|||||||
if( !cmd )
|
if( !cmd )
|
||||||
{
|
{
|
||||||
debug( 1,
|
debug( 1,
|
||||||
L"Sent null command to subshell. This is a fish bug. If it can be reproduced, please send a bug report to %ls",
|
L"Sent null command to subshell. This is a fish bug. If it can be reproduced, please send a bug report to %s",
|
||||||
PACKAGE_BUGREPORT );
|
PACKAGE_BUGREPORT );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
384
expand.c
384
expand.c
@@ -67,6 +67,9 @@ parameter expansion.
|
|||||||
*/
|
*/
|
||||||
#define COMPLETE_LAST_DESC COMPLETE_SEP_STR L"Last background job"
|
#define COMPLETE_LAST_DESC COMPLETE_SEP_STR L"Last background job"
|
||||||
|
|
||||||
|
#define COMPLETE_VAR_DESC L"Variable name is zero characters long."
|
||||||
|
#define COMPLETE_VAR2_DESC L"Variable name is zero characters long. Did you mean{$VARIABLE}? To learn about variable expansion in fish, type 'help expand-variable'."
|
||||||
|
|
||||||
/**
|
/**
|
||||||
String in process expansion denoting ourself
|
String in process expansion denoting ourself
|
||||||
*/
|
*/
|
||||||
@@ -92,23 +95,29 @@ parameter expansion.
|
|||||||
any tokens which need to be expanded or otherwise altered. Clean
|
any tokens which need to be expanded or otherwise altered. Clean
|
||||||
strings can be passed through expand_string and expand_one without
|
strings can be passed through expand_string and expand_one without
|
||||||
changing them. About 90% of all strings are clean, so skipping
|
changing them. About 90% of all strings are clean, so skipping
|
||||||
expantion on them actually does save a small amount of time.
|
expansion on them actually does save a small amount of time, since
|
||||||
|
it avoids multiple memory allocations during the expansion process.
|
||||||
*/
|
*/
|
||||||
static int is_clean( const wchar_t *in )
|
static int is_clean( const wchar_t *in )
|
||||||
{
|
{
|
||||||
|
|
||||||
const wchar_t * str = in;
|
const wchar_t * str = in;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Test characters that have a special meaning in the first character position
|
||||||
|
*/
|
||||||
if( wcschr( UNCLEAN_FIRST, *str ) )
|
if( wcschr( UNCLEAN_FIRST, *str ) )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Test characters that have a special meaning in any character position
|
||||||
|
*/
|
||||||
while( *str )
|
while( *str )
|
||||||
{
|
{
|
||||||
if( wcschr( UNCLEAN, *str ) )
|
if( wcschr( UNCLEAN, *str ) )
|
||||||
return 0;
|
return 0;
|
||||||
str++;
|
str++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// debug( 1, L"%ls", in );
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -120,7 +129,7 @@ static wchar_t *expand_var( wchar_t *in )
|
|||||||
{
|
{
|
||||||
if( !in )
|
if( !in )
|
||||||
return 0;
|
return 0;
|
||||||
return (in[0] == VARIABLE_EXPAND )? env_get( expand_var(in+1) ) : env_get( in );
|
return env_get( in );
|
||||||
}
|
}
|
||||||
|
|
||||||
void expand_variable_array( const wchar_t *val, array_list_t *out )
|
void expand_variable_array( const wchar_t *val, array_list_t *out )
|
||||||
@@ -133,7 +142,6 @@ void expand_variable_array( const wchar_t *val, array_list_t *out )
|
|||||||
if( !cpy )
|
if( !cpy )
|
||||||
{
|
{
|
||||||
die_mem();
|
die_mem();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for( start=pos=cpy; *pos; pos++ )
|
for( start=pos=cpy; *pos; pos++ )
|
||||||
@@ -146,7 +154,7 @@ void expand_variable_array( const wchar_t *val, array_list_t *out )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
al_push( out, wcsdup(start) );
|
al_push( out, wcsdup(start) );
|
||||||
|
|
||||||
free(cpy);
|
free(cpy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -196,7 +204,7 @@ wchar_t *expand_escape_variable( const wchar_t *in )
|
|||||||
switch( al_get_count( &l) )
|
switch( al_get_count( &l) )
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
sb_append( &buff, L"\'\'");
|
sb_append( &buff, L"''");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
@@ -206,9 +214,9 @@ wchar_t *expand_escape_variable( const wchar_t *in )
|
|||||||
if( wcschr( el, L' ' ) && is_quotable( el ) )
|
if( wcschr( el, L' ' ) && is_quotable( el ) )
|
||||||
{
|
{
|
||||||
sb_append2( &buff,
|
sb_append2( &buff,
|
||||||
L"\'",
|
L"'",
|
||||||
el,
|
el,
|
||||||
L"\'",
|
L"'",
|
||||||
(void *)0 );
|
(void *)0 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -232,9 +240,9 @@ wchar_t *expand_escape_variable( const wchar_t *in )
|
|||||||
if( is_quotable( el ) )
|
if( is_quotable( el ) )
|
||||||
{
|
{
|
||||||
sb_append2( &buff,
|
sb_append2( &buff,
|
||||||
L"\'",
|
L"'",
|
||||||
el,
|
el,
|
||||||
L"\'",
|
L"'",
|
||||||
(void *)0 );
|
(void *)0 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -335,7 +343,8 @@ static int match_pid( const wchar_t *cmd,
|
|||||||
Searches for a job with the specified job id, or a job or process
|
Searches for a job with the specified job id, or a job or process
|
||||||
which has the string \c proc as a prefix of its commandline.
|
which has the string \c proc as a prefix of its commandline.
|
||||||
|
|
||||||
If accept_incomplete is true, the remaining string for any matches are inserted.
|
If accept_incomplete is true, the remaining string for any matches
|
||||||
|
are inserted.
|
||||||
|
|
||||||
If accept_incomplete is false, any job matching the specified
|
If accept_incomplete is false, any job matching the specified
|
||||||
string is matched, and the job pgid is returned. If no job
|
string is matched, and the job pgid is returned. If no job
|
||||||
@@ -358,8 +367,6 @@ static int find_process( const wchar_t *proc,
|
|||||||
wchar_t *result;
|
wchar_t *result;
|
||||||
|
|
||||||
job_t *j;
|
job_t *j;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if( iswnumeric(proc) || (wcslen(proc)==0) )
|
if( iswnumeric(proc) || (wcslen(proc)==0) )
|
||||||
{
|
{
|
||||||
@@ -693,11 +700,10 @@ static int expand_variables( wchar_t *in, array_list_t *out )
|
|||||||
int is_ok= 1;
|
int is_ok= 1;
|
||||||
int empty=0;
|
int empty=0;
|
||||||
|
|
||||||
|
|
||||||
for( i=wcslen(in)-1; (i>=0) && is_ok && !empty; i-- )
|
for( i=wcslen(in)-1; (i>=0) && is_ok && !empty; i-- )
|
||||||
{
|
{
|
||||||
c = in[i];
|
c = in[i];
|
||||||
if( c == VARIABLE_EXPAND )
|
if( ( c == VARIABLE_EXPAND ) || (c == VARIABLE_EXPAND_SINGLE ) )
|
||||||
{
|
{
|
||||||
int start_pos = i+1;
|
int start_pos = i+1;
|
||||||
int stop_pos;
|
int stop_pos;
|
||||||
@@ -706,15 +712,8 @@ static int expand_variables( wchar_t *in, array_list_t *out )
|
|||||||
wchar_t * var_val;
|
wchar_t * var_val;
|
||||||
wchar_t * new_in;
|
wchar_t * new_in;
|
||||||
array_list_t l;
|
array_list_t l;
|
||||||
|
int is_single = (c==VARIABLE_EXPAND_SINGLE);
|
||||||
|
|
||||||
|
|
||||||
// fwprintf( stderr, L"Expand %ls\n", in );
|
|
||||||
|
|
||||||
|
|
||||||
// while (in[stop_pos]==VARIABLE_EXPAND)
|
|
||||||
// stop_pos++;
|
|
||||||
|
|
||||||
stop_pos = start_pos;
|
stop_pos = start_pos;
|
||||||
|
|
||||||
while( 1 )
|
while( 1 )
|
||||||
@@ -731,106 +730,156 @@ static int expand_variables( wchar_t *in, array_list_t *out )
|
|||||||
/* printf( "Stop for '%c'\n", in[stop_pos]);*/
|
/* printf( "Stop for '%c'\n", in[stop_pos]);*/
|
||||||
|
|
||||||
var_len = stop_pos - start_pos;
|
var_len = stop_pos - start_pos;
|
||||||
|
|
||||||
|
if( var_len == 0 )
|
||||||
|
{
|
||||||
|
if( in[stop_pos] == BRACKET_BEGIN )
|
||||||
|
{
|
||||||
|
|
||||||
|
error( SYNTAX_ERROR,
|
||||||
|
-1, COMPLETE_VAR_DESC
|
||||||
|
COMPLETE_VAR2_DESC );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error( SYNTAX_ERROR,
|
||||||
|
-1,
|
||||||
|
COMPLETE_VAR_DESC);
|
||||||
|
}
|
||||||
|
|
||||||
|
is_ok = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if( !(var_name = malloc( sizeof(wchar_t)*(var_len+1) )))
|
if( !(var_name = malloc( sizeof(wchar_t)*(var_len+1) )))
|
||||||
{
|
{
|
||||||
die_mem();
|
die_mem();
|
||||||
}
|
}
|
||||||
else
|
wcsncpy( var_name, &in[start_pos], var_len );
|
||||||
{
|
var_name[var_len]='\0';
|
||||||
wcsncpy( var_name, &in[start_pos], var_len );
|
|
||||||
var_name[var_len]='\0';
|
|
||||||
/* printf( "Variable name is %s, len is %d\n", var_name, var_len );*/
|
/* printf( "Variable name is %s, len is %d\n", var_name, var_len );*/
|
||||||
wchar_t *var_val_orig = expand_var( var_name );
|
wchar_t *var_val_orig = expand_var( var_name );
|
||||||
|
|
||||||
if( var_val_orig && (var_val = wcsdup( var_val_orig) ) )
|
if( var_val_orig && (var_val = wcsdup( var_val_orig) ) )
|
||||||
{
|
{
|
||||||
int all_vars=1;
|
int all_vars=1;
|
||||||
array_list_t idx;
|
array_list_t idx;
|
||||||
al_init( &idx );
|
al_init( &idx );
|
||||||
al_init( &l );
|
al_init( &l );
|
||||||
|
|
||||||
if( in[stop_pos] == L'[' )
|
if( in[stop_pos] == L'[' )
|
||||||
{
|
{
|
||||||
wchar_t *end;
|
wchar_t *end;
|
||||||
|
|
||||||
all_vars = 0;
|
all_vars = 0;
|
||||||
|
|
||||||
stop_pos++;
|
stop_pos++;
|
||||||
while( 1 )
|
while( 1 )
|
||||||
|
{
|
||||||
|
int tmp;
|
||||||
|
|
||||||
|
while( iswspace(in[stop_pos]) || (in[stop_pos]==INTERNAL_SEPARATOR))
|
||||||
|
stop_pos++;
|
||||||
|
|
||||||
|
|
||||||
|
if( in[stop_pos] == L']' )
|
||||||
{
|
{
|
||||||
int tmp;
|
stop_pos++;
|
||||||
|
break;
|
||||||
while( iswspace(in[stop_pos]) || (in[stop_pos]==INTERNAL_SEPARATOR))
|
}
|
||||||
stop_pos++;
|
|
||||||
|
|
||||||
|
|
||||||
if( in[stop_pos] == L']' )
|
|
||||||
{
|
|
||||||
stop_pos++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
errno=0;
|
errno=0;
|
||||||
tmp = wcstol( &in[stop_pos], &end, 10 );
|
tmp = wcstol( &in[stop_pos], &end, 10 );
|
||||||
if( ( errno ) || ( end == &in[stop_pos] ) )
|
if( ( errno ) || ( end == &in[stop_pos] ) )
|
||||||
|
{
|
||||||
|
error( SYNTAX_ERROR,
|
||||||
|
-1,
|
||||||
|
L"Expected integer or \']\'" );
|
||||||
|
|
||||||
|
is_ok = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
al_push( &idx, (void *)tmp );
|
||||||
|
stop_pos = end-in;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( is_ok )
|
||||||
|
{
|
||||||
|
expand_variable_array( var_val, &l );
|
||||||
|
if( !all_vars )
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
for( j=0; j<al_get_count( &idx ); j++)
|
||||||
|
{
|
||||||
|
int tmp = (int)al_get( &idx, j );
|
||||||
|
if( tmp < 1 || tmp > al_get_count( &l ) )
|
||||||
{
|
{
|
||||||
error( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
L"Expected integer or \']\'",
|
-1,
|
||||||
-1 );
|
L"Array index out of bounds" );
|
||||||
is_ok = 0;
|
is_ok=0;
|
||||||
|
al_truncate( &idx, j );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
al_push( &idx, (void *)tmp );
|
else
|
||||||
stop_pos = end-in;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( is_ok )
|
|
||||||
{
|
|
||||||
expand_variable_array( var_val, &l );
|
|
||||||
if( !all_vars )
|
|
||||||
{
|
|
||||||
int j;
|
|
||||||
for( j=0; j<al_get_count( &idx ); j++)
|
|
||||||
{
|
{
|
||||||
int tmp = (int)al_get( &idx, j );
|
/* Move string from list l to list idx */
|
||||||
if( tmp < 1 || tmp > al_get_count( &l ) )
|
al_set( &idx, j, al_get( &l, tmp-1 ) );
|
||||||
{
|
al_set( &l, tmp-1, 0 );
|
||||||
error( SYNTAX_ERROR, L"Array index out of bounds", -1 );
|
|
||||||
is_ok=0;
|
|
||||||
al_truncate( &idx, j );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Move string from list l to list idx */
|
|
||||||
al_set( &idx, j, al_get( &l, tmp-1 ) );
|
|
||||||
al_set( &l, tmp-1, 0 );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* Free remaining strings in list l and truncate it */
|
|
||||||
al_foreach( &l, (void (*)(const void *))&free );
|
|
||||||
al_truncate( &l, 0 );
|
|
||||||
/* Add items from list idx back to list l */
|
|
||||||
al_push_all( &l, &idx );
|
|
||||||
}
|
}
|
||||||
free( var_val );
|
/* Free remaining strings in list l and truncate it */
|
||||||
}
|
al_foreach( &l, (void (*)(const void *))&free );
|
||||||
|
al_truncate( &l, 0 );
|
||||||
|
/* Add items from list idx back to list l */
|
||||||
|
al_push_all( &l, &idx );
|
||||||
|
}
|
||||||
|
free( var_val );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( is_single )
|
||||||
|
{
|
||||||
|
string_buffer_t res;
|
||||||
|
sb_init( &res );
|
||||||
|
|
||||||
|
in[i]=0;
|
||||||
|
|
||||||
|
sb_append( &res, in );
|
||||||
|
|
||||||
|
for( j=0; j<al_get_count( &l); j++ )
|
||||||
|
{
|
||||||
|
wchar_t *next = (wchar_t *)al_get( &l, j );
|
||||||
|
|
||||||
|
if( is_ok )
|
||||||
|
{
|
||||||
|
if( j != 0 )
|
||||||
|
sb_append( &res, L" " );
|
||||||
|
sb_append( &res, next );
|
||||||
|
}
|
||||||
|
free( next );
|
||||||
|
}
|
||||||
|
sb_append( &res, &in[stop_pos] );
|
||||||
|
is_ok &= expand_variables( wcsdup((wchar_t *)res.buff), out );
|
||||||
|
|
||||||
|
sb_destroy( &res );
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
for( j=0; j<al_get_count( &l); j++ )
|
for( j=0; j<al_get_count( &l); j++ )
|
||||||
{
|
{
|
||||||
wchar_t *next = (wchar_t *)al_get( &l, j );
|
wchar_t *next = (wchar_t *)al_get( &l, j );
|
||||||
|
|
||||||
if( is_ok )
|
if( is_ok )
|
||||||
{
|
{
|
||||||
|
|
||||||
new_len = wcslen(in) - (stop_pos-start_pos+1) + wcslen( next) +2;
|
new_len = wcslen(in) - (stop_pos-start_pos+1) + wcslen( next) +2;
|
||||||
|
|
||||||
if( !(new_in = malloc( sizeof(wchar_t)*new_len )))
|
if( !(new_in = malloc( sizeof(wchar_t)*new_len )))
|
||||||
{
|
{
|
||||||
error( OOM, L"Out of memory", -1 );
|
die_mem();
|
||||||
is_ok = 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -853,21 +902,54 @@ static int expand_variables( wchar_t *in, array_list_t *out )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
free( next );
|
free( next );
|
||||||
}
|
}
|
||||||
al_destroy( &l );
|
}
|
||||||
al_destroy( &idx );
|
|
||||||
free(in);
|
al_destroy( &l );
|
||||||
free(var_name );
|
al_destroy( &idx );
|
||||||
return is_ok;
|
free(in);
|
||||||
|
free(var_name );
|
||||||
|
return is_ok;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Expand a non-existing variable
|
||||||
|
*/
|
||||||
|
if( c == VARIABLE_EXPAND )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Regular expansion, i.e. expand this argument to nothing
|
||||||
|
*/
|
||||||
|
empty = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
empty = 1;
|
/*
|
||||||
|
Expansion to single argument.
|
||||||
|
*/
|
||||||
|
string_buffer_t res;
|
||||||
|
sb_init( &res );
|
||||||
|
|
||||||
|
in[i]=0;
|
||||||
|
|
||||||
|
sb_append( &res, in );
|
||||||
|
|
||||||
|
sb_append( &res, &in[stop_pos] );
|
||||||
|
is_ok &= expand_variables( wcsdup((wchar_t *)res.buff), out );
|
||||||
|
|
||||||
|
sb_destroy( &res );
|
||||||
|
free(in);
|
||||||
|
free(var_name );
|
||||||
|
return is_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(var_name );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(var_name );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prev_char = c;
|
prev_char = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -966,7 +1048,9 @@ static int expand_brackets( wchar_t *in, int flags, array_list_t *out )
|
|||||||
|
|
||||||
if( syntax_error )
|
if( syntax_error )
|
||||||
{
|
{
|
||||||
error( SYNTAX_ERROR, L"Mismatched brackets", -1 );
|
error( SYNTAX_ERROR,
|
||||||
|
-1,
|
||||||
|
L"Mismatched brackets" );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1112,7 +1196,9 @@ static int expand_subshell( wchar_t *in, array_list_t *out )
|
|||||||
0 ) )
|
0 ) )
|
||||||
{
|
{
|
||||||
case -1:
|
case -1:
|
||||||
error( SYNTAX_ERROR, L"Mismatched parans", -1 );
|
error( SYNTAX_ERROR,
|
||||||
|
-1,
|
||||||
|
L"Mismatched parans" );
|
||||||
return 0;
|
return 0;
|
||||||
case 0:
|
case 0:
|
||||||
al_push( out, in );
|
al_push( out, in );
|
||||||
@@ -1191,26 +1277,25 @@ wchar_t *expand_unescape( const wchar_t * in, int escape_special )
|
|||||||
{
|
{
|
||||||
wchar_t *res = unescape( in, escape_special );
|
wchar_t *res = unescape( in, escape_special );
|
||||||
if( !res )
|
if( !res )
|
||||||
error( SYNTAX_ERROR, L"Unexpected end of string", -1 );
|
error( SYNTAX_ERROR, -1, L"Unexpected end of string" );
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Attempts tilde expansion. Of the string specified. If tilde
|
Attempts tilde expansion. Of the string specified. If tilde
|
||||||
expansion is performed, the argument is freed and a new string is
|
expansion is performed, the original string is freed and a new
|
||||||
allocated in its place. Horrible call signature. Should be
|
string allocated using malloc is returned, otherwise, the original
|
||||||
altered. Fugly!
|
string is returned.
|
||||||
*/
|
*/
|
||||||
static int tilde_expand( wchar_t **ptr )
|
static wchar_t * expand_tilde_internal( wchar_t *in )
|
||||||
{
|
{
|
||||||
wchar_t *in = *ptr;
|
|
||||||
|
|
||||||
if( in[0] == HOME_DIRECTORY )
|
if( in[0] == HOME_DIRECTORY )
|
||||||
{
|
{
|
||||||
int tilde_error = 0;
|
int tilde_error = 0;
|
||||||
wchar_t *home=0;
|
wchar_t *home=0;
|
||||||
wchar_t *new_in;
|
wchar_t *new_in=0;
|
||||||
wchar_t *old_in;
|
wchar_t *old_in=0;
|
||||||
|
|
||||||
// fwprintf( stderr, L"Tilde expand ~%ls\n", (*ptr)+1 );
|
// fwprintf( stderr, L"Tilde expand ~%ls\n", (*ptr)+1 );
|
||||||
if( in[1] == '/' || in[1] == '\0' )
|
if( in[1] == '/' || in[1] == '\0' )
|
||||||
@@ -1267,26 +1352,23 @@ static int tilde_expand( wchar_t **ptr )
|
|||||||
free(name);
|
free(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !tilde_error )
|
if( !tilde_error && home && old_in )
|
||||||
{
|
{
|
||||||
new_in = wcsdupcat( home, old_in );
|
new_in = wcsdupcat( home, old_in );
|
||||||
free( in );
|
}
|
||||||
in = new_in;
|
free(home);
|
||||||
free(home);
|
free( in );
|
||||||
*ptr = in;
|
return new_in;
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return 1;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
wchar_t *expand_tilde(wchar_t *in)
|
wchar_t *expand_tilde( wchar_t *in)
|
||||||
{
|
{
|
||||||
if( in[0] == L'~' )
|
if( in[0] == L'~' )
|
||||||
{
|
{
|
||||||
in[0] = HOME_DIRECTORY;
|
in[0] = HOME_DIRECTORY;
|
||||||
tilde_expand( &in );
|
return expand_tilde_internal( in );
|
||||||
return in;
|
|
||||||
}
|
}
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
@@ -1300,8 +1382,6 @@ static void remove_internal_separator( const void *s, int conv )
|
|||||||
wchar_t *in = (wchar_t *)s;
|
wchar_t *in = (wchar_t *)s;
|
||||||
wchar_t *out=in;
|
wchar_t *out=in;
|
||||||
|
|
||||||
// int changed=0;
|
|
||||||
|
|
||||||
while( *in )
|
while( *in )
|
||||||
{
|
{
|
||||||
switch( *in )
|
switch( *in )
|
||||||
@@ -1325,16 +1405,11 @@ static void remove_internal_separator( const void *s, int conv )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
*out=0;
|
*out=0;
|
||||||
/* if( changed )
|
|
||||||
{
|
|
||||||
fwprintf( stderr, L" -> %ls\n", s );
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The real expansion function. All other expansion functions are wrappers to this one.
|
The real expansion function. expand_one is just a wrapper around this one.
|
||||||
*/
|
*/
|
||||||
int expand_string( wchar_t *str,
|
int expand_string( wchar_t *str,
|
||||||
array_list_t *end_out,
|
array_list_t *end_out,
|
||||||
@@ -1345,11 +1420,15 @@ int expand_string( wchar_t *str,
|
|||||||
|
|
||||||
int i;
|
int i;
|
||||||
int subshell_ok = 1;
|
int subshell_ok = 1;
|
||||||
|
int res = EXPAND_OK;
|
||||||
|
|
||||||
|
// debug( 1, L"Expand %ls", str );
|
||||||
|
|
||||||
|
|
||||||
if( (!(flags & ACCEPT_INCOMPLETE)) && is_clean( str ) )
|
if( (!(flags & ACCEPT_INCOMPLETE)) && is_clean( str ) )
|
||||||
{
|
{
|
||||||
al_push( end_out, str );
|
al_push( end_out, str );
|
||||||
return 1;
|
return EXPAND_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
al_init( &list1 );
|
al_init( &list1 );
|
||||||
@@ -1367,11 +1446,11 @@ int expand_string( wchar_t *str,
|
|||||||
|
|
||||||
if( (pos == str) || ( *(pos-1) != L'\\' ) )
|
if( (pos == str) || ( *(pos-1) != L'\\' ) )
|
||||||
{
|
{
|
||||||
error( SUBSHELL_ERROR, L"Subshells not allowed", -1 );
|
error( SUBSHELL_ERROR, -1, L"Subshells not allowed" );
|
||||||
free( str );
|
free( str );
|
||||||
al_destroy( &list1 );
|
al_destroy( &list1 );
|
||||||
al_destroy( &list2 );
|
al_destroy( &list2 );
|
||||||
return 0;
|
return EXPAND_ERROR;
|
||||||
}
|
}
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
@@ -1385,7 +1464,7 @@ int expand_string( wchar_t *str,
|
|||||||
if( !subshell_ok )
|
if( !subshell_ok )
|
||||||
{
|
{
|
||||||
al_destroy( &list1 );
|
al_destroy( &list1 );
|
||||||
return 0;
|
return EXPAND_ERROR;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1400,7 +1479,7 @@ int expand_string( wchar_t *str,
|
|||||||
1);
|
1);
|
||||||
|
|
||||||
free( (void *)al_get( in, i ) );
|
free( (void *)al_get( in, i ) );
|
||||||
|
|
||||||
if( !next )
|
if( !next )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -1419,7 +1498,7 @@ int expand_string( wchar_t *str,
|
|||||||
{
|
{
|
||||||
al_destroy( in );
|
al_destroy( in );
|
||||||
al_destroy( out );
|
al_destroy( out );
|
||||||
return 0;
|
return EXPAND_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1436,7 +1515,7 @@ int expand_string( wchar_t *str,
|
|||||||
{
|
{
|
||||||
al_destroy( in );
|
al_destroy( in );
|
||||||
al_destroy( out );
|
al_destroy( out );
|
||||||
return 0;
|
return EXPAND_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
al_truncate( in, 0 );
|
al_truncate( in, 0 );
|
||||||
@@ -1447,21 +1526,26 @@ int expand_string( wchar_t *str,
|
|||||||
for( i=0; i<al_get_count( in ); i++ )
|
for( i=0; i<al_get_count( in ); i++ )
|
||||||
{
|
{
|
||||||
wchar_t *next = (wchar_t *)al_get( in, i );
|
wchar_t *next = (wchar_t *)al_get( in, i );
|
||||||
if(!tilde_expand( &next ))
|
if( !(next=expand_tilde_internal( next ) ) )
|
||||||
{
|
{
|
||||||
al_destroy( in );
|
al_destroy( in );
|
||||||
al_destroy( out );
|
al_destroy( out );
|
||||||
return 0;
|
return EXPAND_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( flags & ACCEPT_INCOMPLETE )
|
if( flags & ACCEPT_INCOMPLETE )
|
||||||
{
|
{
|
||||||
if( *next == PROCESS_EXPAND )
|
if( *next == PROCESS_EXPAND )
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
If process expansion matches, we are not
|
||||||
|
interested in other completions, so we
|
||||||
|
short-circut and return
|
||||||
|
*/
|
||||||
expand_pid( next, flags, end_out );
|
expand_pid( next, flags, end_out );
|
||||||
al_destroy( in );
|
al_destroy( in );
|
||||||
al_destroy( out );
|
al_destroy( out );
|
||||||
return 1;
|
return EXPAND_OK;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
al_push( out, next );
|
al_push( out, next );
|
||||||
@@ -1472,7 +1556,7 @@ int expand_string( wchar_t *str,
|
|||||||
{
|
{
|
||||||
al_destroy( in );
|
al_destroy( in );
|
||||||
al_destroy( out );
|
al_destroy( out );
|
||||||
return 0;
|
return EXPAND_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1505,19 +1589,18 @@ int expand_string( wchar_t *str,
|
|||||||
case 0:
|
case 0:
|
||||||
if( !(flags & ACCEPT_INCOMPLETE) )
|
if( !(flags & ACCEPT_INCOMPLETE) )
|
||||||
{
|
{
|
||||||
|
if( res == EXPAND_OK )
|
||||||
|
res = EXPAND_WILDCARD_NO_MATCH;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
|
res = EXPAND_WILDCARD_MATCH;
|
||||||
sort_list( out );
|
sort_list( out );
|
||||||
al_push_all( end_out, out );
|
al_push_all( end_out, out );
|
||||||
al_truncate( out, 0 );
|
al_truncate( out, 0 );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
|
||||||
fwprintf( stderr, L"error\n" );
|
|
||||||
/*al_destroy( &list1 );*/
|
|
||||||
/*al_destroy( &list2 );*/
|
|
||||||
/*return 0;*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1532,7 +1615,8 @@ int expand_string( wchar_t *str,
|
|||||||
al_destroy( out );
|
al_destroy( out );
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return res;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
61
expand.h
61
expand.h
@@ -1,12 +1,12 @@
|
|||||||
/**\file expand.h
|
/**\file expand.h
|
||||||
|
|
||||||
Prototypes for string expantion functions. These functions perform
|
Prototypes for string expansion functions. These functions perform
|
||||||
several kinds of parameter expantion. There are a lot of issues
|
several kinds of parameter expansion. There are a lot of issues
|
||||||
with regards to memory allocation. Overall, these functions would
|
with regards to memory allocation. Overall, these functions would
|
||||||
benefit from using a more clever memory allocation scheme, perhaps
|
benefit from using a more clever memory allocation scheme, perhaps
|
||||||
an evil combination of talloc, string buffers and reference
|
an evil combination of talloc, string buffers and reference
|
||||||
counting.
|
counting.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FISH_EXPAND_H
|
#ifndef FISH_EXPAND_H
|
||||||
@@ -20,17 +20,17 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Flag specifying that subshell expantion should be skipped
|
Flag specifying that subshell expansion should be skipped
|
||||||
*/
|
*/
|
||||||
#define EXPAND_SKIP_SUBSHELL 1
|
#define EXPAND_SKIP_SUBSHELL 1
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Flag specifying that variable expantion should be skipped
|
Flag specifying that variable expansion should be skipped
|
||||||
*/
|
*/
|
||||||
#define EXPAND_SKIP_VARIABLES 2
|
#define EXPAND_SKIP_VARIABLES 2
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Flag specifying that wildcard expantion should be skipped
|
Flag specifying that wildcard expansion should be skipped
|
||||||
*/
|
*/
|
||||||
#define EXPAND_SKIP_WILDCARDS 4
|
#define EXPAND_SKIP_WILDCARDS 4
|
||||||
|
|
||||||
@@ -64,20 +64,45 @@ enum
|
|||||||
/** Character represeting a home directory */
|
/** Character represeting a home directory */
|
||||||
HOME_DIRECTORY = EXPAND_RESERVED,
|
HOME_DIRECTORY = EXPAND_RESERVED,
|
||||||
|
|
||||||
/** Character represeting process expantion */
|
/** Character represeting process expansion */
|
||||||
PROCESS_EXPAND,
|
PROCESS_EXPAND,
|
||||||
|
|
||||||
/** Character representing variable expantion */
|
/** Character representing variable expansion */
|
||||||
VARIABLE_EXPAND,
|
VARIABLE_EXPAND,
|
||||||
|
|
||||||
/** Character representing the start of a bracket expantion */
|
/** Character rpresenting variable expansion into a single element*/
|
||||||
|
VARIABLE_EXPAND_SINGLE,
|
||||||
|
|
||||||
|
/** Character representing the start of a bracket expansion */
|
||||||
BRACKET_BEGIN,
|
BRACKET_BEGIN,
|
||||||
|
|
||||||
/** Character representing the end of a bracket expantion */
|
/** Character representing the end of a bracket expansion */
|
||||||
BRACKET_END,
|
BRACKET_END,
|
||||||
|
|
||||||
/** Character representing separation between two bracket elements */
|
/** Character representing separation between two bracket elements */
|
||||||
BRACKET_SEP,
|
BRACKET_SEP,
|
||||||
|
/**
|
||||||
|
Separate subtokens in a token with this character.
|
||||||
|
*/
|
||||||
|
INTERNAL_SEPARATOR,
|
||||||
|
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
These are the possible return values for expand_string
|
||||||
|
*/
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
/** Error */
|
||||||
|
EXPAND_ERROR,
|
||||||
|
/** Ok */
|
||||||
|
EXPAND_OK,
|
||||||
|
/** Ok, a wildcard in the string matched no files */
|
||||||
|
EXPAND_WILDCARD_NO_MATCH,
|
||||||
|
/* Ok, a wildcard in the string matched a file */
|
||||||
|
EXPAND_WILDCARD_MATCH
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -87,18 +112,13 @@ enum
|
|||||||
/** String containing the character for separating two array elements */
|
/** String containing the character for separating two array elements */
|
||||||
#define ARRAY_SEP_STR L"\x1e"
|
#define ARRAY_SEP_STR L"\x1e"
|
||||||
|
|
||||||
/**
|
|
||||||
Separate subtokens in a token with this character.
|
|
||||||
*/
|
|
||||||
#define INTERNAL_SEPARATOR 0xfffffff0
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Perform various forms of expansion on in, such as tilde expansion
|
Perform various forms of expansion on in, such as tilde expansion
|
||||||
(~USER becomes the users home directory), variable expansion
|
(~USER becomes the users home directory), variable expansion
|
||||||
($VAR_NAME becomes the value of the environment variable VAR_NAME),
|
($VAR_NAME becomes the value of the environment variable VAR_NAME),
|
||||||
subshell expantion and wildcard expansion. The results are inserted
|
subshell expansion and wildcard expansion. The results are inserted
|
||||||
into the list out.
|
into the list out.
|
||||||
|
|
||||||
If the parameter does not need expansion, it is copied into the list
|
If the parameter does not need expansion, it is copied into the list
|
||||||
@@ -106,8 +126,9 @@ enum
|
|||||||
newly allocated strings are inserted into the list out.
|
newly allocated strings are inserted into the list out.
|
||||||
|
|
||||||
\param in The parameter to expand
|
\param in The parameter to expand
|
||||||
\param flag Specifies if any expantion pass should be skipped. Legal values are any combination of EXPAND_SKIP_SUBSHELL EXPAND_SKIP_VARIABLES and EXPAND_SKIP_WILDCARDS
|
\param flag Specifies if any expansion pass should be skipped. Legal values are any combination of EXPAND_SKIP_SUBSHELL EXPAND_SKIP_VARIABLES and EXPAND_SKIP_WILDCARDS
|
||||||
\param out The list to which the result will be appended.
|
\param out The list to which the result will be appended.
|
||||||
|
\return One of EXPAND_OK, EXPAND_ERROR, EXPAND_WILDCARD_MATCH and EXPAND_WILDCARD_NO_MATCH
|
||||||
*/
|
*/
|
||||||
int expand_string( wchar_t *in, array_list_t *out, int flag );
|
int expand_string( wchar_t *in, array_list_t *out, int flag );
|
||||||
|
|
||||||
@@ -117,7 +138,7 @@ int expand_string( wchar_t *in, array_list_t *out, int flag );
|
|||||||
names.
|
names.
|
||||||
|
|
||||||
\param in The parameter to expand
|
\param in The parameter to expand
|
||||||
\param flag Specifies if any expantion pass should be skipped. Legal values are any combination of EXPAND_SKIP_SUBSHELL EXPAND_SKIP_VARIABLES and EXPAND_SKIP_WILDCARDS
|
\param flag Specifies if any expansion pass should be skipped. Legal values are any combination of EXPAND_SKIP_SUBSHELL EXPAND_SKIP_VARIABLES and EXPAND_SKIP_WILDCARDS
|
||||||
\return The expanded parameter, or 0 on failiure
|
\return The expanded parameter, or 0 on failiure
|
||||||
*/
|
*/
|
||||||
wchar_t *expand_one( wchar_t *in, int flag );
|
wchar_t *expand_one( wchar_t *in, int flag );
|
||||||
@@ -154,9 +175,9 @@ wchar_t *expand_escape_variable( const wchar_t *in );
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Perform tilde expantion and nothing else on the specified string.
|
Perform tilde expansion and nothing else on the specified string.
|
||||||
|
|
||||||
If tilde expantion is needed, the original string is freed and a
|
If tilde expansion is needed, the original string is freed and a
|
||||||
new string, allocated using malloc, is returned.
|
new string, allocated using malloc, is returned.
|
||||||
*/
|
*/
|
||||||
wchar_t *expand_tilde(wchar_t *in);
|
wchar_t *expand_tilde(wchar_t *in);
|
||||||
|
|||||||
@@ -69,6 +69,9 @@ fi
|
|||||||
%config %_sysconfdir/fish.d/completions/*.fish
|
%config %_sysconfdir/fish.d/completions/*.fish
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Nov 29 2005 Axel Liljencrantz <axel@liljencrantz.se> 1.17.0-0
|
||||||
|
- 1.17.0
|
||||||
|
|
||||||
* Sat Sep 24 2005 Axel Liljencrantz <axel@liljencrantz.se> 1.14.0-0
|
* Sat Sep 24 2005 Axel Liljencrantz <axel@liljencrantz.se> 1.14.0-0
|
||||||
- 1.14.0
|
- 1.14.0
|
||||||
|
|
||||||
|
|||||||
10
fish_tests.c
10
fish_tests.c
@@ -518,7 +518,7 @@ static void test_parser()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Perform parameter expantion and test if the output equals the zero-terminated parameter list supplied.
|
Perform parameter expansion and test if the output equals the zero-terminated parameter list supplied.
|
||||||
|
|
||||||
\param in the string to expand
|
\param in the string to expand
|
||||||
\param flags the flags to send to expand_string
|
\param flags the flags to send to expand_string
|
||||||
@@ -561,11 +561,11 @@ static int expand_test( const wchar_t *in, int flags, ... )
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Test globbing and other parameter expantion
|
Test globbing and other parameter expansion
|
||||||
*/
|
*/
|
||||||
static void test_expand()
|
static void test_expand()
|
||||||
{
|
{
|
||||||
say( L"Testing parameter expantion" );
|
say( L"Testing parameter expansion" );
|
||||||
|
|
||||||
if( !expand_test( L"foo", 0, L"foo", 0 ))
|
if( !expand_test( L"foo", 0, L"foo", 0 ))
|
||||||
{
|
{
|
||||||
@@ -574,12 +574,12 @@ static void test_expand()
|
|||||||
|
|
||||||
if( !expand_test( L"a{b,c,d}e", 0, L"abe", L"ace", L"ade", 0 ) )
|
if( !expand_test( L"a{b,c,d}e", 0, L"abe", L"ace", L"ade", 0 ) )
|
||||||
{
|
{
|
||||||
err( L"Bracket expantion is broken" );
|
err( L"Bracket expansion is broken" );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !expand_test( L"a*", EXPAND_SKIP_WILDCARDS, L"a*", 0 ) )
|
if( !expand_test( L"a*", EXPAND_SKIP_WILDCARDS, L"a*", 0 ) )
|
||||||
{
|
{
|
||||||
err( L"Cannot skip wildcard expantion" );
|
err( L"Cannot skip wildcard expansion" );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
60
fishd.c
60
fishd.c
@@ -70,6 +70,11 @@ static connection_t *conn;
|
|||||||
*/
|
*/
|
||||||
static int sock;
|
static int sock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set to one when fishd should save and exit
|
||||||
|
*/
|
||||||
|
static int quit=0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Constructs the fish socket filename
|
Constructs the fish socket filename
|
||||||
*/
|
*/
|
||||||
@@ -110,6 +115,15 @@ static char *get_socket_filename()
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Signal handler for the term signal.
|
||||||
|
*/
|
||||||
|
static void handle_term( int signal )
|
||||||
|
{
|
||||||
|
quit=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Acquire the lock for the socket
|
Acquire the lock for the socket
|
||||||
Returns the name of the lock file if successful or
|
Returns the name of the lock file if successful or
|
||||||
@@ -268,26 +282,37 @@ static void daemonize()
|
|||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
Make fishd ignore the HUP signal.
|
||||||
|
*/
|
||||||
struct sigaction act;
|
struct sigaction act;
|
||||||
sigemptyset( & act.sa_mask );
|
sigemptyset( & act.sa_mask );
|
||||||
act.sa_flags=0;
|
act.sa_flags=0;
|
||||||
act.sa_handler=SIG_IGN;
|
act.sa_handler=SIG_IGN;
|
||||||
sigaction( SIGHUP, &act, 0);
|
sigaction( SIGHUP, &act, 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Make fishd save and exit on the TERM signal.
|
||||||
|
*/
|
||||||
|
sigfillset( & act.sa_mask );
|
||||||
|
act.sa_flags=0;
|
||||||
|
act.sa_handler=&handle_term;
|
||||||
|
sigaction( SIGTERM, &act, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
debug( 0, L"Parent calling exit" );
|
debug( 0, L"Parent process exiting (This is normal)" );
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Put ourself in out own processing group
|
Put ourself in out own processing group
|
||||||
*/
|
*/
|
||||||
setsid();
|
setsid();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Close stdin and stdout. We only use stderr, anyway.
|
Close stdin and stdout. We only use stderr, anyway.
|
||||||
*/
|
*/
|
||||||
@@ -386,8 +411,9 @@ static void init()
|
|||||||
*/
|
*/
|
||||||
int main( int argc, char ** argv )
|
int main( int argc, char ** argv )
|
||||||
{
|
{
|
||||||
int child_socket, t;
|
int child_socket;
|
||||||
struct sockaddr_un remote;
|
struct sockaddr_un remote;
|
||||||
|
socklen_t t;
|
||||||
int max_fd;
|
int max_fd;
|
||||||
int update_count=0;
|
int update_count=0;
|
||||||
|
|
||||||
@@ -416,15 +442,27 @@ int main( int argc, char ** argv )
|
|||||||
FD_SET( c->fd, &write_fd );
|
FD_SET( c->fd, &write_fd );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res=select( max_fd, &read_fd, &write_fd, 0, 0 );
|
while( 1 )
|
||||||
|
|
||||||
if( res==-1 )
|
|
||||||
{
|
{
|
||||||
wperror( L"select" );
|
res=select( max_fd, &read_fd, &write_fd, 0, 0 );
|
||||||
exit(1);
|
|
||||||
|
if( quit )
|
||||||
|
{
|
||||||
|
save();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( res != -1 )
|
||||||
|
break;
|
||||||
|
|
||||||
|
if( errno != EINTR )
|
||||||
|
{
|
||||||
|
wperror( L"select" );
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( FD_ISSET( sock, &read_fd ) )
|
if( FD_ISSET( sock, &read_fd ) )
|
||||||
{
|
{
|
||||||
if( (child_socket =
|
if( (child_socket =
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ void function_set_desc( const wchar_t *name, const wchar_t *desc );
|
|||||||
/**
|
/**
|
||||||
Returns true if the function witrh the name name exists.
|
Returns true if the function witrh the name name exists.
|
||||||
*/
|
*/
|
||||||
int function_exists( const wchar_t *name);
|
int function_exists( const wchar_t *name );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Insert all function names into l. These are not copies of the strings and should not be freed after use.
|
Insert all function names into l. These are not copies of the strings and should not be freed after use.
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
|
|
||||||
function __fish_complete_apropos
|
function __fish_complete_apropos
|
||||||
if test (commandline -ct)
|
if test (commandline -ct)
|
||||||
set str (commandline -ct)
|
set str (commandline -ct)
|
||||||
apropos $str|sed -e 's/^\(.*'$str'\([^ ]*\).*\)$/'$str'\2\t\1/'
|
apropos $str|sed -e "s/^\(.*$str\([^ ]*\).*\)$/$str\2\t\1/"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
complete -xc apropos -a "(__fish_complete_apropos)" -d "Whatis entry"
|
complete -xc apropos -a '(__fish_complete_apropos)' -d "Whatis entry"
|
||||||
|
|
||||||
complete -c apropos -s h -l help -d "apropos command help"
|
complete -c apropos -s h -l help -d "apropos command help"
|
||||||
complete -f -c apropos -s d -l debug -d "print debugging info"
|
complete -f -c apropos -s d -l debug -d "print debugging info"
|
||||||
@@ -14,7 +15,7 @@ complete -f -c apropos -s r -l regex -d "keyword as regex"
|
|||||||
complete -f -c apropos -s w -l wildcard -d "keyword as wildwards"
|
complete -f -c apropos -s w -l wildcard -d "keyword as wildwards"
|
||||||
complete -f -c apropos -s e -l exact -d "keyword as exactly match"
|
complete -f -c apropos -s e -l exact -d "keyword as exactly match"
|
||||||
complete -x -c apropos -s m -l system -d "search for other system"
|
complete -x -c apropos -s m -l system -d "search for other system"
|
||||||
complete -x -c apropos -s M -l manpath -a "(echo $MANPATH)" -d "specify man path"
|
complete -x -c apropos -s M -l manpath -a '(echo $MANPATH)' -d "specify man path"
|
||||||
complete -x -c apropos -s C -l config-file -d "specify a conf file"
|
complete -x -c apropos -s C -l config-file -d "specify a conf file"
|
||||||
complete -f -c apropos -s V -l version -d "Display version"
|
complete -f -c apropos -s V -l version -d "Display version"
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#completion for apt-get
|
#completion for apt-get
|
||||||
|
|
||||||
function __fish_apt_no_subcommand -d "test if apt has yet to be given the subcommand"
|
function __fish_apt_no_subcommand -d 'test if apt has yet to be given the subcommand'
|
||||||
for i in (commandline -opc)
|
for i in (commandline -opc)
|
||||||
if contains -- $i update upgrade dselect-upgrade dist-upgrade install remove source build-dep check clean autoclean
|
if contains -- $i update upgrade dselect-upgrade dist-upgrade install remove source build-dep check clean autoclean
|
||||||
return 1
|
return 1
|
||||||
@@ -9,7 +9,7 @@ function __fish_apt_no_subcommand -d "test if apt has yet to be given the subcom
|
|||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
function __fish_apt_use_package -d "Test if apt command should have packages as potential completion"
|
function __fish_apt_use_package -d 'Test if apt command should have packages as potential completion'
|
||||||
for i in (commandline -opc)
|
for i in (commandline -opc)
|
||||||
if contains -- $i contains install remove build-dep
|
if contains -- $i contains install remove build-dep
|
||||||
return 0
|
return 0
|
||||||
@@ -18,47 +18,47 @@ function __fish_apt_use_package -d "Test if apt command should have packages as
|
|||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
|
|
||||||
complete -c apt-get -n "__fish_apt_use_package" -a "(__fish_print_packages)" -d "Package"
|
complete -c apt-get -n '__fish_apt_use_package' -a '(__fish_print_packages)' -d 'Package'
|
||||||
|
|
||||||
complete -c apt-get -s h -l help -d "apt-get command help"
|
complete -c apt-get -s h -l help -d 'apt-get command help'
|
||||||
complete -f -n "__fish_apt_no_subcommand" -c apt-get -a "update" -d "update sources"
|
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'update' -d 'update sources'
|
||||||
complete -f -n "__fish_apt_no_subcommand" -c apt-get -a "upgrade" -d "upgrade or install newest packages"
|
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'upgrade' -d 'upgrade or install newest packages'
|
||||||
complete -f -n "__fish_apt_no_subcommand" -c apt-get -a "dselect-upgrade" -d "use with dselect front-end"
|
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'dselect-upgrade' -d 'use with dselect front-end'
|
||||||
complete -f -n "__fish_apt_no_subcommand" -c apt-get -a "dist-upgrade" -d "distro upgrade"
|
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'dist-upgrade' -d 'distro upgrade'
|
||||||
complete -f -n "__fish_apt_no_subcommand" -c apt-get -a "install" -d "install one or more packages"
|
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'install' -d 'install one or more packages'
|
||||||
complete -f -n "__fish_apt_no_subcommand" -c apt-get -a "remove" -d "remove one or more packages"
|
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'remove' -d 'remove one or more packages'
|
||||||
complete -f -n "__fish_apt_no_subcommand" -c apt-get -a "source" -d "fetch source packages"
|
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'source' -d 'fetch source packages'
|
||||||
complete -f -n "__fish_apt_no_subcommand" -c apt-get -a "build-dep" -d "install/remove packages for dependencies"
|
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'build-dep' -d 'install/remove packages for dependencies'
|
||||||
complete -f -n "__fish_apt_no_subcommand" -c apt-get -a "check" -d "update cache and check dep"
|
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'check' -d 'update cache and check dep'
|
||||||
complete -f -n "__fish_apt_no_subcommand" -c apt-get -a "clean" -d "clean local caches and packages"
|
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'clean' -d 'clean local caches and packages'
|
||||||
complete -f -n "__fish_apt_no_subcommand" -c apt-get -a "autoclean" -d "clean packages no longer be downloaded"
|
complete -f -n '__fish_apt_no_subcommand' -c apt-get -a 'autoclean' -d 'clean packages no longer be downloaded'
|
||||||
complete -c apt-get -s d -l download-only -d "Download Only"
|
complete -c apt-get -s d -l download-only -d 'Download Only'
|
||||||
complete -c apt-get -s f -l fix-broken -d "correct broken deps"
|
complete -c apt-get -s f -l fix-broken -d 'correct broken deps'
|
||||||
complete -c apt-get -s m -l fix-missing -d "ignore missing packages"
|
complete -c apt-get -s m -l fix-missing -d 'ignore missing packages'
|
||||||
complete -c apt-get -l no-download -d "Disable downloading packages"
|
complete -c apt-get -l no-download -d 'Disable downloading packages'
|
||||||
complete -c apt-get -s q -l quiet -d "quiet output"
|
complete -c apt-get -s q -l quiet -d 'quiet output'
|
||||||
complete -c apt-get -s s -l simulate -d "perform a siulation"
|
complete -c apt-get -s s -l simulate -d 'perform a siulation'
|
||||||
complete -c apt-get -s y -l assume-yes -d "automatic yes to prompts"
|
complete -c apt-get -s y -l assume-yes -d 'automatic yes to prompts'
|
||||||
complete -c apt-get -s u -l show-upgraded -d "show upgraded packages"
|
complete -c apt-get -s u -l show-upgraded -d 'show upgraded packages'
|
||||||
complete -c apt-get -s V -l verbose-versions -d "show full versions for packages"
|
complete -c apt-get -s V -l verbose-versions -d 'show full versions for packages'
|
||||||
complete -c apt-get -s b -l compile -d "compile source packages"
|
complete -c apt-get -s b -l compile -d 'compile source packages'
|
||||||
complete -c apt-get -s b -l build -d "compile source packages"
|
complete -c apt-get -s b -l build -d 'compile source packages'
|
||||||
complete -c apt-get -l ignore-hold -d "ignore package Holds"
|
complete -c apt-get -l ignore-hold -d 'ignore package Holds'
|
||||||
complete -c apt-get -l no-upgrade -d "Do not upgrade packages"
|
complete -c apt-get -l no-upgrade -d 'Do not upgrade packages'
|
||||||
complete -c apt-get -l force-yes -d "Force yes"
|
complete -c apt-get -l force-yes -d 'Force yes'
|
||||||
complete -c apt-get -l print-uris -d "print the URIs"
|
complete -c apt-get -l print-uris -d 'print the URIs'
|
||||||
complete -c apt-get -l purge -d "use purge instead of remove"
|
complete -c apt-get -l purge -d 'use purge instead of remove'
|
||||||
complete -c apt-get -l reinstall -d "reinstall packages"
|
complete -c apt-get -l reinstall -d 'reinstall packages'
|
||||||
complete -c apt-get -l list-cleanup -d "erase obsolete files"
|
complete -c apt-get -l list-cleanup -d 'erase obsolete files'
|
||||||
complete -c apt-get -s t -l target-release -d "control default input to the policy engine"
|
complete -c apt-get -s t -l target-release -d 'control default input to the policy engine'
|
||||||
complete -c apt-get -l trivial-only -d "only perform operations that are trivial"
|
complete -c apt-get -l trivial-only -d 'only perform operations that are trivial'
|
||||||
complete -c apt-get -l no-remove -d "abort if any packages are to be removed"
|
complete -c apt-get -l no-remove -d 'abort if any packages are to be removed'
|
||||||
complete -c apt-get -l only-source -d "only accept source packages"
|
complete -c apt-get -l only-source -d 'only accept source packages'
|
||||||
complete -c apt-get -l diff-only -d "download only diff file"
|
complete -c apt-get -l diff-only -d 'download only diff file'
|
||||||
complete -c apt-get -l tar-only -d "download only tar file"
|
complete -c apt-get -l tar-only -d 'download only tar file'
|
||||||
complete -c apt-get -l arch-only -d "only process arch-dep build-deps"
|
complete -c apt-get -l arch-only -d 'only process arch-dep build-deps'
|
||||||
complete -c apt-get -l allow-unauthenticated -d "ignore non-authenticated packages"
|
complete -c apt-get -l allow-unauthenticated -d 'ignore non-authenticated packages'
|
||||||
complete -c apt-get -s v -l version -d "show program version"
|
complete -c apt-get -s v -l version -d 'show program version'
|
||||||
complete -r -c apt-get -s c -l config-file -d "specify a config file"
|
complete -r -c apt-get -s c -l config-file -d 'specify a config file'
|
||||||
complete -r -c apt-get -s o -l option -d "set a config option"
|
complete -r -c apt-get -s o -l option -d 'set a config option'
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
#apt-proxy-import
|
#apt-proxy-import
|
||||||
complete -c apt-proxy-import -s h -l help -d "apt-proxy-import command help"
|
complete -c apt-proxy-import -s h -l help -d 'apt-proxy-import command help'
|
||||||
complete -f -c apt-proxy-import -s V -l version -d "print version"
|
complete -f -c apt-proxy-import -s V -l version -d 'print version'
|
||||||
complete -f -c apt-proxy-import -s v -l verbose -d "verbose info"
|
complete -f -c apt-proxy-import -s v -l verbose -d 'verbose info'
|
||||||
complete -f -c apt-proxy-import -s q -l quiet -d "no message to STDOUT"
|
complete -f -c apt-proxy-import -s q -l quiet -d 'no message to STDOUT'
|
||||||
complete -f -c apt-proxy-import -s r -l recursive -d "recurse into subdir"
|
complete -f -c apt-proxy-import -s r -l recursive -d 'recurse into subdir'
|
||||||
complete -r -c apt-proxy-import -s i -l import-dir -a "(ls -Fp|grep /$)" -d "dir to import"
|
complete -r -c apt-proxy-import -s i -l import-dir -a '(ls -Fp|grep /$)' -d 'dir to import'
|
||||||
complete -r -c apt-proxy-import -s u -l user -a "(__fish_complete_users)" -d "change to user"
|
complete -r -c apt-proxy-import -s u -l user -a '(__fish_complete_users)' -d 'change to user'
|
||||||
complete -r -c apt-proxy-import -s d -l debug -d "debug level[default 0]"
|
complete -r -c apt-proxy-import -s d -l debug -d 'debug level[default 0]'
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
#apt-show-source
|
#apt-show-source
|
||||||
complete -c apt-show-source -s h -l help -d "apt-show-source command help"
|
complete -c apt-show-source -s h -l help -d 'apt-show-source command help'
|
||||||
complete -r -c apt-show-source -l status-file -d "read pkg from FILE" -f
|
complete -r -c apt-show-source -l status-file -d 'read pkg from FILE' -f
|
||||||
complete -r -c apt-show-source -o stf -d "read pkg from FILE" -f
|
complete -r -c apt-show-source -o stf -d 'read pkg from FILE' -f
|
||||||
complete -r -c apt-show-source -l list-dir -a "(ls -Fp .|grep /$) /var/lib/apt/lists" -d "specify APT list dir"
|
complete -r -c apt-show-source -l list-dir -a '(ls -Fp .|grep /$) /var/lib/apt/lists' -d 'specify APT list dir'
|
||||||
complete -r -c apt-show-source -o ld -a "(ls -Fp .|grep /$) /var/lib/apt/lists" -d "specify APT list dir"
|
complete -r -c apt-show-source -o ld -a '(ls -Fp .|grep /$) /var/lib/apt/lists' -d 'specify APT list dir'
|
||||||
complete -r -c apt-show-source -s p -l package -a "(apt-cache pkgnames)" -d "list PKG info"
|
complete -r -c apt-show-source -s p -l package -a '(apt-cache pkgnames)' -d 'list PKG info'
|
||||||
complete -f -c apt-show-source -l version-only -d "print version only"
|
complete -f -c apt-show-source -l version-only -d 'print version only'
|
||||||
complete -f -c apt-show-source -s a -l all -d "print all src pkgs with version"
|
complete -f -c apt-show-source -s a -l all -d 'print all src pkgs with version'
|
||||||
complete -f -c apt-show-source -s v -l verbose -d "verbose message"
|
complete -f -c apt-show-source -s v -l verbose -d 'verbose message'
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
#apt-show-versions
|
#apt-show-versions
|
||||||
complete -c apt-show-source -s h -l help -d "apt-show-versions command help"
|
complete -c apt-show-source -s h -l help -d 'apt-show-versions command help'
|
||||||
complete -r -c apt-show-versions -s p -l packages -a "(apt-cache pkgnames)" -d "print PKG versions"
|
complete -r -c apt-show-versions -s p -l packages -a '(apt-cache pkgnames)' -d 'print PKG versions'
|
||||||
complete -f -c apt-show-versions -s r -l regex -d "using regex"
|
complete -f -c apt-show-versions -s r -l regex -d 'using regex'
|
||||||
complete -f -c apt-show-versions -s u -l upgradeable -d "print only upgradeable pkgs"
|
complete -f -c apt-show-versions -s u -l upgradeable -d 'print only upgradeable pkgs'
|
||||||
complete -f -c apt-show-versions -s a -l allversions -d "print all versions"
|
complete -f -c apt-show-versions -s a -l allversions -d 'print all versions'
|
||||||
complete -f -c apt-show-versions -s b -l brief -d "print pkg name/distro"
|
complete -f -c apt-show-versions -s b -l brief -d 'print pkg name/distro'
|
||||||
complete -f -c apt-show-versions -s v -l verbose -d "print verbose info"
|
complete -f -c apt-show-versions -s v -l verbose -d 'print verbose info'
|
||||||
complete -f -c apt-show-versions -s i -l initialize -d "init or update cache only"
|
complete -f -c apt-show-versions -s i -l initialize -d 'init or update cache only'
|
||||||
complete -r -c apt-show-versions -l status-file -d "read pkg from FILE"
|
complete -r -c apt-show-versions -l status-file -d 'read pkg from FILE'
|
||||||
complete -r -c apt-show-versions -o stf -d "read pkg from FILE"
|
complete -r -c apt-show-versions -o stf -d 'read pkg from FILE'
|
||||||
complete -r -c apt-show-versions -l list-dir -a "(ls -Fp .|grep /$) /var/lib/apt/lists /var/state/apt/lists" -d "specify APT list dir"
|
complete -r -c apt-show-versions -l list-dir -a '(ls -Fp .|grep /$) /var/lib/apt/lists /var/state/apt/lists' -d 'specify APT list dir'
|
||||||
complete -r -c apt-show-versions -o ld -a "(ls -Fp .|grep /$) /var/lib/apt/lists /var/state/apt/lists" -d "specify APT list dir"
|
complete -r -c apt-show-versions -o ld -a '(ls -Fp .|grep /$) /var/lib/apt/lists /var/state/apt/lists' -d 'specify APT list dir'
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
complete -c cat -s A -l show-all -d "Escape all non-printing characters"
|
complete -c cat -s A -l show-all -d 'Escape all non-printing characters'
|
||||||
complete -c cat -s b -l number-nonblank -d "Number nonblank lines"
|
complete -c cat -s b -l number-nonblank -d 'Number nonblank lines'
|
||||||
complete -c cat -s e -d "Escape non-printing characters except tab"
|
complete -c cat -s e -d 'Escape non-printing characters except tab'
|
||||||
complete -c cat -s E -l show-ends -d "Display $ at end of line"
|
complete -c cat -s E -l show-ends -d 'Display $ at end of line'
|
||||||
complete -c cat -s n -l number -d "Number all lines"
|
complete -c cat -s n -l number -d 'Number all lines'
|
||||||
complete -c cat -s s -l squeeze-blank -d "Never more than single blank line"
|
complete -c cat -s s -l squeeze-blank -d 'Never more than single blank line'
|
||||||
complete -c cat -s t -d "Escape non-printing characters except newline"
|
complete -c cat -s t -d 'Escape non-printing characters except newline'
|
||||||
complete -c cat -s T -l show-tabs -d "Escape tab"
|
complete -c cat -s T -l show-tabs -d 'Escape tab'
|
||||||
complete -c cat -s v -d "Escape non-printing except newline and tab"
|
complete -c cat -s v -d 'Escape non-printing except newline and tab'
|
||||||
complete -c cat -l help -d "Display help and exit"
|
complete -c cat -l help -d 'Display help and exit'
|
||||||
complete -c cat -l version -d "Display version and exit"
|
complete -c cat -l version -d 'Display version and exit'
|
||||||
|
|
||||||
|
|||||||
@@ -2,52 +2,52 @@
|
|||||||
# I don't use CVS, so these completions are probably not all that good.
|
# I don't use CVS, so these completions are probably not all that good.
|
||||||
#
|
#
|
||||||
|
|
||||||
complete -c cvs -x -a "add" -d "Add a new file/directory to the repository"
|
complete -c cvs -x -a 'add' -d 'Add a new file/directory to the repository'
|
||||||
complete -c cvs -x -a "admin" -d "Administration front end for rcs"
|
complete -c cvs -x -a 'admin' -d 'Administration front end for rcs'
|
||||||
complete -c cvs -x -a "annotate" -d "Show last revision where each line was modified"
|
complete -c cvs -x -a 'annotate' -d 'Show last revision where each line was modified'
|
||||||
complete -c cvs -x -a "checkout" -d "Checkout sources for editing"
|
complete -c cvs -x -a 'checkout' -d 'Checkout sources for editing'
|
||||||
complete -c cvs -x -a "commit" -d "Check files into the repository"
|
complete -c cvs -x -a 'commit' -d 'Check files into the repository'
|
||||||
complete -c cvs -x -a "diff" -d "Show differences between revisions"
|
complete -c cvs -x -a 'diff' -d 'Show differences between revisions'
|
||||||
complete -c cvs -x -a "edit" -d "Get ready to edit a watched file"
|
complete -c cvs -x -a 'edit' -d 'Get ready to edit a watched file'
|
||||||
complete -c cvs -x -a "editors" -d "See who is editing a watched file"
|
complete -c cvs -x -a 'editors' -d 'See who is editing a watched file'
|
||||||
complete -c cvs -x -a "export" -d "Export sources from CVS, similar to checkout"
|
complete -c cvs -x -a 'export' -d 'Export sources from CVS, similar to checkout'
|
||||||
complete -c cvs -x -a "history" -d "Show repository access history"
|
complete -c cvs -x -a 'history' -d 'Show repository access history'
|
||||||
complete -c cvs -x -a "import" -d "Import sources into CVS, using vendor branches"
|
complete -c cvs -x -a 'import' -d 'Import sources into CVS, using vendor branches'
|
||||||
complete -c cvs -x -a "init" -d "Create a CVS repository if it doesnt exist"
|
complete -c cvs -x -a 'init' -d 'Create a CVS repository if it doesnt exist'
|
||||||
complete -c cvs -x -a "kserver" -d "Kerberos server mode"
|
complete -c cvs -x -a 'kserver' -d 'Kerberos server mode'
|
||||||
complete -c cvs -x -a "log" -d "Print out history information for files"
|
complete -c cvs -x -a 'log' -d 'Print out history information for files'
|
||||||
complete -c cvs -x -a "login" -d "Prompt for password for authenticating server"
|
complete -c cvs -x -a 'login' -d 'Prompt for password for authenticating server'
|
||||||
complete -c cvs -x -a "logout" -d "Removes entry in .cvspass for remote repository"
|
complete -c cvs -x -a 'logout' -d 'Removes entry in .cvspass for remote repository'
|
||||||
complete -c cvs -x -a "pserver" -d "Password server mode"
|
complete -c cvs -x -a 'pserver' -d 'Password server mode'
|
||||||
complete -c cvs -x -a "rannotate" -d "Show last revision where each line of module was modified"
|
complete -c cvs -x -a 'rannotate' -d 'Show last revision where each line of module was modified'
|
||||||
complete -c cvs -x -a "rdiff" -d "Create 'patch' format diffs between releases"
|
complete -c cvs -x -a 'rdiff' -d 'Create "patch" format diffs between releases'
|
||||||
complete -c cvs -x -a "release" -d "Indicate that a Module is no longer in use"
|
complete -c cvs -x -a 'release' -d 'Indicate that a Module is no longer in use'
|
||||||
complete -c cvs -x -a "remove" -d "Remove an entry from the repository"
|
complete -c cvs -x -a 'remove' -d 'Remove an entry from the repository'
|
||||||
complete -c cvs -x -a "rlog" -d "Print out history information for a module"
|
complete -c cvs -x -a 'rlog' -d 'Print out history information for a module'
|
||||||
complete -c cvs -x -a "rtag" -d "Add a symbolic tag to a module"
|
complete -c cvs -x -a 'rtag' -d 'Add a symbolic tag to a module'
|
||||||
complete -c cvs -x -a "server" -d "Server mode"
|
complete -c cvs -x -a 'server' -d 'Server mode'
|
||||||
complete -c cvs -x -a "status" -d "Display status information on checked out files"
|
complete -c cvs -x -a 'status' -d 'Display status information on checked out files'
|
||||||
complete -c cvs -x -a "tag" -d "Add a symbolic tag to checked out version of files"
|
complete -c cvs -x -a 'tag' -d 'Add a symbolic tag to checked out version of files'
|
||||||
complete -c cvs -x -a "unedit" -d "Undo an edit command"
|
complete -c cvs -x -a 'unedit' -d 'Undo an edit command'
|
||||||
complete -c cvs -x -a "update" -d "Bring work tree in sync with repository"
|
complete -c cvs -x -a 'update' -d 'Bring work tree in sync with repository'
|
||||||
complete -c cvs -x -a "version" -d "Show current CVS version(s)"
|
complete -c cvs -x -a 'version' -d 'Show current CVS version(s)'
|
||||||
complete -c cvs -x -a "watch" -d "Set watches"
|
complete -c cvs -x -a 'watch' -d 'Set watches'
|
||||||
complete -c cvs -x -a "watchers" -d "See who is watching a file"
|
complete -c cvs -x -a 'watchers' -d 'See who is watching a file'
|
||||||
|
|
||||||
complete -c cvs -x -s H -d "Displays usage information for command"
|
complete -c cvs -x -s H -d 'Displays usage information for command'
|
||||||
complete -c cvs -x -s Q -d "Cause CVS to be really quiet"
|
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 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 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 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 execute anything that will change the disk'
|
||||||
complete -c cvs -x -s t -d "Show trace of program execution -- try with -n"
|
complete -c cvs -x -s t -d 'Show trace of program execution -- try with -n'
|
||||||
complete -c cvs -x -s v -d "CVS version and copyright"
|
complete -c cvs -x -s v -d 'CVS version and copyright'
|
||||||
complete -c cvs -x -s T -r -d "Use 'tmpdir' for temporary files"
|
complete -c cvs -x -s T -r -d 'Use "tmpdir" for temporary files'
|
||||||
complete -c cvs -x -s e -r -d "Use 'editor' for editing log information"
|
complete -c cvs -x -s e -r -d 'Use "editor" for editing log information'
|
||||||
complete -c cvs -x -s d -r -d "Overrides $CVSROOT as the root of the CVS tree"
|
complete -c cvs -x -s d -r -d 'Overrides $CVSROOT as the root of the CVS tree'
|
||||||
complete -c cvs -x -s f -d "Do not use the ~/.cvsrc file"
|
complete -c cvs -x -s f -d 'Do not use the ~/.cvsrc file'
|
||||||
complete -c cvs -x -s z -d "Compression level for net traffic" -x -a "1 2 3 4 5 6 7 8 9"
|
complete -c cvs -x -s z -d 'Compression level for net traffic' -x -a '1 2 3 4 5 6 7 8 9'
|
||||||
complete -c cvs -x -s x -d "Encrypt all net traffic"
|
complete -c cvs -x -s x -d 'Encrypt all net traffic'
|
||||||
complete -c cvs -x -s a -d "Authenticate all net traffic"
|
complete -c cvs -x -s a -d 'Authenticate all net traffic'
|
||||||
complete -c cvs -x -s s -d "Set CVS user variable" -x
|
complete -c cvs -x -s s -d 'Set CVS user variable' -x
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
complete -c fish -s c -l "command" -d "Run fish with this command"
|
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 h -l help -d "Display help and exit"
|
||||||
complete -c fish -l version -d "Display version 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 i -l interactive -d "Run in interactive mode"
|
||||||
complete -c fish -s p -l profile -d "Output profiling information to specified file" -f
|
complete -c fish -s p -l profile -d "Output profiling information to specified file" -f
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# The gcc completion list is incomplete. There are just so many of them...
|
# The gcc completion list is incomplete. There are just so many of them...
|
||||||
#
|
#
|
||||||
|
|
||||||
complete -c gcc -s x -d "Language" -x -a "
|
complete -c gcc -s x -d 'Language' -x -a '
|
||||||
c
|
c
|
||||||
c-header
|
c-header
|
||||||
cpp-output
|
cpp-output
|
||||||
@@ -19,17 +19,17 @@ complete -c gcc -s x -d "Language" -x -a "
|
|||||||
java
|
java
|
||||||
treelang
|
treelang
|
||||||
none
|
none
|
||||||
"
|
'
|
||||||
complete -c gcc -o pass-exit-codes -d "Pass program exit codes"
|
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 c -d 'Stop after assembler'
|
||||||
complete -c gcc -s S -d "Stop after compile"
|
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 preprocesswor'
|
||||||
complete -c gcc -s o -r -d "Output file"
|
complete -c gcc -s o -r -d 'Output file'
|
||||||
complete -c gcc -s v -d "Print commands to stderr"
|
complete -c gcc -s v -d 'Print commands to stderr'
|
||||||
complete -c gcc -o \#\#\# -d "Print quoted commands to stderr, do not run"
|
complete -c gcc -o \#\#\# -d 'Print quoted commands to stderr, do not run'
|
||||||
complete -c gcc -o pipe -d "Use pipes"
|
complete -c gcc -o pipe -d 'Use pipes'
|
||||||
complete -c gcc -o ansi -d "Use ansi mode"
|
complete -c gcc -o ansi -d 'Use ansi mode'
|
||||||
complete -c gcc -o std -d "Standard mode" -x -a '
|
complete -c gcc -o std -d 'Standard mode' -x -a '
|
||||||
c89\t"ISO C90"
|
c89\t"ISO C90"
|
||||||
iso9899:1990\t"ISO C90"
|
iso9899:1990\t"ISO C90"
|
||||||
iso9899:199409\t"ISO C90 as modified in amendment 1"
|
iso9899:199409\t"ISO C90 as modified in amendment 1"
|
||||||
@@ -43,54 +43,54 @@ complete -c gcc -o std -d "Standard mode" -x -a '
|
|||||||
c++98\t"ISO C++98"
|
c++98\t"ISO C++98"
|
||||||
gnu++98\t"ISO C++98 plus GNU extentions"
|
gnu++98\t"ISO C++98 plus GNU extentions"
|
||||||
'
|
'
|
||||||
complete -c gcc -o aux-info -r -d "Write prototypes to file"
|
complete -c gcc -o aux-info -r -d 'Write prototypes to file'
|
||||||
complete -c gcc -o fno-asm -d "Do not recognize asm, inline or typeof keywords"
|
complete -c gcc -o fno-asm -d 'Do not recognize asm, inline or typeof keywords'
|
||||||
complete -c gcc -o fno-builtin -d "Do not use builtin functions"
|
complete -c gcc -o fno-builtin -d 'Do not use builtin functions'
|
||||||
complete -c gcc -o fhosted -d "Assert hosted environment"
|
complete -c gcc -o fhosted -d 'Assert hosted environment'
|
||||||
complete -c gcc -o ffreestanding -d "Assert freestanding environment"
|
complete -c gcc -o ffreestanding -d 'Assert freestanding environment'
|
||||||
complete -c gcc -o fms-extensions -d "Use Microsoft extensions"
|
complete -c gcc -o fms-extensions -d 'Use Microsoft extensions'
|
||||||
complete -c gcc -o trigraphs -d "Use ANSI trigraphs"
|
complete -c gcc -o trigraphs -d 'Use ANSI trigraphs'
|
||||||
complete -c gcc -o no-integrated-cpp -d "Do not use integrated preprocessor"
|
complete -c gcc -o no-integrated-cpp -d 'Do not use integrated preprocessor'
|
||||||
complete -c gcc -o funsigned-char -d "char is unsigned"
|
complete -c gcc -o funsigned-char -d 'char is unsigned'
|
||||||
complete -c gcc -o fsigned-char -d "char is signed"
|
complete -c gcc -o fsigned-char -d 'char is signed'
|
||||||
complete -c gcc -o funsigned-bitfields -d "bifield is unsigned"
|
complete -c gcc -o funsigned-bitfields -d 'bifield is unsigned'
|
||||||
complete -c gcc -o fsigned-bitfields -d "bifield is signed"
|
complete -c gcc -o fsigned-bitfields -d 'bifield is signed'
|
||||||
complete -c gcc -o fno-unsigned-bitfields -d "All bifields are signed"
|
complete -c gcc -o fno-unsigned-bitfields -d 'All bifields are signed'
|
||||||
complete -c gcc -o fno-signed-bitfields -d "All bifield are signed"
|
complete -c gcc -o fno-signed-bitfields -d 'All bifield are signed'
|
||||||
complete -c gcc -o fwritable-strings -d "String constants are not const"
|
complete -c gcc -o fwritable-strings -d 'String constants are not const'
|
||||||
complete -c gcc -o fabi-version -d "C++ ABI version" -r -x -a "1 0"
|
complete -c gcc -o fabi-version -d 'C++ ABI version' -r -x -a '1 0'
|
||||||
complete -c gcc -o fno-access-control -d "Turn off access checking"
|
complete -c gcc -o fno-access-control -d 'Turn off access checking'
|
||||||
complete -c gcc -o fcheck-new -d "Check pointer returned by new"
|
complete -c gcc -o fcheck-new -d 'Check pointer returned by new'
|
||||||
complete -c gcc -o fconserve-space -d "Put globals in the common segment"
|
complete -c gcc -o fconserve-space -d 'Put globals in the common segment'
|
||||||
complete -c gcc -o fno-const-strings -d "String constants are not const"
|
complete -c gcc -o fno-const-strings -d 'String constants are not const'
|
||||||
complete -c gcc -o fdollars-in-identifiers -d "Accept $ in identifiers"
|
complete -c gcc -o fdollars-in-identifiers -d 'Accept $ in identifiers'
|
||||||
complete -c gcc -o fno-dollars-in-identifiers -d "Reject $ in identifiers"
|
complete -c gcc -o fno-dollars-in-identifiers -d 'Reject $ in identifiers'
|
||||||
complete -c gcc -o fno-elide-constructors -d "Do not omit unneeded temporarys"
|
complete -c gcc -o fno-elide-constructors -d 'Do not omit unneeded temporarys'
|
||||||
complete -c gcc -o fno-enforce-eh-specs -d "Allow exception violations"
|
complete -c gcc -o fno-enforce-eh-specs -d 'Allow exception violations'
|
||||||
complete -c gcc -o ffor-scope -d "Do not extend for-loop scope"
|
complete -c gcc -o ffor-scope -d 'Do not extend for-loop scope'
|
||||||
complete -c gcc -o fno-for-scope -d "Extend for-loop scope"
|
complete -c gcc -o fno-for-scope -d 'Extend for-loop scope'
|
||||||
complete -c gcc -o fno-gnu-keywords -d "Do not recognize typeof as keyword"
|
complete -c gcc -o fno-gnu-keywords -d 'Do not recognize typeof as keyword'
|
||||||
complete -c gcc -o fno-implicit-templates -d "Do not emit code for implicit templates"
|
complete -c gcc -o fno-implicit-templates -d 'Do not emit code for implicit templates'
|
||||||
complete -c gcc -o fno-implicit-inline-templates -d "Do not emit code for implicit inline templates"
|
complete -c gcc -o fno-implicit-inline-templates -d 'Do not emit code for implicit inline templates'
|
||||||
complete -c gcc -o fno-implement-inlines -d "Do not emit out-of-line code for inline functions"
|
complete -c gcc -o fno-implement-inlines -d 'Do not emit out-of-line code for inline functions'
|
||||||
complete -c gcc -o fms-extensions -d "Disable warnings about MFC"
|
complete -c gcc -o fms-extensions -d 'Disable warnings about MFC'
|
||||||
complete -c gcc -o fno-nonansi-builtins -d "Disable some built-in functions"
|
complete -c gcc -o fno-nonansi-builtins -d 'Disable some built-in functions'
|
||||||
complete -c gcc -o fno-operator-names -d "Disable operator keywords"
|
complete -c gcc -o fno-operator-names -d 'Disable operator keywords'
|
||||||
complete -c gcc -o fno-optional-diags -d "Disable optional diagnostics"
|
complete -c gcc -o fno-optional-diags -d 'Disable optional diagnostics'
|
||||||
complete -c gcc -o fpermissive -d "Downgrade some errors to warnings"
|
complete -c gcc -o fpermissive -d 'Downgrade some errors to warnings'
|
||||||
complete -c gcc -o frepo -d "Enable automatic template instantiation at link time"
|
complete -c gcc -o frepo -d 'Enable automatic template instantiation at link time'
|
||||||
complete -c gcc -o fno-rtti -d "Disable generation of C++ runtime type information"
|
complete -c gcc -o fno-rtti -d 'Disable generation of C++ runtime type information'
|
||||||
#complete -c gcc -o fstats -d "Emit front-end usage statistics"
|
#complete -c gcc -o fstats -d 'Emit front-end usage statistics'
|
||||||
|
|
||||||
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17;
|
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17;
|
||||||
complete -c gcc -o ftemplate-depth-1 -d Set\ maximum\ template\ depth\ to\ $i;
|
complete -c gcc -o ftemplate-depth-1 -d Set\ maximum\ template\ depth\ to\ $i;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
complete -c gcc -o fno-threadsafe-statistics -d "Do not emit code for thread-safe initialization of local statics"
|
complete -c gcc -o fno-threadsafe-statistics -d 'Do not emit code for thread-safe initialization of local statics'
|
||||||
complete -c gcc -o fuse-cxa-atexit -d "Use __cxa_atexit for destructors"
|
complete -c gcc -o fuse-cxa-atexit -d 'Use __cxa_atexit for destructors'
|
||||||
complete -c gcc -o fvisibility-inlines-hidden -d "Hides inline methods from export table"
|
complete -c gcc -o fvisibility-inlines-hidden -d 'Hides inline methods from export table'
|
||||||
complete -c gcc -o fno-weak -d "Do not use weak symbol support"
|
complete -c gcc -o fno-weak -d 'Do not use weak symbol support'
|
||||||
# gcc completion listing is incomplete.
|
# gcc completion listing is incomplete.
|
||||||
#complete -c gcc -o -d ""
|
#complete -c gcc -o -d ''
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,8 +22,6 @@ complete -c help -x -a prompt -d "Help on how to set the prompt"
|
|||||||
complete -c help -x -a title -d "Help on how to set the titlebar message"
|
complete -c help -x -a title -d "Help on how to set the titlebar message"
|
||||||
complete -c help -x -a killring -d "Help on how to copy and paste"
|
complete -c help -x -a killring -d "Help on how to copy and paste"
|
||||||
complete -c help -x -a editor -d "Help on editor shortcuts"
|
complete -c help -x -a editor -d "Help on editor shortcuts"
|
||||||
complete -c help -x -a expand -d "Help on parameter expantion (Globbing)"
|
|
||||||
complete -c help -x -a globbing -d "Help on parameter expantion (Globbing)"
|
|
||||||
complete -c help -x -a variables -d "Help on environment variables"
|
complete -c help -x -a variables -d "Help on environment variables"
|
||||||
complete -c help -x -a color -d "Help on setting syntax highlighting colors"
|
complete -c help -x -a color -d "Help on setting syntax highlighting colors"
|
||||||
complete -c help -x -a prompt -d "Help on changing the prompt"
|
complete -c help -x -a prompt -d "Help on changing the prompt"
|
||||||
@@ -31,3 +29,11 @@ complete -c help -x -a title -d "Help on changing the titlebar messages"
|
|||||||
complete -c help -x -a builtin-overview -d "A short summary of all builtin commands"
|
complete -c help -x -a builtin-overview -d "A short summary of all builtin commands"
|
||||||
complete -c help -x -a changes -d "The changelog"
|
complete -c help -x -a changes -d "The changelog"
|
||||||
|
|
||||||
|
complete -c help -x -a globbing -d "Help on parameter expansion (Globbing)"
|
||||||
|
complete -c help -x -a expand -d "Help on parameter expansion (Globbing)"
|
||||||
|
complete -c help -x -a expand-variable -d "Help on variable exapantion \$VARNAME"
|
||||||
|
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-process -d "Help on process expansion %JOB"
|
||||||
|
|||||||
@@ -24,12 +24,12 @@ else
|
|||||||
|
|
||||||
complete -c kill -s l -d "List codes and names of available signals"
|
complete -c kill -s l -d "List codes and names of available signals"
|
||||||
|
|
||||||
for i in (kill -l|tr \ \t \n|grep "^[A-Z][A-Z0-9]*$")
|
for i in (kill -l|tr \ \t \n|grep '^[A-Z][A-Z0-9]*$')
|
||||||
complete -c kill -o $i -d Send\ $i\ signal
|
complete -c kill -o $i -d Send\ $i\ signal
|
||||||
complete -c kill -o s -x -a $i\tSend\ $i\ signal -d "Send specified signal"
|
complete -c kill -o s -x -a $i\tSend\ $i\ signal -d "Send specified signal"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
complete -c kill -xa "(__fish_complete_pids)"
|
complete -c kill -xa '(__fish_complete_pids)'
|
||||||
complete -c kill -s l -d "List names of available signals"
|
complete -c kill -s l -d "List names of available signals"
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ complete -c less -s I -l IGNORE-CASE -d "Search ignores all case"
|
|||||||
complete -c less -s j -l jump-target -d "Target line" -r -a "0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19"
|
complete -c less -s j -l jump-target -d "Target line" -r -a "0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19"
|
||||||
complete -c less -s J -l status-column -d "Display status column"
|
complete -c less -s J -l status-column -d "Display status column"
|
||||||
complete -c less -s k -l lesskey-file -d "Specify key bindings file" -r
|
complete -c less -s k -l lesskey-file -d "Specify key bindings file" -r
|
||||||
complete -c less -s L -l no-lessopen -d "Ignore $LESSOPEN"
|
complete -c less -s L -l no-lessopen -d 'Ignore $LESSOPEN'
|
||||||
complete -c less -s m -l long-prompt -d "Prompt with percentage"
|
complete -c less -s m -l long-prompt -d "Prompt with percentage"
|
||||||
complete -c less -s M -l LONG-PROMPT -d "Verbose prompt"
|
complete -c less -s M -l LONG-PROMPT -d "Verbose prompt"
|
||||||
complete -c less -s n -l line-numbers -d "Display line number"
|
complete -c less -s n -l line-numbers -d "Display line number"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
# A list of all known filesystem types, used by various completions,
|
# A list of all known filesystem types, used by various completions,
|
||||||
# including mount and df
|
# including mount and df
|
||||||
|
|
||||||
set -g __fish_filesystems "
|
set -g __fish_filesystems '
|
||||||
adfs
|
adfs
|
||||||
affs
|
affs
|
||||||
autofs
|
autofs
|
||||||
@@ -39,29 +39,29 @@ set -g __fish_filesystems "
|
|||||||
xenix
|
xenix
|
||||||
xfs
|
xfs
|
||||||
xiafs
|
xiafs
|
||||||
"
|
'
|
||||||
|
|
||||||
# Completions for mount
|
# Completions for mount
|
||||||
complete -x -c mount -a "(cat /etc/fstab|sed -e 's/^\([^ \t]*\)[ \t]*\([^ \t]*\).*/\1\n\2/'|grep '^/')" -d "Mount point"
|
complete -x -c mount -a '(cat /etc/fstab|sed -e "s/^\([^ \t]*\)[ \t]*\([^ \t]*\).*/\1\n\2/"|grep "^/")' -d 'Mount point'
|
||||||
complete -c mount -s V -d "Display version and exit"
|
complete -c mount -s V -d 'Display version and exit'
|
||||||
complete -c mount -s h -d "Display help and exit"
|
complete -c mount -s h -d 'Display help and exit'
|
||||||
complete -c mount -s v -d "Verbose mode"
|
complete -c mount -s v -d 'Verbose mode'
|
||||||
complete -c mount -s a -d "Mount filesystems in fstab"
|
complete -c mount -s a -d 'Mount filesystems in fstab'
|
||||||
complete -c mount -s F -d "Fork process for each mount"
|
complete -c mount -s F -d 'Fork process for each mount'
|
||||||
complete -c mount -s f -d "Fake mounting"
|
complete -c mount -s f -d 'Fake mounting'
|
||||||
complete -c mount -s l -d "Add label to output"
|
complete -c mount -s l -d 'Add label to output'
|
||||||
complete -c mount -s n -d "Do not write mtab"
|
complete -c mount -s n -d 'Do not write mtab'
|
||||||
complete -c mount -s s -d "Tolerate sloppy mount options"
|
complete -c mount -s s -d 'Tolerate sloppy mount options'
|
||||||
complete -c mount -s r -d "Read only"
|
complete -c mount -s r -d 'Read only'
|
||||||
complete -c mount -s w -d "Read/Write mode"
|
complete -c mount -s w -d 'Read/Write mode'
|
||||||
complete -x -c mount -s L -d "Mount partition with specified label"
|
complete -x -c mount -s L -d 'Mount partition with specified label'
|
||||||
complete -x -c mount -s U -d "Mount partition with specified UID"
|
complete -x -c mount -s U -d 'Mount partition with specified UID'
|
||||||
complete -c mount -s O -x -d "Exclude filesystems"
|
complete -c mount -s O -x -d 'Exclude filesystems'
|
||||||
complete -c mount -l bind -f -d "Remount a subtree to a second position"
|
complete -c mount -l bind -f -d 'Remount a subtree to a second position'
|
||||||
complete -c mount -l move -f -d "Move a subtree to a new position"
|
complete -c mount -l move -f -d 'Move a subtree to a new position'
|
||||||
complete -c mount -x -s t -d "Filesystem" -a $__fish_filesystems
|
complete -c mount -x -s t -d 'Filesystem' -a $__fish_filesystems
|
||||||
|
|
||||||
complete -c mount -x -s o -d "Mount option" -a "(__fish_append ',' $__fish_mount_opts)"
|
complete -c mount -x -s o -d 'Mount option' -a '(__fish_append , $__fish_mount_opts)'
|
||||||
|
|
||||||
set -g __fish_mount_opts async\tUse\ asynchronous\ I/O atime\tUpdate\ time\ on\ each\ access auto\tMounted\ with\ -a defaults\tUse\ default\ options dev\tInterpret\ character/block\ special\ devices exec\tPermit\ executables _netdev\tFilesystem\ uses\network noatime\tDo\ not\ update\ time\ on\ each\ access noauto\tNot\ mounted\ by\ -a nodev\tDo\ not\ interpret\ character/block\ special\ devices noexec\tDo\ not\ permit\ executables nosuid\tIgnore\ suid\ bits nouser\tOnly\ root\ may\ mount remount\tRemount\ read-only\ filesystem ro\tMount\ read-only rw\tMount\ read-write suid\tAllow\ suid\ bits sync\tUse\ synchronous\ I/O dirsync\tUse\ synchronous\ directory\ operations user\tAny\ user\ may\ mount users\tAny\ user\ may\ mount\ and\ unmount
|
set -g __fish_mount_opts async\tUse\ asynchronous\ I/O atime\tUpdate\ time\ on\ each\ access auto\tMounted\ with\ -a defaults\tUse\ default\ options dev\tInterpret\ character/block\ special\ devices exec\tPermit\ executables _netdev\tFilesystem\ uses\network noatime\tDo\ not\ update\ time\ on\ each\ access noauto\tNot\ mounted\ by\ -a nodev\tDo\ not\ interpret\ character/block\ special\ devices noexec\tDo\ not\ permit\ executables nosuid\tIgnore\ suid\ bits nouser\tOnly\ root\ may\ mount remount\tRemount\ read-only\ filesystem ro\tMount\ read-only rw\tMount\ read-write suid\tAllow\ suid\ bits sync\tUse\ synchronous\ I/O dirsync\tUse\ synchronous\ directory\ operations user\tAny\ user\ may\ mount users\tAny\ user\ may\ mount\ and\ unmount
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
complete -c perl -s 0 -d "Specify record separator"
|
complete -c perl -s 0 -d 'Specify record separator'
|
||||||
complete -c perl -s a -d "Feed input to split"
|
complete -c perl -s a -d 'Feed input to split'
|
||||||
complete -c perl -s c -d "Check syntax"
|
complete -c perl -s c -d 'Check syntax'
|
||||||
complete -c perl -s d -d "Debugger"
|
complete -c perl -s d -d 'Debugger'
|
||||||
complete -c perl -s D -x -d "Debug option"
|
complete -c perl -s D -x -d 'Debug option'
|
||||||
complete -c perl -s e -x -d "Execute command"
|
complete -c perl -s e -x -d 'Execute command'
|
||||||
complete -c perl -s F -d "Set regexp used to split input"
|
complete -c perl -s F -d 'Set regexp used to split input'
|
||||||
complete -c perl -s i -d "Edit files in-place"
|
complete -c perl -s i -d 'Edit files in-place'
|
||||||
complete -c perl -s I -d "Include path"
|
complete -c perl -s I -d 'Include path'
|
||||||
complete -c perl -s l -d "Line ending processing"
|
complete -c perl -s l -d 'Line ending processing'
|
||||||
complete -c perl -s n -d "Loop script"
|
complete -c perl -s n -d 'Loop script'
|
||||||
complete -c perl -s p -d "Loop script, print $_"
|
complete -c perl -s p -d 'Loop script, print $_'
|
||||||
complete -c perl -s P -d "Invoke CPP"
|
complete -c perl -s P -d 'Invoke CPP'
|
||||||
complete -c perl -s s -d "Define custom switches"
|
complete -c perl -s s -d 'Define custom switches'
|
||||||
complete -c perl -s S -d "Search $PATH for script"
|
complete -c perl -s S -d 'Search $PATH for script'
|
||||||
complete -c perl -s T -d "Taint checking"
|
complete -c perl -s T -d 'Taint checking'
|
||||||
complete -c perl -s U -d "Unsafe mode"
|
complete -c perl -s U -d 'Unsafe mode'
|
||||||
complete -c perl -s v -d "Display version"
|
complete -c perl -s v -d 'Display version'
|
||||||
complete -c perl -s x -d "Extract script"
|
complete -c perl -s x -d 'Extract script'
|
||||||
|
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ complete $rpm_erase -l repackage -d 'Re-package the files before erasing'
|
|||||||
complete $rpm_erase -l test -d 'Dont really uninstall anything, just go through the motions'
|
complete $rpm_erase -l test -d 'Dont really uninstall anything, just go through the motions'
|
||||||
set -e rpm_erase
|
set -e rpm_erase
|
||||||
|
|
||||||
set -- rpm_mode -c rpm -n "__fish_contains_opt -s e -s i -s F -s V -s U -s q erase install freshen verify upgrade query; if test $status = 0; false; else; true; end"
|
set -- rpm_mode -c rpm -n '__fish_contains_opt -s e -s i -s F -s V -s U -s q erase install freshen verify upgrade query; if test $status = 0; false; else; true; end'
|
||||||
complete $rpm_mode -s i -l install -d 'Install new package'
|
complete $rpm_mode -s i -l install -d 'Install new package'
|
||||||
complete $rpm_mode -s U -l upgrade -d 'Upgrade existing package'
|
complete $rpm_mode -s U -l upgrade -d 'Upgrade existing package'
|
||||||
complete $rpm_mode -s F -l freshen -d 'Upgrade package if already installed'
|
complete $rpm_mode -s F -l freshen -d 'Upgrade package if already installed'
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
#Completions for ruby
|
#Completions for ruby
|
||||||
complete -c ruby -s 0 -d "Specify record separator"
|
complete -c ruby -s 0 -d 'Specify record separator'
|
||||||
complete -c ruby -s a -d "Feed input to split"
|
complete -c ruby -s a -d 'Feed input to split'
|
||||||
complete -c ruby -s c -d "Check syntax"
|
complete -c ruby -s c -d 'Check syntax'
|
||||||
complete -c ruby -s K -d "Kanji code-set"
|
complete -c ruby -s K -d 'Kanji code-set'
|
||||||
complete -c ruby -s d -l debug -d "Debugger"
|
complete -c ruby -s d -l debug -d 'Debugger'
|
||||||
complete -c ruby -s e -x -d "Execute command"
|
complete -c ruby -s e -x -d 'Execute command'
|
||||||
complete -c ruby -s h -l help -d "Display help"
|
complete -c ruby -s h -l help -d 'Display help'
|
||||||
complete -c ruby -s F -d "Set regexp used to split input"
|
complete -c ruby -s F -d 'Set regexp used to split input'
|
||||||
complete -c ruby -s i -d "Edit files in-place"
|
complete -c ruby -s i -d 'Edit files in-place'
|
||||||
complete -c ruby -s I -d "Include path"
|
complete -c ruby -s I -d 'Include path'
|
||||||
complete -c ruby -s l -d "Line ending processing"
|
complete -c ruby -s l -d 'Line ending processing'
|
||||||
complete -c ruby -s n -d "Loop script"
|
complete -c ruby -s n -d 'Loop script'
|
||||||
complete -c ruby -s p -d "Loop script, print $_"
|
complete -c ruby -s p -d 'Loop script, print $_'
|
||||||
complete -c ruby -s r -r -d "Require file"
|
complete -c ruby -s r -r -d 'Require file'
|
||||||
complete -c ruby -s s -d "Define custom switches"
|
complete -c ruby -s s -d 'Define custom switches'
|
||||||
complete -c ruby -s S -d "Search $PATH for script"
|
complete -c ruby -s S -d 'Search $PATH for script'
|
||||||
complete -c ruby -s T -d "Taint checking"
|
complete -c ruby -s T -d 'Taint checking'
|
||||||
complete -c ruby -s v -l verbose -d "Verbose mode"
|
complete -c ruby -s v -l verbose -d 'Verbose mode'
|
||||||
complete -c ruby -s w -d "Verbose mode without message"
|
complete -c ruby -s w -d 'Verbose mode without message'
|
||||||
complete -c ruby -l version -d "Display version"
|
complete -c ruby -l version -d 'Display version'
|
||||||
complete -c ruby -s x -d "Extract script"
|
complete -c ruby -s x -d 'Extract script'
|
||||||
complete -c ruby -s X -x -a "(__fish_complete_directory (commandline -ct))" -d "Directory"
|
complete -c ruby -s X -x -a '(__fish_complete_directory (commandline -ct))' -d 'Directory'
|
||||||
complete -c ruby -s y -l yydebug -d "Compiler debug mode"
|
complete -c ruby -s y -l yydebug -d 'Compiler debug mode'
|
||||||
|
|
||||||
|
|||||||
@@ -3,35 +3,35 @@ function __fish_complete_screen -d "Print a list of running screen sessions"
|
|||||||
end
|
end
|
||||||
|
|
||||||
complete -c screen -x
|
complete -c screen -x
|
||||||
complete -c screen -s a -d "Include all capabilitys"
|
complete -c screen -s a -d 'Include all capabilitys'
|
||||||
complete -c screen -s A -d "Adapt window size"
|
complete -c screen -s A -d 'Adapt window size'
|
||||||
complete -c screen -s c -r -d "Specify init file"
|
complete -c screen -s c -r -d 'Specify init file'
|
||||||
complete -c screen -s d -d "Detach screen" -a "(__fish_complete_screen)"
|
complete -c screen -s d -d 'Detach screen' -a '(__fish_complete_screen)'
|
||||||
complete -c screen -s D -d "Detach screen" -a "(__fish_complete_screen)"
|
complete -c screen -s D -d 'Detach screen' -a '(__fish_complete_screen)'
|
||||||
complete -c screen -s r -d "Reattach session" -a "(__fish_complete_screen)"
|
complete -c screen -s r -d 'Reattach session' -a '(__fish_complete_screen)'
|
||||||
complete -c screen -s R -d "Reattach/create session"
|
complete -c screen -s R -d 'Reattach/create session'
|
||||||
complete -c screen -o RR -d "Reattach/create any session"
|
complete -c screen -o RR -d 'Reattach/create any session'
|
||||||
complete -c screen -s e -x -d "Escape character"
|
complete -c screen -s e -x -d 'Escape character'
|
||||||
complete -c screen -s f -d "Flow control on"
|
complete -c screen -s f -d 'Flow control on'
|
||||||
complete -c screen -o fn -d "Flow control off"
|
complete -c screen -o fn -d 'Flow control off'
|
||||||
complete -c screen -o fa -d "Flow control automatic"
|
complete -c screen -o fa -d 'Flow control automatic'
|
||||||
complete -c screen -s h -x -d "History length"
|
complete -c screen -s h -x -d 'History length'
|
||||||
complete -c screen -s i -d "Interrupt display on C-c"
|
complete -c screen -s i -d 'Interrupt display on C-c'
|
||||||
complete -c screen -s l -d "Login on"
|
complete -c screen -s l -d 'Login on'
|
||||||
complete -c screen -o ln -d "Login off"
|
complete -c screen -o ln -d 'Login off'
|
||||||
complete -c screen -o ls -d "List sessions"
|
complete -c screen -o ls -d 'List sessions'
|
||||||
complete -c screen -o list -d "List sessions"
|
complete -c screen -o list -d 'List sessions'
|
||||||
complete -c screen -s L -d "Log on"
|
complete -c screen -s L -d 'Log on'
|
||||||
complete -c screen -s m -d "Ignore $STY"
|
complete -c screen -s m -d 'Ignore $STY'
|
||||||
complete -c screen -s O -d "Optimal output"
|
complete -c screen -s O -d 'Optimal output'
|
||||||
complete -c screen -s p -d "Preselect window"
|
complete -c screen -s p -d 'Preselect window'
|
||||||
complete -c screen -s q -d "Quiet mode"
|
complete -c screen -s q -d 'Quiet mode'
|
||||||
complete -c screen -s s -r -d "Set shell"
|
complete -c screen -s s -r -d 'Set shell'
|
||||||
complete -c screen -s S -x -d "Session name"
|
complete -c screen -s S -x -d 'Session name'
|
||||||
complete -c screen -s t -x -d "Session title"
|
complete -c screen -s t -x -d 'Session title'
|
||||||
complete -c screen -s U -d "UTF-8 mode"
|
complete -c screen -s U -d 'UTF-8 mode'
|
||||||
complete -c screen -s v -d "Display version"
|
complete -c screen -s v -d 'Display version'
|
||||||
complete -c screen -o wipe -d "Wipe dead sessions"
|
complete -c screen -o wipe -d 'Wipe dead sessions'
|
||||||
complete -c screen -s x -d "Multi attach"
|
complete -c screen -s x -d 'Multi attach'
|
||||||
complete -c screen -s X -r -d "Send command"
|
complete -c screen -s X -r -d 'Send command'
|
||||||
|
|
||||||
|
|||||||
19
init/fish.in
19
init/fish.in
@@ -16,19 +16,20 @@ set -g IFS \ \t\n
|
|||||||
#
|
#
|
||||||
|
|
||||||
for i in /bin /usr/bin /usr/X11R6/bin @PREFIX@/bin
|
for i in /bin /usr/bin /usr/X11R6/bin @PREFIX@/bin
|
||||||
if test -d $i
|
if not expr "$PATH" : .\*$i.\* >/dev/null
|
||||||
if not echo $PATH|grep $i >/dev/null
|
if test -d $i
|
||||||
set PATH $PATH $i
|
set PATH $PATH $i
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Set some value for LANG if nothing was set before
|
# Set some value for LANG if nothing was set before
|
||||||
#
|
#
|
||||||
|
|
||||||
if status --is-login
|
if status --is-login
|
||||||
if not count $LANG >/dev/null
|
if not set -q LANG >/dev/null
|
||||||
set -gx LANG en_US.UTF-8
|
set -gx LANG en_US.UTF-8
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -39,13 +40,9 @@ end
|
|||||||
# situation as well?
|
# situation as well?
|
||||||
#
|
#
|
||||||
|
|
||||||
if count $LANG >/dev/null
|
if expr match "$LANG" ".*UTF" >/dev/null
|
||||||
if test (expr match $LANG ".*UTF") -gt 0
|
if test linux = "$TERM"
|
||||||
if count $TERM >/dev/null
|
unicode_start ^/dev/null
|
||||||
if test linux = $TERM
|
|
||||||
unicode_start ^/dev/null
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -56,7 +53,7 @@ end
|
|||||||
#
|
#
|
||||||
|
|
||||||
for i in DISPLAY
|
for i in DISPLAY
|
||||||
if test (count $$i) -gt 1
|
if set -q $i
|
||||||
set -- $i (printf ":%s" $$i|cut -c 2-)
|
set -- $i (printf ":%s" $$i|cut -c 2-)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ if not status --is-interactive
|
|||||||
exit
|
exit
|
||||||
end
|
end
|
||||||
|
|
||||||
set -g fish_complete_path /etc/fish.d/completions ~/.fish.d/completions
|
set -g fish_complete_path @SYSCONFDIR@/fish.d/completions ~/.fish.d/completions
|
||||||
|
|
||||||
# Knowing the location of the whatis database speeds up command
|
# Knowing the location of the whatis database speeds up command
|
||||||
# description lookup.
|
# description lookup.
|
||||||
@@ -42,10 +42,10 @@ function __fish_complete_suffix -d "Complete using files"
|
|||||||
set -- desc $argv[3]
|
set -- desc $argv[3]
|
||||||
|
|
||||||
set -- base (echo $comp |sed -e 's/\.[a-zA-Z0-9]*$//')
|
set -- base (echo $comp |sed -e 's/\.[a-zA-Z0-9]*$//')
|
||||||
eval "set -- files "$base"*"$suff
|
eval "set -- files $base*$suff"
|
||||||
|
|
||||||
if test $files[1]
|
if test $files[1]
|
||||||
printf "%s\t"$desc"\n" $files
|
printf "%s\t$desc\n" $files
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -74,7 +74,7 @@ function __fish_complete_directory -d "Complete using directories"
|
|||||||
eval "set -- dirs "$comp"*/"
|
eval "set -- dirs "$comp"*/"
|
||||||
|
|
||||||
if test $dirs[1]
|
if test $dirs[1]
|
||||||
printf "%s\t"$desc"\n" $dirs
|
printf "%s\t$desc\n" $dirs
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -6,10 +6,8 @@
|
|||||||
function _contains_help -d "Helper function for contains"
|
function _contains_help -d "Helper function for contains"
|
||||||
|
|
||||||
set bullet \*
|
set bullet \*
|
||||||
if count $LANG >/dev/null
|
if expr match "$LANG" ".*UTF" >/dev/null
|
||||||
if test (expr match $LANG ".*UTF") -gt 0
|
set bullet \u2022
|
||||||
set bullet \u2022
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
echo \tcontains - Test if a word is present in a list\n
|
echo \tcontains - Test if a word is present in a list\n
|
||||||
@@ -134,18 +132,20 @@ function help -d "Show help for the fish shell"
|
|||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
|
|
||||||
set fish_help_item $argv[1]
|
if count $argv >/dev/null
|
||||||
|
set fish_help_item $argv[1]
|
||||||
|
end
|
||||||
set fish_help_page ""
|
set fish_help_page ""
|
||||||
|
|
||||||
if test $fish_help_item = .
|
if test "$fish_help_item" = .
|
||||||
set fish_help_page "builtins.html\#source"
|
set fish_help_page "builtins.html\#source"
|
||||||
end
|
end
|
||||||
|
|
||||||
if test $fish_help_item = difference
|
if test "$fish_help_item" = difference
|
||||||
set fish_help_page difference.html
|
set fish_help_page difference.html
|
||||||
end
|
end
|
||||||
|
|
||||||
if test $fish_help_item = globbing
|
if test "$fish_help_item" = globbing
|
||||||
set fish_help_page "index.html\#expand"
|
set fish_help_page "index.html\#expand"
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -158,8 +158,9 @@ function help -d "Show help for the fish shell"
|
|||||||
end
|
end
|
||||||
|
|
||||||
set idx_subj syntax completion editor job-control todo bugs history
|
set idx_subj syntax completion editor job-control todo bugs history
|
||||||
set idx_subj $idx_subj killring help color prompt title expand variables
|
set idx_subj $idx_subj killring help color prompt title variables
|
||||||
set idx_subj $idx_subj builtin-overview changes
|
set idx_subj $idx_subj builtin-overview changes
|
||||||
|
set idx_subj $idx_subj expand expand-variable expand-home expand-brace expand-wildcard expand-command-substitution expand-process
|
||||||
|
|
||||||
if contains -- $fish_help_item $idx_subj
|
if contains -- $fish_help_item $idx_subj
|
||||||
set fish_help_page "index.html\#"$fish_help_item
|
set fish_help_page "index.html\#"$fish_help_item
|
||||||
@@ -222,11 +223,9 @@ function prompt_pwd -d "Print the current working directory, ellipsise it if it
|
|||||||
if test $len -gt $max_width
|
if test $len -gt $max_width
|
||||||
#Write ellipsis character if known to be using UTF
|
#Write ellipsis character if known to be using UTF
|
||||||
#else use $
|
#else use $
|
||||||
set -l ellipsis "$" #default
|
set -l ellipsis '$' #default
|
||||||
if count $LANG >/dev/null
|
if expr match "$LANG" ".*UTF" >/dev/null
|
||||||
if test (expr match $LANG ".*UTF") -gt 0
|
set ellipsis \u2026
|
||||||
set ellipsis \u2026
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
printf %s%s $ellipsis (echo $wd|cut -c (echo $len-$max_width-1|bc)- ^/dev/null )
|
printf %s%s $ellipsis (echo $wd|cut -c (echo $len-$max_width-1|bc)- ^/dev/null )
|
||||||
else
|
else
|
||||||
@@ -564,10 +563,8 @@ end
|
|||||||
function __fish_type_help -d "Help for the type shellscript function"
|
function __fish_type_help -d "Help for the type shellscript function"
|
||||||
|
|
||||||
set bullet \*
|
set bullet \*
|
||||||
if count $LANG >/dev/null
|
if expr match "$LANG" ".*UTF" >/dev/null
|
||||||
if test (expr match $LANG ".*UTF") -gt 0
|
|
||||||
set bullet \u2022
|
set bullet \u2022
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
echo \ttype - Indicate how a name would be interpreted if used as a \n\tcommand name
|
echo \ttype - Indicate how a name would be interpreted if used as a \n\tcommand name
|
||||||
@@ -1008,3 +1005,4 @@ function delete-or-exit --key-binding
|
|||||||
exit
|
exit
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ printf 'for instructions on how to use fish\n'
|
|||||||
# Set exit message
|
# Set exit message
|
||||||
#
|
#
|
||||||
|
|
||||||
function fish_on_exit -d "Commands to execute when fish exits"
|
function fish_on_exit -d "Commands to execute when fish exits" --on-process %self
|
||||||
echo Good bye
|
echo Good bye
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -39,9 +39,11 @@ end
|
|||||||
# other than fish, which may use a different file. The new value should
|
# other than fish, which may use a different file. The new value should
|
||||||
# be exported, since the fish inputrc file plays nice with other files
|
# be exported, since the fish inputrc file plays nice with other files
|
||||||
# by including them when found.
|
# by including them when found.
|
||||||
|
# Give priority to the default file installed with fish in
|
||||||
|
# @SYSCONFDIR@/fish_inputrc.
|
||||||
#
|
#
|
||||||
|
|
||||||
for i in ~/.fish_inputrc ~/etc/fish_inputrc /etc/fish_inputrc ~/.inputrc /etc/inputrc
|
for i in ~/.fish_inputrc @SYSCONFDIR@/fish_inputrc ~/etc/fish_inputrc /etc/fish_inputrc ~/.inputrc /etc/inputrc
|
||||||
if test -f $i
|
if test -f $i
|
||||||
set -xg INPUTRC $i
|
set -xg INPUTRC $i
|
||||||
break
|
break
|
||||||
@@ -58,7 +60,7 @@ function set_default_color -d "Set an universal variable, unless it has already
|
|||||||
set -U -- $argv
|
set -U -- $argv
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if contains -- $$argv[1] (set_color --print-colors)
|
if contains -- $$argv[1] (set_color -c)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
set -U -- $argv
|
set -U -- $argv
|
||||||
7
input.c
7
input.c
@@ -49,6 +49,7 @@ implementation in fish is as of yet incomplete.
|
|||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "env.h"
|
#include "env.h"
|
||||||
#include "expand.h"
|
#include "expand.h"
|
||||||
|
#include "event.h"
|
||||||
|
|
||||||
static void input_read_inputrc( wchar_t *fn );
|
static void input_read_inputrc( wchar_t *fn );
|
||||||
|
|
||||||
@@ -697,7 +698,7 @@ static wchar_t *input_expand_sequence( const wchar_t *in )
|
|||||||
}
|
}
|
||||||
debug( 1, L"Invalid sequence - Control-nothing?\n" );
|
debug( 1, L"Invalid sequence - Control-nothing?\n" );
|
||||||
error = 1;
|
error = 1;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1266,6 +1267,10 @@ static void add_vi_bindings()
|
|||||||
*/
|
*/
|
||||||
static int interrupt_handler()
|
static int interrupt_handler()
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
Fire any pending events
|
||||||
|
*/
|
||||||
|
event_fire( 0, 0 );
|
||||||
if( job_reap( 1 ) )
|
if( job_reap( 1 ) )
|
||||||
repaint();
|
repaint();
|
||||||
if( reader_interupted() )
|
if( reader_interupted() )
|
||||||
|
|||||||
8
main.c
8
main.c
@@ -111,7 +111,7 @@ int main( int argc, char **argv )
|
|||||||
|
|
||||||
while( 1 )
|
while( 1 )
|
||||||
{
|
{
|
||||||
#ifdef __GLIBC__
|
#ifdef HAVE_GETOPT_LONG
|
||||||
static struct option
|
static struct option
|
||||||
long_options[] =
|
long_options[] =
|
||||||
{
|
{
|
||||||
@@ -284,11 +284,7 @@ int main( int argc, char **argv )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc_fire_event( L"PROCESS_EXIT", EVENT_EXIT, getpid(), res );
|
||||||
if( function_exists(L"fish_on_exit"))
|
|
||||||
{
|
|
||||||
eval( L"fish_on_exit", 0, TOP );
|
|
||||||
}
|
|
||||||
|
|
||||||
reader_pop_current_filename();
|
reader_pop_current_filename();
|
||||||
|
|
||||||
|
|||||||
2
mimedb.c
2
mimedb.c
@@ -1018,7 +1018,7 @@ int main (int argc, char *argv[])
|
|||||||
*/
|
*/
|
||||||
while( 1 )
|
while( 1 )
|
||||||
{
|
{
|
||||||
#ifdef __GLIBC__
|
#ifdef HAVE_GETOPT_LONG
|
||||||
static struct option
|
static struct option
|
||||||
long_options[] =
|
long_options[] =
|
||||||
{
|
{
|
||||||
|
|||||||
409
parser.c
409
parser.c
@@ -66,7 +66,7 @@ The fish parser. Contains functions for parsing code.
|
|||||||
Error message for tokenizer error. The tokenizer message is
|
Error message for tokenizer error. The tokenizer message is
|
||||||
appended to this message.
|
appended to this message.
|
||||||
*/
|
*/
|
||||||
#define TOK_ERR_MSG L"Tokenizer error"
|
#define TOK_ERR_MSG L"Tokenizer error: %ls"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Error message for short circut command error.
|
Error message for short circut command error.
|
||||||
@@ -98,6 +98,16 @@ The fish parser. Contains functions for parsing code.
|
|||||||
*/
|
*/
|
||||||
#define CMD_ERR_MSG L"Expected command"
|
#define CMD_ERR_MSG L"Expected command"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Error message for wildcards with no matches
|
||||||
|
*/
|
||||||
|
#define WILDCARD_ERR_MSG L"Warning: No match for wildcard %ls"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Error message for Posix-style assignment
|
||||||
|
*/
|
||||||
|
#define COMMAND_ASSIGN_ERR_MSG L"Unknown command %ls. Did you mean 'set VARIABLE VALUE'? For information on setting variable values, see the manual section on the set command by typing 'help set'."
|
||||||
|
|
||||||
/** Last error code */
|
/** Last error code */
|
||||||
int error_code;
|
int error_code;
|
||||||
|
|
||||||
@@ -152,23 +162,23 @@ static int parse_job( process_t *p,
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
Time spent executing the specified command, including parse time for nested blocks
|
Time spent executing the specified command, including parse time for nested blocks.
|
||||||
*/
|
*/
|
||||||
int exec;
|
int exec;
|
||||||
/**
|
/**
|
||||||
Time spent parsing the specified command, incvluding execution time for command substitutions
|
Time spent parsing the specified command, including execution time for command substitutions.
|
||||||
*/
|
*/
|
||||||
int parse;
|
int parse;
|
||||||
/**
|
/**
|
||||||
The block level of the specified command
|
The block level of the specified command. nested blocks and command substitutions both increase the block level.
|
||||||
*/
|
*/
|
||||||
int level;
|
int level;
|
||||||
/**
|
/**
|
||||||
If the execution of this command was skipped
|
If the execution of this command was skipped.
|
||||||
*/
|
*/
|
||||||
int skipped;
|
int skipped;
|
||||||
/**
|
/**
|
||||||
The command string
|
The command string.
|
||||||
*/
|
*/
|
||||||
wchar_t *cmd;
|
wchar_t *cmd;
|
||||||
} profile_element_t;
|
} profile_element_t;
|
||||||
@@ -192,11 +202,14 @@ void parser_push_block( int type )
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
New blocks should be skipped if the outer block is skipped,
|
New blocks should be skipped if the outer block is skipped,
|
||||||
except TOP ans SUBST block, which open up new environments
|
except TOP ans SUBST block, which open up new environments. Fake
|
||||||
|
blocks should always be skipped. Rather complicated... :-(
|
||||||
*/
|
*/
|
||||||
new->skip=current_block?current_block->skip:0;
|
new->skip=current_block?current_block->skip:0;
|
||||||
if( type == TOP || type == SUBST )
|
if( type == TOP || type == SUBST )
|
||||||
new->skip = 0;
|
new->skip = 0;
|
||||||
|
if( type == FAKE )
|
||||||
|
new->skip = 1;
|
||||||
|
|
||||||
new->job = 0;
|
new->job = 0;
|
||||||
|
|
||||||
@@ -559,21 +572,17 @@ void parser_allow_function()
|
|||||||
free( (void *) al_pop( &forbidden_function ) );
|
free( (void *) al_pop( &forbidden_function ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void error( int ec, const wchar_t *str, int p )
|
void error( int ec, int p, const wchar_t *str, ... )
|
||||||
{
|
{
|
||||||
error_code = ec;
|
va_list va;
|
||||||
wcsncpy( err_str, str, 256 );
|
|
||||||
err_pos = p;
|
error_code = ec;
|
||||||
}
|
err_pos = p;
|
||||||
|
|
||||||
|
va_start( va, str );
|
||||||
|
vswprintf( err_str, 256, str, va );
|
||||||
|
va_end( va );
|
||||||
|
|
||||||
/**
|
|
||||||
Wrapper for the error function, which sets the error string to "ec 'ea'".
|
|
||||||
*/
|
|
||||||
static void error_arg( int ec, const wchar_t *es, const wchar_t *ea, int p )
|
|
||||||
{
|
|
||||||
wchar_t *msg = wcsdupcat2( es, L" \'", ea, L"\'", 0 );
|
|
||||||
error( ec, msg, p );
|
|
||||||
free(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wchar_t *get_filename( const wchar_t *cmd )
|
wchar_t *get_filename( const wchar_t *cmd )
|
||||||
@@ -652,7 +661,7 @@ wchar_t *get_filename( const wchar_t *cmd )
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
debug( 1,
|
debug( 1,
|
||||||
L"Error while searching for command %d",
|
L"Error while searching for command %ls",
|
||||||
new_cmd );
|
new_cmd );
|
||||||
wperror( L"access" );
|
wperror( L"access" );
|
||||||
}
|
}
|
||||||
@@ -757,7 +766,6 @@ static void print_errors()
|
|||||||
{
|
{
|
||||||
int tmp;
|
int tmp;
|
||||||
|
|
||||||
|
|
||||||
debug( 0, L"%ls", err_str );
|
debug( 0, L"%ls", err_str );
|
||||||
|
|
||||||
tmp = current_tokenizer_pos;
|
tmp = current_tokenizer_pos;
|
||||||
@@ -791,10 +799,20 @@ int eval_args( const wchar_t *line, array_list_t *args )
|
|||||||
switch(tok_last_type( &tok ) )
|
switch(tok_last_type( &tok ) )
|
||||||
{
|
{
|
||||||
case TOK_STRING:
|
case TOK_STRING:
|
||||||
if( !expand_string( wcsdup(tok_last( &tok )), args, 0 ) )
|
switch( expand_string( wcsdup(tok_last( &tok )), args, 0 ) )
|
||||||
{
|
{
|
||||||
err_pos=tok_get_pos( &tok );
|
case EXPAND_ERROR:
|
||||||
do_loop=0;
|
{
|
||||||
|
err_pos=tok_get_pos( &tok );
|
||||||
|
do_loop=0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -803,20 +821,21 @@ int eval_args( const wchar_t *line, array_list_t *args )
|
|||||||
|
|
||||||
case TOK_ERROR:
|
case TOK_ERROR:
|
||||||
{
|
{
|
||||||
error_arg( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
TOK_ERR_MSG,
|
tok_get_pos( &tok ),
|
||||||
tok_last(&tok),
|
TOK_ERR_MSG,
|
||||||
tok_get_pos( &tok ) );
|
tok_last(&tok) );
|
||||||
|
|
||||||
do_loop=0;
|
do_loop=0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error_arg( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
L"Unexpected token of type",
|
tok_get_pos( &tok ),
|
||||||
tok_get_desc( tok_last_type(&tok)),
|
L"Unexpected token of type %ls",
|
||||||
tok_get_pos( &tok ) );
|
tok_get_desc( tok_last_type(&tok)) );
|
||||||
|
|
||||||
do_loop=0;
|
do_loop=0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -948,6 +967,11 @@ static void parse_job_main_loop( process_t *p,
|
|||||||
|
|
||||||
int proc_is_count=0;
|
int proc_is_count=0;
|
||||||
|
|
||||||
|
int matched_wildcard = 0, unmatched_wildcard = 0;
|
||||||
|
|
||||||
|
wchar_t *unmatched = 0;
|
||||||
|
int unmatched_pos=0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Test if this is the 'count' command. We need to special case
|
Test if this is the 'count' command. We need to special case
|
||||||
count, since it should display a help message on 'count .h',
|
count, since it should display a help message on 'count .h',
|
||||||
@@ -974,8 +998,8 @@ static void parse_job_main_loop( process_t *p,
|
|||||||
if( (p->type == INTERNAL_EXEC) )
|
if( (p->type == INTERNAL_EXEC) )
|
||||||
{
|
{
|
||||||
error( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
EXEC_ERR_MSG,
|
tok_get_pos( tok ),
|
||||||
tok_get_pos( tok ) );
|
EXEC_ERR_MSG );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
p->pipe_fd = wcstol( tok_last( tok ), 0, 10 );
|
p->pipe_fd = wcstol( tok_last( tok ), 0, 10 );
|
||||||
@@ -1045,20 +1069,48 @@ static void parse_job_main_loop( process_t *p,
|
|||||||
wcscpy( p->actual_cmd, L"count" );
|
wcscpy( p->actual_cmd, L"count" );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !expand_string( wcsdup(tok_last( tok )),
|
|
||||||
args,
|
switch( expand_string( wcsdup(tok_last( tok )), args, 0 ) )
|
||||||
0 )
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
err_pos=tok_get_pos( tok );
|
case EXPAND_ERROR:
|
||||||
if( error_code == 0 )
|
|
||||||
{
|
{
|
||||||
error_arg( SYNTAX_ERROR,
|
err_pos=tok_get_pos( tok );
|
||||||
|
if( error_code == 0 )
|
||||||
|
{
|
||||||
|
error( SYNTAX_ERROR,
|
||||||
|
tok_get_pos( tok ),
|
||||||
L"Could not expand string",
|
L"Could not expand string",
|
||||||
tok_last(tok),
|
tok_last(tok) );
|
||||||
tok_get_pos( tok ) );
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case EXPAND_WILDCARD_NO_MATCH:
|
||||||
|
{
|
||||||
|
unmatched_wildcard = 1;
|
||||||
|
if( !unmatched )
|
||||||
|
{
|
||||||
|
unmatched = wcsdup(tok_last( tok ));
|
||||||
|
unmatched_pos = tok_get_pos( tok );
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case EXPAND_WILDCARD_MATCH:
|
||||||
|
{
|
||||||
|
matched_wildcard = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case EXPAND_OK:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -1102,27 +1154,27 @@ static void parse_job_main_loop( process_t *p,
|
|||||||
target = expand_one( wcsdup( tok_last( tok ) ), 0);
|
target = expand_one( wcsdup( tok_last( tok ) ), 0);
|
||||||
if( target == 0 && error_code == 0 )
|
if( target == 0 && error_code == 0 )
|
||||||
{
|
{
|
||||||
error_arg( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
L"Could not expand string",
|
tok_get_pos( tok ),
|
||||||
tok_last( tok ),
|
L"Could not expand string %ls",
|
||||||
tok_get_pos( tok ) );
|
tok_last( tok ) );
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error_arg( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
L"Expected redirection, got token of type",
|
tok_get_pos( tok ),
|
||||||
tok_get_desc( tok_last_type(tok)),
|
L"Expected redirection, got token of type %ls",
|
||||||
tok_get_pos( tok ) );
|
tok_get_desc( tok_last_type(tok)) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( target == 0 || wcslen( target )==0 )
|
if( target == 0 || wcslen( target )==0 )
|
||||||
{
|
{
|
||||||
if( error_code == 0 )
|
if( error_code == 0 )
|
||||||
error( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
L"Invalid IO redirection",
|
tok_get_pos( tok ),
|
||||||
tok_get_pos( tok ) );
|
L"Invalid IO redirection" );
|
||||||
tok_next(tok);
|
tok_next(tok);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1163,11 +1215,12 @@ static void parse_job_main_loop( process_t *p,
|
|||||||
if( ( new_io->param1.old_fd < 0 ) ||
|
if( ( new_io->param1.old_fd < 0 ) ||
|
||||||
( new_io->param1.old_fd > 10 ) )
|
( new_io->param1.old_fd > 10 ) )
|
||||||
{
|
{
|
||||||
error_arg( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
L"Requested redirection to something "
|
tok_get_pos( tok ),
|
||||||
L"that is not a file descriptor",
|
L"Requested redirection to something "
|
||||||
target,
|
L"that is not a file descriptor %ls",
|
||||||
tok_get_pos( tok ) );
|
target );
|
||||||
|
|
||||||
tok_next(tok);
|
tok_next(tok);
|
||||||
}
|
}
|
||||||
free(target);
|
free(target);
|
||||||
@@ -1183,19 +1236,20 @@ static void parse_job_main_loop( process_t *p,
|
|||||||
|
|
||||||
case TOK_ERROR:
|
case TOK_ERROR:
|
||||||
{
|
{
|
||||||
error_arg( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
TOK_ERR_MSG,
|
tok_get_pos( tok ),
|
||||||
tok_last(tok),
|
TOK_ERR_MSG,
|
||||||
tok_get_pos( tok ) );
|
tok_last(tok) );
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error_arg( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
L"Unexpected token of type",
|
tok_get_pos( tok ),
|
||||||
tok_get_desc( tok_last_type(tok)),
|
L"Unexpected token of type %ls",
|
||||||
tok_get_pos( tok ) );
|
tok_get_desc( tok_last_type(tok)) );
|
||||||
|
|
||||||
tok_next(tok);
|
tok_next(tok);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1205,6 +1259,30 @@ static void parse_job_main_loop( process_t *p,
|
|||||||
|
|
||||||
tok_next( tok );
|
tok_next( tok );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( !error_code )
|
||||||
|
{
|
||||||
|
if( unmatched_wildcard && !matched_wildcard )
|
||||||
|
{
|
||||||
|
j->wildcard_error = 1;
|
||||||
|
proc_set_last_status( 1 );
|
||||||
|
if( is_interactive && !is_block )
|
||||||
|
{
|
||||||
|
int tmp;
|
||||||
|
|
||||||
|
debug( 1, WILDCARD_ERR_MSG, unmatched );
|
||||||
|
tmp = current_tokenizer_pos;
|
||||||
|
current_tokenizer_pos = unmatched_pos;
|
||||||
|
|
||||||
|
fwprintf( stderr, L"%ls", parser_current_line() );
|
||||||
|
|
||||||
|
current_tokenizer_pos=tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free( unmatched );
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1240,39 +1318,45 @@ static int parse_job( process_t *p,
|
|||||||
switch( tok_last_type( tok ))
|
switch( tok_last_type( tok ))
|
||||||
{
|
{
|
||||||
case TOK_STRING:
|
case TOK_STRING:
|
||||||
|
{
|
||||||
nxt = expand_one( wcsdup(tok_last( tok )),
|
nxt = expand_one( wcsdup(tok_last( tok )),
|
||||||
EXPAND_SKIP_SUBSHELL | EXPAND_SKIP_VARIABLES);
|
EXPAND_SKIP_SUBSHELL | EXPAND_SKIP_VARIABLES);
|
||||||
if( nxt == 0 )
|
if( nxt == 0 )
|
||||||
{
|
{
|
||||||
error_arg( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
L"Illegal command name ",
|
tok_get_pos( tok ),
|
||||||
tok_last( tok ),
|
L"Illegal command name %ls",
|
||||||
tok_get_pos( tok ) );
|
tok_last( tok ) );
|
||||||
|
|
||||||
al_destroy( &args );
|
al_destroy( &args );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case TOK_ERROR:
|
case TOK_ERROR:
|
||||||
{
|
{
|
||||||
error_arg( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
TOK_ERR_MSG,
|
tok_get_pos( tok ),
|
||||||
tok_last(tok),
|
TOK_ERR_MSG,
|
||||||
tok_get_pos( tok ) );
|
tok_last(tok) );
|
||||||
|
|
||||||
al_destroy( &args );
|
al_destroy( &args );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error_arg( SYNTAX_ERROR,
|
{
|
||||||
L"Expected a command name, got token of type ",
|
error( SYNTAX_ERROR,
|
||||||
tok_get_desc( tok_last_type(tok)),
|
tok_get_pos( tok ),
|
||||||
tok_get_pos( tok ) );
|
L"Expected a command name, got token of type %ls",
|
||||||
|
tok_get_desc( tok_last_type(tok) ) );
|
||||||
|
|
||||||
al_destroy( &args );
|
al_destroy( &args );
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int mark = tok_get_pos( tok );
|
int mark = tok_get_pos( tok );
|
||||||
|
|
||||||
if( wcscmp( L"command", nxt )==0 )
|
if( wcscmp( L"command", nxt )==0 )
|
||||||
@@ -1351,8 +1435,8 @@ static int parse_job( process_t *p,
|
|||||||
if( p != j->first_process )
|
if( p != j->first_process )
|
||||||
{
|
{
|
||||||
error( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
EXEC_ERR_MSG,
|
tok_get_pos( tok ),
|
||||||
tok_get_pos( tok ) );
|
EXEC_ERR_MSG );
|
||||||
al_destroy( &args );
|
al_destroy( &args );
|
||||||
free(nxt);
|
free(nxt);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1377,7 +1461,7 @@ static int parse_job( process_t *p,
|
|||||||
int new_block = 0;
|
int new_block = 0;
|
||||||
tok_next( tok );
|
tok_next( tok );
|
||||||
|
|
||||||
if( (current_block->type != WHILE) )
|
if( ( current_block->type != WHILE ) )
|
||||||
{
|
{
|
||||||
new_block = 1;
|
new_block = 1;
|
||||||
}
|
}
|
||||||
@@ -1436,8 +1520,8 @@ static int parse_job( process_t *p,
|
|||||||
if( al_get_count( &forbidden_function ) > MAX_RECURSION_DEPTH )
|
if( al_get_count( &forbidden_function ) > MAX_RECURSION_DEPTH )
|
||||||
{
|
{
|
||||||
error( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
RECURSION_ERR_MSG,
|
tok_get_pos( tok ),
|
||||||
tok_get_pos( tok ) );
|
RECURSION_ERR_MSG );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1507,10 +1591,23 @@ static int parse_job( process_t *p,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error_arg( EVAL_ERROR,
|
if( wcschr( (wchar_t *)al_get( &args, 0 ), L'=' ) )
|
||||||
L"Unknown command",
|
{
|
||||||
(wchar_t *)al_get( &args, 0 ),
|
error( EVAL_ERROR,
|
||||||
tok_get_pos( tok ) );
|
tok_get_pos( tok ),
|
||||||
|
COMMAND_ASSIGN_ERR_MSG,
|
||||||
|
(wchar_t *)al_get( &args, 0 ) );
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error( EVAL_ERROR,
|
||||||
|
tok_get_pos( tok ),
|
||||||
|
L"Unknown command %ls",
|
||||||
|
(wchar_t *)al_get( &args, 0 ) );
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1527,8 +1624,8 @@ static int parse_job( process_t *p,
|
|||||||
if( !end )
|
if( !end )
|
||||||
{
|
{
|
||||||
error( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
L"Could not find end of block" ,
|
tok_get_pos( tok ),
|
||||||
tok_get_pos( tok ) );
|
L"Could not find end of block" );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !make_sub_block )
|
if( !make_sub_block )
|
||||||
@@ -1552,8 +1649,8 @@ static int parse_job( process_t *p,
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
error( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
BLOCK_END_ERR_MSG,
|
current_tokenizer_pos,
|
||||||
current_tokenizer_pos );
|
BLOCK_END_ERR_MSG );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tok_destroy( &subtok );
|
tok_destroy( &subtok );
|
||||||
@@ -1609,7 +1706,6 @@ static int parse_job( process_t *p,
|
|||||||
*/
|
*/
|
||||||
while( prev_block != current_block )
|
while( prev_block != current_block )
|
||||||
parser_pop_block();
|
parser_pop_block();
|
||||||
|
|
||||||
}
|
}
|
||||||
al_destroy( &args );
|
al_destroy( &args );
|
||||||
|
|
||||||
@@ -1628,9 +1724,10 @@ static int parse_job( process_t *p,
|
|||||||
static void skipped_exec( job_t * j )
|
static void skipped_exec( job_t * j )
|
||||||
{
|
{
|
||||||
process_t *p;
|
process_t *p;
|
||||||
|
|
||||||
for( p = j->first_process; p; p=p->next )
|
for( p = j->first_process; p; p=p->next )
|
||||||
{
|
{
|
||||||
if( p->type )
|
if( p->type == INTERNAL_BUILTIN )
|
||||||
{
|
{
|
||||||
if(( wcscmp( p->argv[0], L"for" )==0) ||
|
if(( wcscmp( p->argv[0], L"for" )==0) ||
|
||||||
( wcscmp( p->argv[0], L"switch" )==0) ||
|
( wcscmp( p->argv[0], L"switch" )==0) ||
|
||||||
@@ -1707,7 +1804,6 @@ static void eval_job( tokenizer *tok )
|
|||||||
|
|
||||||
current_block->job = j;
|
current_block->job = j;
|
||||||
|
|
||||||
proc_had_barrier=0;
|
|
||||||
|
|
||||||
if( is_interactive )
|
if( is_interactive )
|
||||||
{
|
{
|
||||||
@@ -1760,10 +1856,19 @@ static void eval_job( tokenizer *tok )
|
|||||||
}
|
}
|
||||||
|
|
||||||
skip |= current_block->skip;
|
skip |= current_block->skip;
|
||||||
|
skip |= j->wildcard_error;
|
||||||
|
|
||||||
if(!skip )
|
if(!skip )
|
||||||
{
|
{
|
||||||
|
int was_builtin = 0;
|
||||||
|
// if( j->first_process->type==INTERNAL_BUILTIN && !j->first_process->next)
|
||||||
|
// was_builtin = 1;
|
||||||
|
|
||||||
exec( j );
|
exec( j );
|
||||||
|
|
||||||
|
/* Only external commands require a new fishd barrier */
|
||||||
|
if( !was_builtin )
|
||||||
|
proc_had_barrier=0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1806,9 +1911,11 @@ static void eval_job( tokenizer *tok )
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
This job could not be properly parsed. We free it instead.
|
This job could not be properly parsed. We free it instead, and set the status to 1.
|
||||||
*/
|
*/
|
||||||
job_free( j );
|
job_free( j );
|
||||||
|
|
||||||
|
proc_set_last_status( 1 );
|
||||||
}
|
}
|
||||||
current_block->job = 0;
|
current_block->job = 0;
|
||||||
break;
|
break;
|
||||||
@@ -1823,21 +1930,21 @@ static void eval_job( tokenizer *tok )
|
|||||||
|
|
||||||
case TOK_ERROR:
|
case TOK_ERROR:
|
||||||
{
|
{
|
||||||
error_arg( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
TOK_ERR_MSG,
|
tok_get_pos( tok ),
|
||||||
tok_last(tok),
|
TOK_ERR_MSG,
|
||||||
tok_get_pos( tok ) );
|
tok_last(tok) );
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
error_arg( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
L"Expected a command string, got token of type",
|
tok_get_pos( tok ),
|
||||||
tok_get_desc( tok_last_type(tok)),
|
L"Expected a command string, got token of type %ls",
|
||||||
tok_get_pos( tok ) );
|
tok_get_desc( tok_last_type(tok)) );
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2019,8 +2126,9 @@ int parser_test( wchar_t * buff,
|
|||||||
if( babble )
|
if( babble )
|
||||||
{
|
{
|
||||||
error( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
COND_ERR_MSG,
|
tok_get_pos( &tok ),
|
||||||
tok_get_pos( &tok ) );
|
COND_ERR_MSG );
|
||||||
|
|
||||||
print_errors();
|
print_errors();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2045,7 +2153,10 @@ int parser_test( wchar_t * buff,
|
|||||||
{
|
{
|
||||||
if( count >= BLOCK_MAX_COUNT )
|
if( count >= BLOCK_MAX_COUNT )
|
||||||
{
|
{
|
||||||
error( SYNTAX_ERROR, BLOCK_ERR_MSG, tok_get_pos( &tok ) );
|
error( SYNTAX_ERROR,
|
||||||
|
tok_get_pos( &tok ),
|
||||||
|
BLOCK_ERR_MSG );
|
||||||
|
|
||||||
print_errors();
|
print_errors();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2101,8 +2212,9 @@ int parser_test( wchar_t * buff,
|
|||||||
if( babble )
|
if( babble )
|
||||||
{
|
{
|
||||||
error( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
EXEC_ERR_MSG,
|
tok_get_pos( &tok ),
|
||||||
tok_get_pos( &tok ) );
|
EXEC_ERR_MSG );
|
||||||
|
|
||||||
print_errors();
|
print_errors();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2123,8 +2235,9 @@ int parser_test( wchar_t * buff,
|
|||||||
if( babble )
|
if( babble )
|
||||||
{
|
{
|
||||||
error( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
EXEC_ERR_MSG,
|
tok_get_pos( &tok ),
|
||||||
tok_get_pos( &tok ) );
|
EXEC_ERR_MSG );
|
||||||
|
|
||||||
print_errors();
|
print_errors();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2147,8 +2260,9 @@ int parser_test( wchar_t * buff,
|
|||||||
if( babble )
|
if( babble )
|
||||||
{
|
{
|
||||||
error( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
L"'case' builtin not inside of switch block",
|
tok_get_pos( &tok ),
|
||||||
tok_get_pos( &tok ) );
|
L"'case' builtin not inside of switch block" );
|
||||||
|
|
||||||
print_errors();
|
print_errors();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2179,9 +2293,9 @@ int parser_test( wchar_t * buff,
|
|||||||
if( babble )
|
if( babble )
|
||||||
{
|
{
|
||||||
error( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
L"Loop control command while not inside of loop",
|
tok_get_pos( &tok ),
|
||||||
tok_get_pos( &tok ) );
|
L"Loop control command while not inside of loop" );
|
||||||
print_errors();
|
print_errors();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2197,9 +2311,9 @@ int parser_test( wchar_t * buff,
|
|||||||
if( babble )
|
if( babble )
|
||||||
{
|
{
|
||||||
error( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
L"'else' builtin not inside of if block",
|
tok_get_pos( &tok ),
|
||||||
tok_get_pos( &tok ) );
|
L"'else' builtin not inside of if block" );
|
||||||
print_errors();
|
print_errors();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2214,8 +2328,8 @@ int parser_test( wchar_t * buff,
|
|||||||
if( babble )
|
if( babble )
|
||||||
{
|
{
|
||||||
error( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
L"'end' command outside of block",
|
tok_get_pos( &tok ),
|
||||||
tok_get_pos( &tok ) );
|
L"'end' command outside of block" );
|
||||||
print_errors();
|
print_errors();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2234,8 +2348,8 @@ int parser_test( wchar_t * buff,
|
|||||||
if( babble )
|
if( babble )
|
||||||
{
|
{
|
||||||
error( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
L"Redirection error",
|
tok_get_pos( &tok ),
|
||||||
tok_get_pos( &tok ) );
|
L"Redirection error" );
|
||||||
print_errors();
|
print_errors();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2250,9 +2364,9 @@ int parser_test( wchar_t * buff,
|
|||||||
if( babble )
|
if( babble )
|
||||||
{
|
{
|
||||||
error( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
CMD_ERR_MSG,
|
tok_get_pos( &tok ),
|
||||||
tok_get_pos( &tok ) );
|
CMD_ERR_MSG );
|
||||||
print_errors();
|
print_errors();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
needs_cmd=0;
|
needs_cmd=0;
|
||||||
@@ -2270,8 +2384,9 @@ int parser_test( wchar_t * buff,
|
|||||||
if( babble )
|
if( babble )
|
||||||
{
|
{
|
||||||
error( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
EXEC_ERR_MSG,
|
tok_get_pos( &tok ),
|
||||||
tok_get_pos( &tok ) );
|
EXEC_ERR_MSG );
|
||||||
|
|
||||||
print_errors();
|
print_errors();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2288,8 +2403,9 @@ int parser_test( wchar_t * buff,
|
|||||||
if( babble )
|
if( babble )
|
||||||
{
|
{
|
||||||
error( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
CMD_ERR_MSG,
|
tok_get_pos( &tok ),
|
||||||
tok_get_pos( &tok ) );
|
CMD_ERR_MSG );
|
||||||
|
|
||||||
print_errors();
|
print_errors();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2306,10 +2422,12 @@ int parser_test( wchar_t * buff,
|
|||||||
err = 1;
|
err = 1;
|
||||||
if( babble )
|
if( babble )
|
||||||
{
|
{
|
||||||
error_arg( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
TOK_ERR_MSG,
|
tok_get_pos( &tok ),
|
||||||
tok_last(&tok),
|
TOK_ERR_MSG,
|
||||||
tok_get_pos( &tok ) );
|
tok_last(&tok) );
|
||||||
|
|
||||||
|
|
||||||
print_errors();
|
print_errors();
|
||||||
//debug( 2, tok_last( &tok) );
|
//debug( 2, tok_last( &tok) );
|
||||||
}
|
}
|
||||||
@@ -2323,8 +2441,9 @@ int parser_test( wchar_t * buff,
|
|||||||
if( babble )
|
if( babble )
|
||||||
{
|
{
|
||||||
error( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
COND_ERR_MSG,
|
tok_get_pos( &tok ),
|
||||||
tok_get_pos( &tok ) );
|
COND_ERR_MSG );
|
||||||
|
|
||||||
print_errors();
|
print_errors();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2333,8 +2452,8 @@ int parser_test( wchar_t * buff,
|
|||||||
if( babble && count>0 )
|
if( babble && count>0 )
|
||||||
{
|
{
|
||||||
error( SYNTAX_ERROR,
|
error( SYNTAX_ERROR,
|
||||||
END_ERR_MSG L"\n",
|
block_pos[count-1],
|
||||||
block_pos[count-1] );
|
END_ERR_MSG );
|
||||||
print_errors();
|
print_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
29
parser.h
29
parser.h
@@ -125,12 +125,34 @@ enum while_status
|
|||||||
*/
|
*/
|
||||||
enum parser_error
|
enum parser_error
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
No error
|
||||||
|
*/
|
||||||
NO_ERR=0,
|
NO_ERR=0,
|
||||||
|
/**
|
||||||
|
An error in the syntax
|
||||||
|
*/
|
||||||
SYNTAX_ERROR,
|
SYNTAX_ERROR,
|
||||||
|
/**
|
||||||
|
Error occured while evaluating commands
|
||||||
|
*/
|
||||||
EVAL_ERROR,
|
EVAL_ERROR,
|
||||||
|
/**
|
||||||
|
Out of memory error
|
||||||
|
*/
|
||||||
OOM,
|
OOM,
|
||||||
|
/**
|
||||||
|
Stack inconsistency error
|
||||||
|
*/
|
||||||
STACK_ERROR,
|
STACK_ERROR,
|
||||||
SUBSHELL_ERROR
|
/**
|
||||||
|
Error while evaluating subshell
|
||||||
|
*/
|
||||||
|
SUBSHELL_ERROR,
|
||||||
|
/**
|
||||||
|
No files matching wildcards where found
|
||||||
|
*/
|
||||||
|
WILDCARD_ERROR
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -178,10 +200,11 @@ int eval_args( const wchar_t *line,
|
|||||||
Sets the current error
|
Sets the current error
|
||||||
|
|
||||||
\param ec The new error code
|
\param ec The new error code
|
||||||
\param str The new error message
|
|
||||||
\param p The character offset at which the error occured
|
\param p The character offset at which the error occured
|
||||||
|
\param str The printf-style error message filter
|
||||||
*/
|
*/
|
||||||
void error( int ec, const wchar_t *str, int p );
|
void error( int ec, int p, const wchar_t *str, ... );
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Tests if the specified commands parameters should be interpreted as another command, which will be true if the command is either 'command', 'exec', 'if', 'while' or 'builtin'.
|
Tests if the specified commands parameters should be interpreted as another command, which will be true if the command is either 'command', 'exec', 'if', 'while' or 'builtin'.
|
||||||
|
|||||||
11
proc.c
11
proc.c
@@ -482,12 +482,9 @@ static void format_job_info( const job_t *j, const wchar_t *status )
|
|||||||
fwprintf (stdout, L"\n" );
|
fwprintf (stdout, L"\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fire_process_event( const wchar_t *msg, int type, pid_t pid, int status )
|
void proc_fire_event( const wchar_t *msg, int type, pid_t pid, int status )
|
||||||
{
|
{
|
||||||
static event_t ev;
|
static event_t ev;
|
||||||
event_t e;
|
|
||||||
|
|
||||||
e.function_name=0;
|
|
||||||
|
|
||||||
ev.type=type;
|
ev.type=type;
|
||||||
ev.param1.pid = pid;
|
ev.param1.pid = pid;
|
||||||
@@ -538,7 +535,7 @@ int job_reap( int interactive )
|
|||||||
|
|
||||||
s = p->status;
|
s = p->status;
|
||||||
|
|
||||||
fire_process_event( L"PROCESS_EXIT", EVENT_EXIT, p->pid, ( WIFSIGNALED(s)?-1:WEXITSTATUS( s )) );
|
proc_fire_event( L"PROCESS_EXIT", EVENT_EXIT, p->pid, ( WIFSIGNALED(s)?-1:WEXITSTATUS( s )) );
|
||||||
|
|
||||||
if( WIFSIGNALED(s) )
|
if( WIFSIGNALED(s) )
|
||||||
{
|
{
|
||||||
@@ -596,8 +593,8 @@ int job_reap( int interactive )
|
|||||||
found=1;
|
found=1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fire_process_event( L"JOB_EXIT", EVENT_EXIT, -j->pgid, 0 );
|
proc_fire_event( L"JOB_EXIT", EVENT_EXIT, -j->pgid, 0 );
|
||||||
fire_process_event( L"JOB_EXIT", EVENT_JOB_ID, j->job_id, 0 );
|
proc_fire_event( L"JOB_EXIT", EVENT_JOB_ID, j->job_id, 0 );
|
||||||
|
|
||||||
job_free(j);
|
job_free(j);
|
||||||
}
|
}
|
||||||
|
|||||||
8
proc.h
8
proc.h
@@ -134,6 +134,9 @@ typedef struct job
|
|||||||
/** Should the exit status be negated? This flag can only be set by the not builtin. */
|
/** Should the exit status be negated? This flag can only be set by the not builtin. */
|
||||||
int negate;
|
int negate;
|
||||||
|
|
||||||
|
/** This flag is set to one on wildcard expansion errors. It means that the current command should not be executed */
|
||||||
|
int wildcard_error;
|
||||||
|
|
||||||
/** Pointer to the next job */
|
/** Pointer to the next job */
|
||||||
struct job *next;
|
struct job *next;
|
||||||
}
|
}
|
||||||
@@ -254,6 +257,11 @@ void proc_update_jiffies();
|
|||||||
*/
|
*/
|
||||||
void proc_sanity_check();
|
void proc_sanity_check();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Send of an process/job exit event notification. This function is a conveniance wrapper around event_fire().
|
||||||
|
*/
|
||||||
|
void proc_fire_event( const wchar_t *msg, int type, pid_t pid, int status );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Initializations
|
Initializations
|
||||||
*/
|
*/
|
||||||
|
|||||||
40
reader.c
40
reader.c
@@ -1093,7 +1093,7 @@ static wchar_t get_quote( wchar_t *cmd, int l )
|
|||||||
\param pos An index in the string which is inside the parameter
|
\param pos An index in the string which is inside the parameter
|
||||||
\param quote If not 0, store the type of quote this parameter has, can be either ', " or \\0, meaning the string is not quoted.
|
\param quote If not 0, store the type of quote this parameter has, can be either ', " or \\0, meaning the string is not quoted.
|
||||||
\param offset If not 0, get_param will store a pointer to the beginning of the parameter.
|
\param offset If not 0, get_param will store a pointer to the beginning of the parameter.
|
||||||
\param string If not o, get_parm will store a copy of the parameter string as returned by the tokenizer.
|
\param string If not 0, get_parm will store a copy of the parameter string as returned by the tokenizer.
|
||||||
\param type If not 0, get_param will store the token type as returned by tok_last.
|
\param type If not 0, get_param will store the token type as returned by tok_last.
|
||||||
*/
|
*/
|
||||||
static void get_param( wchar_t *cmd,
|
static void get_param( wchar_t *cmd,
|
||||||
@@ -1123,6 +1123,7 @@ static void get_param( wchar_t *cmd,
|
|||||||
*type = tok_last_type( &tok );
|
*type = tok_last_type( &tok );
|
||||||
if( string != 0 )
|
if( string != 0 )
|
||||||
wcscpy( *string, tok_last( &tok ) );
|
wcscpy( *string, tok_last( &tok ) );
|
||||||
|
|
||||||
prev_pos = tok_get_pos( &tok );
|
prev_pos = tok_get_pos( &tok );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1381,13 +1382,12 @@ static int handle_completions( array_list_t *comp )
|
|||||||
0,
|
0,
|
||||||
0 );
|
0 );
|
||||||
|
|
||||||
|
len = &data->buff[data->buff_pos]-prefix_start+1;
|
||||||
len = &data->buff[data->buff_pos]-prefix_start;
|
|
||||||
|
|
||||||
if( len <= PREFIX_MAX_LEN )
|
if( len <= PREFIX_MAX_LEN )
|
||||||
{
|
{
|
||||||
prefix = malloc( sizeof(wchar_t)*(len+1) );
|
prefix = malloc( sizeof(wchar_t)*(len+1) );
|
||||||
wcsncpy( prefix, prefix_start, len );
|
wcslcpy( prefix, prefix_start, len );
|
||||||
prefix[len]=L'\0';
|
prefix[len]=L'\0';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1400,7 +1400,9 @@ static int handle_completions( array_list_t *comp )
|
|||||||
;
|
;
|
||||||
|
|
||||||
prefix = wcsdupcat( tmp,
|
prefix = wcsdupcat( tmp,
|
||||||
prefix_start + (len - PREFIX_MAX_LEN+1) );
|
prefix_start + (len - PREFIX_MAX_LEN) );
|
||||||
|
prefix[PREFIX_MAX_LEN] = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -2347,21 +2349,13 @@ static int read_i()
|
|||||||
that we can handle a call to reader_set_buffer
|
that we can handle a call to reader_set_buffer
|
||||||
during evaluation.
|
during evaluation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
tmp = wcsdup( reader_readline() );
|
tmp = wcsdup( reader_readline() );
|
||||||
|
|
||||||
data->buff_pos=data->buff_len=0;
|
data->buff_pos=data->buff_len=0;
|
||||||
data->buff[data->buff_len]=L'\0';
|
data->buff[data->buff_len]=L'\0';
|
||||||
if( function_exists(L"fish_on_exec"))
|
|
||||||
{
|
|
||||||
eval( L"fish_on_exec", 0, TOP );
|
|
||||||
}
|
|
||||||
reader_run_command( tmp );
|
reader_run_command( tmp );
|
||||||
free( tmp );
|
free( tmp );
|
||||||
if( function_exists(L"fish_on_return"))
|
|
||||||
{
|
|
||||||
eval( L"fish_on_return", 0, TOP );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( data->end_loop)
|
if( data->end_loop)
|
||||||
{
|
{
|
||||||
@@ -2405,7 +2399,6 @@ static int can_read( int fd )
|
|||||||
static int wchar_private( wchar_t c )
|
static int wchar_private( wchar_t c )
|
||||||
{
|
{
|
||||||
return ( (c >= 0xe000) && (c <= 0xf8ff ) );
|
return ( (c >= 0xe000) && (c <= 0xf8ff ) );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wchar_t *reader_readline()
|
wchar_t *reader_readline()
|
||||||
@@ -2593,10 +2586,13 @@ wchar_t *reader_readline()
|
|||||||
|
|
||||||
case R_BACKWARD_KILL_LINE:
|
case R_BACKWARD_KILL_LINE:
|
||||||
{
|
{
|
||||||
wchar_t prev = data->buff[data->buff_pos];
|
wchar_t *str = wcsndup( data->buff, data->buff_pos );
|
||||||
data->buff[data->buff_pos]=0;
|
if( !str )
|
||||||
kill_add( data->buff );
|
die_mem();
|
||||||
data->buff[data->buff_pos]=prev;
|
|
||||||
|
kill_add( str );
|
||||||
|
free( str );
|
||||||
|
|
||||||
data->buff_len = wcslen(data->buff +data->buff_pos);
|
data->buff_len = wcslen(data->buff +data->buff_pos);
|
||||||
memmove( data->buff, data->buff +data->buff_pos, sizeof(wchar_t)*data->buff_len );
|
memmove( data->buff, data->buff +data->buff_pos, sizeof(wchar_t)*data->buff_len );
|
||||||
data->buff[data->buff_len]=L'\0';
|
data->buff[data->buff_len]=L'\0';
|
||||||
@@ -2761,8 +2757,8 @@ wchar_t *reader_readline()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Move left*/
|
/* Move left*/
|
||||||
case R_BACKWARD_CHAR:
|
case R_BACKWARD_CHAR:
|
||||||
if( data->buff_pos > 0 )
|
if( data->buff_pos > 0 )
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ int main( int argc, char **argv )
|
|||||||
|
|
||||||
while( 1 )
|
while( 1 )
|
||||||
{
|
{
|
||||||
#ifdef __GLIBC__
|
#ifdef HAVE_GETOPT_LONG
|
||||||
static struct option
|
static struct option
|
||||||
long_options[] =
|
long_options[] =
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ int main( int argc, char **argv )
|
|||||||
|
|
||||||
while( 1 )
|
while( 1 )
|
||||||
{
|
{
|
||||||
#ifdef __GLIBC__
|
#ifdef HAVE_GETOPT_LONG
|
||||||
static struct option
|
static struct option
|
||||||
long_options[] =
|
long_options[] =
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
|
|
|
|
||||||
<a class="qindex" href="index.html">Main documentation page</a>
|
<a class="qindex" href="index.html">Main documentation page</a>
|
||||||
|
|
|
|
||||||
|
<a class="qindex" href="design.html">Design document</a>
|
||||||
|
|
|
||||||
<a class="qindex" href="about.html">About fish</a>
|
<a class="qindex" href="about.html">About fish</a>
|
||||||
|
|
|
|
||||||
<a class="qindex" href="commands.html">External commands</a>
|
<a class="qindex" href="commands.html">External commands</a>
|
||||||
|
|||||||
18
wgetopt.c
18
wgetopt.c
@@ -7,12 +7,18 @@
|
|||||||
internal commands use wide characters and hence this library is
|
internal commands use wide characters and hence this library is
|
||||||
useful.
|
useful.
|
||||||
|
|
||||||
If you want to use this version of getopt in your program, simply
|
If you want to use this version of getopt in your program,
|
||||||
copy wgetopt.c and wgetopt.h into your program, include wgetopt.h,
|
download the fish sourcecode, available at <a
|
||||||
and use all the regular getopt functions, prefixing every
|
href='http://roo.no-ip.org/fish/'>the fish homepage</a>. Extract
|
||||||
function, global variable and structure with a 'w', and use only
|
the sourcode, copy wgetopt.c and wgetopt.h into your program
|
||||||
wide character strings. There are no other functional changes in
|
directory, include wgetopt.h in your program, and use all the
|
||||||
this version of getopt besides using wide character strings.
|
regular getopt functions, prefixing every function, global
|
||||||
|
variable and structure with a 'w', and use only wide character
|
||||||
|
strings. There are no other functional changes in this version of
|
||||||
|
getopt besides using wide character strings.
|
||||||
|
|
||||||
|
For examples of how to use wgetopt, see the fish builtin
|
||||||
|
functions, many of which are defined in builtin.c.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
18
wgetopt.h
18
wgetopt.h
@@ -7,12 +7,18 @@
|
|||||||
internal commands use wide characters and hence this library is
|
internal commands use wide characters and hence this library is
|
||||||
useful.
|
useful.
|
||||||
|
|
||||||
If you want to use this version of getopt in your program, simply
|
If you want to use this version of getopt in your program,
|
||||||
copy wgetopt.c and wgetopt.h into your program, include wgetopt.h,
|
download the fish sourcecode, available at <a
|
||||||
and use all the regular getopt functions, prefixing every
|
href='http://roo.no-ip.org/fish/'>the fish homepage</a>. Extract
|
||||||
function, global variable and structure with a 'w', and use only
|
the sourcode, copy wgetopt.c and wgetopt.h into your program
|
||||||
wide character strings. There are no other functional changes in
|
directory, include wgetopt.h in your program, and use all the
|
||||||
this version of getopt besides using wide character strings.
|
regular getopt functions, prefixing every function, global
|
||||||
|
variable and structure with a 'w', and use only wide character
|
||||||
|
strings. There are no other functional changes in this version of
|
||||||
|
getopt besides using wide character strings.
|
||||||
|
|
||||||
|
For examples of how to use wgetopt, see the fish builtin
|
||||||
|
functions, many of which are defined in builtin.c.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
331
wildcard.c
331
wildcard.c
@@ -1,6 +1,8 @@
|
|||||||
/** \file wildcard.c
|
/** \file wildcard.c
|
||||||
My own globbing implementation. Needed to implement this to
|
|
||||||
support tab-expansion of globbed parameters.
|
Fish needs it's own globbing implementation to support
|
||||||
|
tab-expansion of globbed parameters. Also provides recursive
|
||||||
|
wildcards using **.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -25,6 +27,19 @@
|
|||||||
#include "reader.h"
|
#include "reader.h"
|
||||||
#include "expand.h"
|
#include "expand.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
This flag is set in the flags parameter of wildcard_expand if the
|
||||||
|
call is part of a recursiv wildcard search. It is used to make sure
|
||||||
|
that the contents of subdirectories are only searched once.
|
||||||
|
*/
|
||||||
|
#define WILDCARD_RECURSIVE 64
|
||||||
|
|
||||||
|
/**
|
||||||
|
The maximum length of a filename token. This is a fallback value,
|
||||||
|
an attempt to find the true value using patchconf is always made.
|
||||||
|
*/
|
||||||
|
#define MAX_FILE_LENGTH 1024
|
||||||
|
|
||||||
int wildcard_has( const wchar_t *str, int internal )
|
int wildcard_has( const wchar_t *str, int internal )
|
||||||
{
|
{
|
||||||
wchar_t prev=0;
|
wchar_t prev=0;
|
||||||
@@ -55,7 +70,7 @@ int wildcard_has( const wchar_t *str, int internal )
|
|||||||
|
|
||||||
\param str String to be matched.
|
\param str String to be matched.
|
||||||
\param wc The wildcard.
|
\param wc The wildcard.
|
||||||
\param is_first Whether files beginning with dots should not be matched against wildcards.
|
\param is_first Whether files beginning with dots should not be matched against wildcards.
|
||||||
\param wc_unescaped Whether the unescaped special character ANY_CHAR abd ANY_STRING should be used instead of '?' and '*' for wildcard matching
|
\param wc_unescaped Whether the unescaped special character ANY_CHAR abd ANY_STRING should be used instead of '?' and '*' for wildcard matching
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -72,7 +87,9 @@ static int wildcard_match2( const wchar_t *str,
|
|||||||
{
|
{
|
||||||
/* Ignore hidden file */
|
/* Ignore hidden file */
|
||||||
if( is_first && *str == L'.' )
|
if( is_first && *str == L'.' )
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Try all submatches */
|
/* Try all submatches */
|
||||||
do
|
do
|
||||||
@@ -83,8 +100,16 @@ static int wildcard_match2( const wchar_t *str,
|
|||||||
while( *(str++) != 0 );
|
while( *(str++) != 0 );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( *wc == ANY_CHAR )
|
if( *wc == ANY_CHAR )
|
||||||
|
{
|
||||||
|
if( is_first && *str == L'.' )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return wildcard_match2( str+1, wc+1, 0 );
|
return wildcard_match2( str+1, wc+1, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
if( *wc == *str )
|
if( *wc == *str )
|
||||||
return wildcard_match2( str+1, wc+1, 0 );
|
return wildcard_match2( str+1, wc+1, 0 );
|
||||||
@@ -205,15 +230,13 @@ static wchar_t *make_path( const wchar_t *base_dir, const wchar_t *name )
|
|||||||
int base_len = wcslen( base_dir );
|
int base_len = wcslen( base_dir );
|
||||||
if( !(long_name= malloc( sizeof(wchar_t)*(base_len+wcslen(name)+1) )))
|
if( !(long_name= malloc( sizeof(wchar_t)*(base_len+wcslen(name)+1) )))
|
||||||
{
|
{
|
||||||
|
die_mem();
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
wcscpy( long_name, base_dir );
|
wcscpy( long_name, base_dir );
|
||||||
wcscpy(&long_name[base_len], name );
|
wcscpy(&long_name[base_len], name );
|
||||||
return long_name;
|
return long_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void get_desc( wchar_t *fn, string_buffer_t *sb, int is_cmd )
|
void get_desc( wchar_t *fn, string_buffer_t *sb, int is_cmd )
|
||||||
{
|
{
|
||||||
const wchar_t *desc;
|
const wchar_t *desc;
|
||||||
@@ -282,6 +305,11 @@ void get_desc( wchar_t *fn, string_buffer_t *sb, int is_cmd )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Test if the file specified by the given filename matches the
|
||||||
|
expansion flags specified. flags can be a combination of
|
||||||
|
EXECUTABLES_ONLY and DIRECTORIES_ONLY.
|
||||||
|
*/
|
||||||
static int test_flags( wchar_t *filename,
|
static int test_flags( wchar_t *filename,
|
||||||
int flags )
|
int flags )
|
||||||
{
|
{
|
||||||
@@ -306,11 +334,37 @@ int wildcard_expand( const wchar_t *wc,
|
|||||||
int flags,
|
int flags,
|
||||||
array_list_t *out )
|
array_list_t *out )
|
||||||
{
|
{
|
||||||
// debug( 3, L"WILDCARD_EXPAND %ls in %ls", wc, base_dir );
|
|
||||||
|
/* Points to the end of the current wildcard segment */
|
||||||
|
wchar_t *wc_end;
|
||||||
|
|
||||||
|
/* Variables for traversing a directory */
|
||||||
|
struct dirent *next;
|
||||||
|
DIR *dir;
|
||||||
|
|
||||||
|
/* The result returned */
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
/* Length of the directory to search in */
|
||||||
|
int base_len;
|
||||||
|
|
||||||
|
/* Variables for testing for presense of recursive wildcards */
|
||||||
|
wchar_t *wc_recursive;
|
||||||
|
int is_recursive;
|
||||||
|
|
||||||
|
/* Sligtly mangled version of base_dir */
|
||||||
|
const wchar_t *dir_string;
|
||||||
|
|
||||||
|
/* Description for completions */
|
||||||
|
string_buffer_t sb_desc;
|
||||||
|
|
||||||
|
// debug( 3, L"WILDCARD_EXPAND %ls in %ls", wc, base_dir );
|
||||||
|
|
||||||
if( flags & ACCEPT_INCOMPLETE )
|
if( flags & ACCEPT_INCOMPLETE )
|
||||||
{
|
{
|
||||||
/* Avoid excessive number of returned matches for wc ending with a * */
|
/*
|
||||||
|
Avoid excessive number of returned matches for wc ending with a *
|
||||||
|
*/
|
||||||
int len = wcslen(wc);
|
int len = wcslen(wc);
|
||||||
if( len && (wc[len-1]==ANY_STRING) )
|
if( len && (wc[len-1]==ANY_STRING) )
|
||||||
{
|
{
|
||||||
@@ -321,50 +375,58 @@ int wildcard_expand( const wchar_t *wc,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dirent *next;
|
|
||||||
wchar_t *wc_end = wcschr(wc,L'/');
|
|
||||||
DIR *dir;
|
|
||||||
|
|
||||||
int res = 0;
|
|
||||||
int base_len = wcslen( base_dir );
|
|
||||||
|
|
||||||
wchar_t *wc_recursive = wcschr( wc, ANY_STRING_RECURSIVE );
|
/*
|
||||||
int is_recursive = is_recursive = ( wc_recursive && (!wc_end || wc_recursive < wc_end));
|
Initialize various variables
|
||||||
|
*/
|
||||||
|
|
||||||
const wchar_t *dir_string = base_dir[0]==L'\0'?L".":base_dir;
|
dir_string = base_dir[0]==L'\0'?L".":base_dir;
|
||||||
|
|
||||||
string_buffer_t sb_desc;
|
|
||||||
|
|
||||||
sb_init( &sb_desc );
|
|
||||||
// if( accept_incomplete )
|
|
||||||
// wprintf( L"Glob %ls in '%ls'\n", wc, base_dir );//[0]==L'\0'?L".":base_dir );
|
|
||||||
|
|
||||||
/*
|
|
||||||
Test for recursive match string in current segment
|
|
||||||
*/
|
|
||||||
|
|
||||||
if( !(dir = wopendir( dir_string )))
|
if( !(dir = wopendir( dir_string )))
|
||||||
{
|
{
|
||||||
// if( errno != EACCES && errno != ENOENT )
|
|
||||||
// wperror( L"opendir" );
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
wc_end = wcschr(wc,L'/');
|
||||||
Is this segment of the wildcard the last?
|
base_len = wcslen( base_dir );
|
||||||
*/
|
|
||||||
if( wc_end == 0 )
|
/*
|
||||||
|
Test for recursive match string in current segment
|
||||||
|
*/
|
||||||
|
wc_recursive = wcschr( wc, ANY_STRING_RECURSIVE );
|
||||||
|
is_recursive = ( wc_recursive && (!wc_end || wc_recursive < wc_end));
|
||||||
|
|
||||||
|
/*
|
||||||
|
This makes sure that the base
|
||||||
|
directory of the recursive search is
|
||||||
|
also searched for matching files.
|
||||||
|
*/
|
||||||
|
if( is_recursive && (wc_end==(wc+1)) && !(flags & WILDCARD_RECURSIVE ) )
|
||||||
|
{
|
||||||
|
wildcard_expand( wc_end + 1,
|
||||||
|
base_dir,
|
||||||
|
flags,
|
||||||
|
out );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( flags & ACCEPT_INCOMPLETE )
|
||||||
|
sb_init( &sb_desc );
|
||||||
|
|
||||||
|
/*
|
||||||
|
Is this segment of the wildcard the last?
|
||||||
|
*/
|
||||||
|
if( !wc_end && !is_recursive )
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Wildcard segment is the last segment
|
Wildcard segment is the last segment,
|
||||||
|
|
||||||
Insert all matching files/directories
|
Insert all matching files/directories
|
||||||
*/
|
*/
|
||||||
if( wc[0]=='\0' )
|
if( wc[0]=='\0' )
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
The last wildcard segment is empty. Insert everything if completing, the directory itself otherwise.
|
The last wildcard segment is empty. Insert everything if
|
||||||
|
completing, the directory itself otherwise.
|
||||||
*/
|
*/
|
||||||
if( flags & ACCEPT_INCOMPLETE )
|
if( flags & ACCEPT_INCOMPLETE )
|
||||||
{
|
{
|
||||||
@@ -375,20 +437,10 @@ int wildcard_expand( const wchar_t *wc,
|
|||||||
wchar_t *name = str2wcs(next->d_name);
|
wchar_t *name = str2wcs(next->d_name);
|
||||||
if( name == 0 )
|
if( name == 0 )
|
||||||
{
|
{
|
||||||
/* closedir( dir );*/
|
|
||||||
/* return -1; */
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
wchar_t *long_name = make_path( base_dir, name );
|
wchar_t *long_name = make_path( base_dir, name );
|
||||||
|
|
||||||
if( long_name == 0 )
|
|
||||||
{
|
|
||||||
wperror( L"malloc" );
|
|
||||||
closedir( dir );
|
|
||||||
free(name);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( test_flags( long_name, flags ) )
|
if( test_flags( long_name, flags ) )
|
||||||
{
|
{
|
||||||
get_desc( long_name,
|
get_desc( long_name,
|
||||||
@@ -407,7 +459,7 @@ int wildcard_expand( const wchar_t *wc,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
res = 1;
|
res = 1;
|
||||||
al_push( out, wcsdup( base_dir ) );
|
al_push_check( out, wcsdup( base_dir ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -423,22 +475,13 @@ int wildcard_expand( const wchar_t *wc,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wprintf( L"Filen heter %s\n\n\n", next->d_name );*/
|
|
||||||
/* wprintf( L"Match %ls (%s) against %ls\n\n\n", name, "tjo", wc );*/
|
|
||||||
if( flags & ACCEPT_INCOMPLETE )
|
if( flags & ACCEPT_INCOMPLETE )
|
||||||
{
|
{
|
||||||
/* wprintf( L"match %ls to %ls\n", name, wc );*/
|
|
||||||
|
|
||||||
wchar_t *long_name = make_path( base_dir, name );
|
wchar_t *long_name = make_path( base_dir, name );
|
||||||
if( long_name == 0 )
|
|
||||||
{
|
|
||||||
wperror( L"malloc" );
|
|
||||||
closedir( dir );
|
|
||||||
free(name);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
Test for matches before stating file, so as to minimize the number of stat calls
|
Test for matches before stating file, so as to minimize the number of calls to the much slower stat function
|
||||||
*/
|
*/
|
||||||
if( wildcard_complete( name,
|
if( wildcard_complete( name,
|
||||||
wc,
|
wc,
|
||||||
@@ -446,8 +489,6 @@ int wildcard_expand( const wchar_t *wc,
|
|||||||
0,
|
0,
|
||||||
0 ) )
|
0 ) )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
if( test_flags( long_name, flags ) )
|
if( test_flags( long_name, flags ) )
|
||||||
{
|
{
|
||||||
get_desc( long_name,
|
get_desc( long_name,
|
||||||
@@ -470,15 +511,8 @@ int wildcard_expand( const wchar_t *wc,
|
|||||||
if( wildcard_match2( name, wc, 1 ) )
|
if( wildcard_match2( name, wc, 1 ) )
|
||||||
{
|
{
|
||||||
wchar_t *long_name = make_path( base_dir, name );
|
wchar_t *long_name = make_path( base_dir, name );
|
||||||
if( long_name == 0 )
|
|
||||||
{
|
|
||||||
wperror( L"malloc" );
|
|
||||||
closedir( dir );
|
|
||||||
free(name);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
al_push( out, long_name );
|
al_push_check( out, long_name );
|
||||||
res = 1;
|
res = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -489,34 +523,52 @@ int wildcard_expand( const wchar_t *wc,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Wilcard segment is not the last segment.
|
Wilcard segment is not the last segment. Recursively call
|
||||||
Recursively call wildcard_expand for all matching subdirectories.
|
wildcard_expand for all matching subdirectories.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
wc_str is the part of the wildcarded string from the
|
||||||
|
beginning to the first slash
|
||||||
*/
|
*/
|
||||||
wchar_t *wc_str;
|
wchar_t *wc_str;
|
||||||
|
|
||||||
|
/*
|
||||||
|
new_dir is a scratch area containing the full path to a
|
||||||
|
file/directory we are iterating over
|
||||||
|
*/
|
||||||
wchar_t *new_dir;
|
wchar_t *new_dir;
|
||||||
static size_t ln=1024;
|
|
||||||
|
/*
|
||||||
|
The maximum length of a file element
|
||||||
|
*/
|
||||||
|
static size_t ln=MAX_FILE_LENGTH;
|
||||||
char * narrow_dir_string = wcs2str( dir_string );
|
char * narrow_dir_string = wcs2str( dir_string );
|
||||||
|
|
||||||
if( narrow_dir_string )
|
if( narrow_dir_string )
|
||||||
{
|
{
|
||||||
ln = pathconf( narrow_dir_string, _PC_NAME_MAX ); /* Find out how long the filename can be in a worst case scenario */
|
/*
|
||||||
|
Find out how long the filename can be in a worst case
|
||||||
|
scenario
|
||||||
|
*/
|
||||||
|
ln = pathconf( narrow_dir_string, _PC_NAME_MAX );
|
||||||
|
|
||||||
|
/*
|
||||||
|
If not specified, use som large number as fallback
|
||||||
|
*/
|
||||||
if( ln < 0 )
|
if( ln < 0 )
|
||||||
ln = 1024;
|
ln = MAX_FILE_LENGTH;
|
||||||
free( narrow_dir_string );
|
free( narrow_dir_string );
|
||||||
}
|
}
|
||||||
new_dir= malloc( sizeof(wchar_t)*(base_len+ln+2) );
|
new_dir= malloc( sizeof(wchar_t)*(base_len+ln+2) );
|
||||||
|
|
||||||
wc_str = wcsndup(wc, wc_end-wc);
|
wc_str = wc_end?wcsndup(wc, wc_end-wc):wcsdup(wc);
|
||||||
|
|
||||||
if( (!new_dir) || (!wc_str) )
|
if( (!new_dir) || (!wc_str) )
|
||||||
{
|
{
|
||||||
if( new_dir )
|
die_mem();
|
||||||
free( new_dir );
|
|
||||||
if( wc_str )
|
|
||||||
free( wc_str );
|
|
||||||
wperror( L"malloc" );
|
|
||||||
closedir( dir );
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wcscpy( new_dir, base_dir );
|
wcscpy( new_dir, base_dir );
|
||||||
|
|
||||||
while( (next=readdir(dir))!=0 )
|
while( (next=readdir(dir))!=0 )
|
||||||
@@ -526,56 +578,103 @@ int wildcard_expand( const wchar_t *wc,
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Test if the file/directory name matches the whole
|
||||||
|
wildcard element, i.e. regular matching.
|
||||||
|
*/
|
||||||
|
int whole_match = wildcard_match2( name, wc_str, 1 );
|
||||||
|
int partial_match = 0;
|
||||||
|
|
||||||
if( wildcard_match2( name, wc_str, 1 ) )
|
/*
|
||||||
|
If we are doing recursive matching, also check if this
|
||||||
|
directory matches the part up to the recusrive
|
||||||
|
wildcard, if so, then we can search all subdirectories
|
||||||
|
for matches.
|
||||||
|
*/
|
||||||
|
if( is_recursive )
|
||||||
|
{
|
||||||
|
wchar_t *end = wcschr( wc, ANY_STRING_RECURSIVE );
|
||||||
|
wchar_t *wc_sub = wcsndup( wc, end-wc+1);
|
||||||
|
partial_match = wildcard_match2( name, wc_sub, 1 );
|
||||||
|
free( wc_sub );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( whole_match || partial_match )
|
||||||
{
|
{
|
||||||
int new_len;
|
int new_len;
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
wcscpy(&new_dir[base_len], name );
|
char *dir_str;
|
||||||
free(name);
|
|
||||||
char *dir_str = wcs2str( new_dir );
|
|
||||||
int stat_res;
|
int stat_res;
|
||||||
|
|
||||||
if( !dir_str )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
stat_res= stat( dir_str, &buf );
|
|
||||||
free( dir_str );
|
|
||||||
|
|
||||||
if( stat_res )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( buf.st_mode & S_IFDIR )
|
wcscpy(&new_dir[base_len], name );
|
||||||
|
dir_str = wcs2str( new_dir );
|
||||||
|
|
||||||
|
if( dir_str )
|
||||||
{
|
{
|
||||||
new_len = wcslen( new_dir );
|
stat_res = stat( dir_str, &buf );
|
||||||
new_dir[new_len] = L'/';
|
free( dir_str );
|
||||||
new_dir[new_len+1] = L'\0';
|
|
||||||
switch( wildcard_expand( wc_end + 1, new_dir, flags, out ) )
|
if( !stat_res )
|
||||||
{
|
{
|
||||||
case 0:
|
if( buf.st_mode & S_IFDIR )
|
||||||
break;
|
{
|
||||||
case 1:
|
new_len = wcslen( new_dir );
|
||||||
res = 1;
|
new_dir[new_len] = L'/';
|
||||||
break;
|
new_dir[new_len+1] = L'\0';
|
||||||
|
|
||||||
|
/*
|
||||||
|
Regular matching
|
||||||
|
*/
|
||||||
|
if( whole_match )
|
||||||
|
{
|
||||||
|
res |= wildcard_expand( wc_end?wc_end + 1:L"",
|
||||||
|
new_dir,
|
||||||
|
flags,
|
||||||
|
out );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Recursive matching
|
||||||
|
*/
|
||||||
|
if( partial_match )
|
||||||
|
{
|
||||||
|
res |= wildcard_expand( wcschr( wc, ANY_STRING_RECURSIVE ),
|
||||||
|
new_dir,
|
||||||
|
flags | WILDCARD_RECURSIVE,
|
||||||
|
out );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
free(name);
|
||||||
{
|
|
||||||
free(name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free( wc_str );
|
free( wc_str );
|
||||||
free( new_dir );
|
free( new_dir );
|
||||||
}
|
}
|
||||||
closedir( dir );
|
closedir( dir );
|
||||||
|
|
||||||
sb_destroy( &sb_desc );
|
if( flags & ACCEPT_INCOMPLETE )
|
||||||
|
sb_destroy( &sb_desc );
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void al_push_check( array_list_t *l, const wchar_t *new )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for( i = 0; i < al_get_count(l); i++ )
|
||||||
|
{
|
||||||
|
if( !wcscmp( al_get(l, i), new ) )
|
||||||
|
{
|
||||||
|
free( new );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
al_push( l, new );
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
|
|
||||||
/** \file wildcard.h
|
/** \file wildcard.h
|
||||||
|
|
||||||
My own globbing implementation. Needed to implement this instead
|
My own globbing implementation. Needed to implement this instead
|
||||||
of using libs globbing to support tab-expantion of globbed
|
of using libs globbing to support tab-expansion of globbed
|
||||||
paramaters.
|
paramaters.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
@@ -93,4 +92,10 @@ int wildcard_complete( const wchar_t *str,
|
|||||||
const wchar_t *(*desc_func)(const wchar_t *),
|
const wchar_t *(*desc_func)(const wchar_t *),
|
||||||
array_list_t *out );
|
array_list_t *out );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Push string if not already in list
|
||||||
|
*/
|
||||||
|
void al_push_check( array_list_t *l, const wchar_t *str );
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user