mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-13 12:51:15 -03:00
Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
13a7269378 | ||
|
|
fd2644ce49 | ||
|
|
508de57459 | ||
|
|
de2405b35a | ||
|
|
a7f977836a | ||
|
|
f59e4a88c6 | ||
|
|
c755bd0358 | ||
|
|
536523ffd7 | ||
|
|
ca82fc2f03 | ||
|
|
d1411c42d6 | ||
|
|
9d770af5f4 | ||
|
|
d1ff6a323a | ||
|
|
112ea1759a | ||
|
|
76bafbef2a | ||
|
|
1947ec88f1 | ||
|
|
d0956f1e43 | ||
|
|
6996c7718e | ||
|
|
45d56d8e05 | ||
|
|
53295d38b7 | ||
|
|
bd9c843fd1 | ||
|
|
f812b9b26c | ||
|
|
52851a3ba4 |
10
Makefile.in
10
Makefile.in
@@ -344,7 +344,6 @@ builtin_help.c: $(BUILTIN_DOC_HDR) doc_src/count.doxygen gen_hdr2 gen_hdr.sh bui
|
||||
./gen_hdr.sh $*.doxygen >>$@
|
||||
echo ");" >>$@
|
||||
echo "}" >>$@
|
||||
#man -- doc_src/builtin_doc/man/man1/`basename $@ .c`.1 | cat -s | ./gen_hdr2 >>$@
|
||||
|
||||
#
|
||||
# The build rules for installing/uninstalling fish
|
||||
@@ -413,7 +412,7 @@ install-force: all install-translations
|
||||
@echo \* use the command \'chsh -s $(DESTDIR)$(bindir)/fish\'.
|
||||
@echo
|
||||
@echo Have fun!
|
||||
.PHONY: force-install
|
||||
.PHONY: install-force
|
||||
|
||||
|
||||
# Uninstall this fish version
|
||||
@@ -455,6 +454,7 @@ uninstall-legacy: uninstall
|
||||
rmdir $(DESTDIR)$(sysconfdir)/fish.d/completions; true
|
||||
rmdir $(DESTDIR)$(sysconfdir)/fish.d; true
|
||||
@echo The previous fish installation has been removed.
|
||||
.PHONY: uninstall-legacy
|
||||
|
||||
install-translations: $(TRANSLATIONS)
|
||||
if test $(HAVE_GETTEXT) = 1; then \
|
||||
@@ -579,7 +579,7 @@ distclean: clean
|
||||
.PHONY: distclean
|
||||
|
||||
clean:
|
||||
rm -f *.o doc.h doc_src/*.doxygen doc_src/*.c builtin_help.c
|
||||
rm -f *.o doc.h doc_src/*.doxygen doc_src/*.c builtin_help.c doc_src/*.o
|
||||
rm -f tests/tmp.err tests/tmp.out tests/tmp.status tests/foo.txt
|
||||
rm -f tokenizer_test fish key_reader set_color gen_hdr2 mimedb
|
||||
rm -f fishd fish_pager count fish_tests
|
||||
@@ -620,7 +620,6 @@ complete.o: signal.h config.h fallback.h common.h util.h tokenizer.h
|
||||
complete.o: wildcard.h proc.h io.h parser.h event.h function.h complete.h
|
||||
complete.o: builtin.h env.h exec.h expand.h reader.h history.h intern.h
|
||||
complete.o: translate.h parse_util.h halloc_util.h wutil.h
|
||||
dragon.o: signal.h
|
||||
env.o: config.h signal.h fallback.h common.h util.h wutil.h proc.h io.h env.h
|
||||
env.o: sanity.h expand.h history.h reader.h parser.h event.h env_universal.h
|
||||
env.o: env_universal_common.h input_common.h translate.h complete.h
|
||||
@@ -637,7 +636,7 @@ exec.o: halloc.h halloc_util.h parse_util.h
|
||||
expand.o: signal.h config.h fallback.h common.h util.h wutil.h env.h proc.h
|
||||
expand.o: io.h parser.h event.h expand.h wildcard.h exec.h tokenizer.h
|
||||
expand.o: complete.h translate.h parse_util.h halloc_util.h
|
||||
fallback.o: config.h common.h util.h
|
||||
fallback.o: config.h fallback.h common.h util.h
|
||||
fishd.o: config.h signal.h fallback.h common.h util.h wutil.h
|
||||
fishd.o: env_universal_common.h
|
||||
fish_pager.o: config.h signal.h fallback.h common.h util.h wutil.h complete.h
|
||||
@@ -670,6 +669,7 @@ kill.o: io.h sanity.h env.h exec.h parser.h event.h
|
||||
main.o: config.h signal.h fallback.h common.h util.h reader.h builtin.h
|
||||
main.o: function.h complete.h wutil.h env.h sanity.h proc.h io.h parser.h
|
||||
main.o: event.h expand.h intern.h exec.h output.h translate.h halloc_util.h
|
||||
main.o: history.h
|
||||
mimedb.o: config.h xdgmime.h fallback.h common.h util.h
|
||||
output.o: config.h signal.h fallback.h common.h util.h wutil.h expand.h
|
||||
output.o: output.h halloc_util.h highlight.h
|
||||
|
||||
53
builtin.c
53
builtin.c
@@ -1029,7 +1029,7 @@ static int builtin_function( wchar_t **argv )
|
||||
{
|
||||
event_t *e;
|
||||
|
||||
if( !wcsvarname( woptarg ) )
|
||||
if( wcsvarname( woptarg ) )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: Invalid variable name '%ls'\n" ),
|
||||
@@ -1145,7 +1145,7 @@ static int builtin_function( wchar_t **argv )
|
||||
argc-woptind );
|
||||
res=1;
|
||||
}
|
||||
else if( !(is_binding?wcsbindingname( argv[woptind] ) : wcsvarname( argv[woptind] ) ))
|
||||
else if( !(is_binding?wcsbindingname( argv[woptind] ) : !wcsvarname( argv[woptind] ) ))
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: Illegal function name '%ls'\n" ),
|
||||
@@ -1468,20 +1468,6 @@ static int builtin_read( wchar_t **argv )
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( woptind == argc )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
BUILTIN_ERR_MISSING,
|
||||
argv[0] );
|
||||
|
||||
sb_append2( sb_err,
|
||||
parser_current_line(),
|
||||
L"\n",
|
||||
(void *)0 );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Verify all variable names
|
||||
*/
|
||||
@@ -1512,10 +1498,6 @@ static int builtin_read( wchar_t **argv )
|
||||
*/
|
||||
i=woptind;
|
||||
|
||||
ifs = env_get( L"IFS" );
|
||||
if( ifs == 0 )
|
||||
ifs = L"";
|
||||
|
||||
/*
|
||||
Check if we should read interactively using \c reader_readline()
|
||||
*/
|
||||
@@ -1593,20 +1575,29 @@ static int builtin_read( wchar_t **argv )
|
||||
sb_destroy( &sb );
|
||||
}
|
||||
|
||||
wchar_t *state;
|
||||
|
||||
nxt = wcstok( buff, (i<argc-1)?ifs:L"", &state );
|
||||
|
||||
while( i<argc )
|
||||
if( i != argc )
|
||||
{
|
||||
env_set( argv[i], nxt != 0 ? nxt: L"", place );
|
||||
|
||||
wchar_t *state;
|
||||
|
||||
i++;
|
||||
if( nxt != 0 )
|
||||
nxt = wcstok( 0, (i<argc-1)?ifs:L"", &state);
|
||||
ifs = env_get( L"IFS" );
|
||||
if( ifs == 0 )
|
||||
ifs = L"";
|
||||
|
||||
nxt = wcstok( buff, (i<argc-1)?ifs:L"", &state );
|
||||
|
||||
while( i<argc )
|
||||
{
|
||||
env_set( argv[i], nxt != 0 ? nxt: L"", place );
|
||||
|
||||
i++;
|
||||
if( nxt != 0 )
|
||||
nxt = wcstok( 0, (i<argc-1)?ifs:L"", &state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
free( buff );
|
||||
|
||||
return exit_res;
|
||||
}
|
||||
|
||||
@@ -2593,7 +2584,7 @@ static int builtin_for( wchar_t **argv )
|
||||
argv[0] );
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
}
|
||||
else if ( !wcsvarname(argv[1]) )
|
||||
else if ( wcsvarname(argv[1]) )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_( L"%ls: '%ls' is not a valid variable name\n" ),
|
||||
|
||||
168
builtin_set.c
168
builtin_set.c
@@ -26,6 +26,26 @@ Functions used for implementing the set builtin.
|
||||
#include "parser.h"
|
||||
#include "translate.h"
|
||||
|
||||
#define BUILTIN_SET_PATH_ERROR L"%ls: Could not add component %ls to %ls.\n"
|
||||
#define BUILTIN_SET_PATH_HINT L"%ls: Did you mean 'set %ls $%ls %ls'?\n"
|
||||
|
||||
/**
|
||||
Call env_set. On error, print a description of the problem to
|
||||
stderr.
|
||||
*/
|
||||
static void my_env_set( const wchar_t *key, const wchar_t *val, int scope )
|
||||
{
|
||||
|
||||
switch( env_set( key, val, scope | ENV_USER ) )
|
||||
{
|
||||
case ENV_PERM:
|
||||
{
|
||||
sb_printf( sb_err, _(L"%ls: Tried to change the read-only variable '%ls'\n"), L"set", key );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Extract the name from a destination argument of the form name[index1 index2...]
|
||||
*/
|
||||
@@ -114,7 +134,12 @@ static int parse_fill_indexes( array_list_t *indexes,
|
||||
|
||||
|
||||
/**
|
||||
Update a list by writing the specified values at the specified indexes
|
||||
Update a list \c list by writing copies (using wcsdup) of the
|
||||
values specified by \c values to the indexes specified by \c
|
||||
indexes. The previous entries at the specidied position will be
|
||||
free'd.
|
||||
|
||||
\return The number of elements in the list after the modifications have been made
|
||||
*/
|
||||
static int update_values( array_list_t *list,
|
||||
array_list_t *indexes,
|
||||
@@ -122,16 +147,12 @@ static int update_values( array_list_t *list,
|
||||
{
|
||||
int i;
|
||||
|
||||
//fwprintf(stderr, L"Scan complete\n");
|
||||
/* Replace values where needed */
|
||||
for( i = 0; i < al_get_count(indexes); i++ )
|
||||
{
|
||||
int ind = *(int *) al_get(indexes, i) - 1;
|
||||
void *new = (void *) al_get(values, i);
|
||||
if (al_get(list, ind) != 0)
|
||||
{
|
||||
free((void *) al_get(list, ind));
|
||||
}
|
||||
free((void *) al_get(list, ind));
|
||||
al_set(list, ind, new != 0 ? wcsdup(new) : wcsdup(L""));
|
||||
}
|
||||
|
||||
@@ -169,8 +190,6 @@ static int erase_values(array_list_t *list, array_list_t *indexes)
|
||||
int i;
|
||||
array_list_t result;
|
||||
|
||||
//fwprintf(stderr, L"Starting with %d\n", al_get_count(list));
|
||||
|
||||
al_init(&result);
|
||||
|
||||
for (i = 0; i < al_get_count(list); i++)
|
||||
@@ -189,8 +208,6 @@ static int erase_values(array_list_t *list, array_list_t *indexes)
|
||||
al_push_all( list, &result );
|
||||
al_destroy(&result);
|
||||
|
||||
//fwprintf(stderr, L"Remaining: %d\n", al_get_count(&result));
|
||||
|
||||
return al_get_count(list);
|
||||
}
|
||||
|
||||
@@ -207,8 +224,6 @@ static int fill_buffer_from_list(string_buffer_t *sb, array_list_t *list)
|
||||
wchar_t *v = (wchar_t *) al_get(list, i);
|
||||
if (v != 0)
|
||||
{
|
||||
// fwprintf(stderr, L".\n");
|
||||
// fwprintf(stderr, L"Collecting %ls from %d\n", v, i);
|
||||
sb_append(sb, v);
|
||||
}
|
||||
if (i < al_get_count(list) - 1)
|
||||
@@ -254,12 +269,25 @@ static void print_variables(int include_values, int esc, int scope)
|
||||
al_destroy(&names);
|
||||
}
|
||||
|
||||
static int is_path_variable( const wchar_t *env )
|
||||
{
|
||||
return contains_str( env,
|
||||
L"PATH",
|
||||
L"CDPATH",
|
||||
(void *)0 );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
The set builtin. Creates, updates and erases environment variables and environemnt variable arrays.
|
||||
*/
|
||||
|
||||
int builtin_set( wchar_t **argv )
|
||||
{
|
||||
|
||||
/**
|
||||
Variables used for parsing the argument list
|
||||
*/
|
||||
const static struct woption
|
||||
long_options[] =
|
||||
{
|
||||
@@ -293,7 +321,7 @@ int builtin_set( wchar_t **argv )
|
||||
}
|
||||
;
|
||||
|
||||
wchar_t short_options[] = L"+xglenuUq";
|
||||
const wchar_t *short_options = L"+xglenuUq";
|
||||
|
||||
int argc = builtin_count_args(argv);
|
||||
|
||||
@@ -363,6 +391,15 @@ int builtin_set( wchar_t **argv )
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Ok, all arguments have been parsed, let's validate them
|
||||
*/
|
||||
|
||||
/*
|
||||
If we are checking the existance of a variable (-q) we can not
|
||||
also specify scope
|
||||
*/
|
||||
|
||||
if( query && (erase || list || global || local || universal || export || unexport ) )
|
||||
{
|
||||
sb_printf(sb_err,
|
||||
@@ -375,7 +412,7 @@ int builtin_set( wchar_t **argv )
|
||||
}
|
||||
|
||||
|
||||
/* Check operation and modifiers sanity */
|
||||
/* We can't both list and erase varaibles */
|
||||
if( erase && list )
|
||||
{
|
||||
sb_printf(sb_err,
|
||||
@@ -387,6 +424,9 @@ int builtin_set( wchar_t **argv )
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Variables can only have one scope
|
||||
*/
|
||||
if( local + global + universal > 1 )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
@@ -397,6 +437,9 @@ int builtin_set( wchar_t **argv )
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Variables can only have one export status
|
||||
*/
|
||||
if( export && unexport )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
@@ -410,13 +453,16 @@ int builtin_set( wchar_t **argv )
|
||||
if( query )
|
||||
{
|
||||
/*
|
||||
Query mode. Return number of specified variables that do not exist.
|
||||
Query mode. Return the number variables that do not exist
|
||||
out of the specified variables.
|
||||
*/
|
||||
int i;
|
||||
for( i=woptind; i<argc; i++ )
|
||||
{
|
||||
if( !env_exist( argv[i] ) )
|
||||
{
|
||||
retcode++;
|
||||
}
|
||||
|
||||
}
|
||||
return retcode;
|
||||
@@ -427,8 +473,7 @@ int builtin_set( wchar_t **argv )
|
||||
if( woptind < argc )
|
||||
{
|
||||
dest = wcsdup(argv[woptind++]);
|
||||
//fwprintf(stderr, L"Dest: %ls\n", dest);
|
||||
|
||||
|
||||
if( !wcslen( dest ) )
|
||||
{
|
||||
free( dest );
|
||||
@@ -444,9 +489,82 @@ int builtin_set( wchar_t **argv )
|
||||
while( woptind < argc )
|
||||
{
|
||||
al_push(&values, argv[woptind++]);
|
||||
// fwprintf(stderr, L"Val: %ls\n", argv[woptind - 1]);
|
||||
}
|
||||
|
||||
if( is_path_variable( dest ) )
|
||||
{
|
||||
int i;
|
||||
int error = 0;
|
||||
|
||||
for( i=0; i<al_get_count( &values ); i++ )
|
||||
{
|
||||
int show_perror = 0;
|
||||
int show_hint = 0;
|
||||
|
||||
struct stat buff;
|
||||
wchar_t *dir = (wchar_t *)al_get( &values, i );
|
||||
|
||||
if( wstat( dir, &buff ) )
|
||||
{
|
||||
error = 1;
|
||||
show_perror = 1;
|
||||
}
|
||||
|
||||
if( !( S_IFDIR & buff.st_mode ) )
|
||||
{
|
||||
error = 1;
|
||||
|
||||
}
|
||||
|
||||
if( error )
|
||||
{
|
||||
wchar_t *colon;
|
||||
|
||||
sb_printf( sb_err,
|
||||
_(BUILTIN_SET_PATH_ERROR),
|
||||
argv[0],
|
||||
dir,
|
||||
dest );
|
||||
colon = wcschr( dir, L':' );
|
||||
|
||||
if( colon && *(colon+1) )
|
||||
{
|
||||
show_hint = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( show_perror )
|
||||
{
|
||||
builtin_wperror( argv[0] );
|
||||
}
|
||||
|
||||
if( show_hint )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
_(BUILTIN_SET_PATH_HINT),
|
||||
argv[0],
|
||||
dest,
|
||||
dest,
|
||||
wcschr( dir, L':' )+1);
|
||||
}
|
||||
|
||||
if( error )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( error )
|
||||
{
|
||||
al_destroy(&values);
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Extract variable name and indexes */
|
||||
|
||||
sb_init(&name_sb);
|
||||
@@ -459,8 +577,7 @@ int builtin_set( wchar_t **argv )
|
||||
if( !retcode )
|
||||
{
|
||||
name = (wchar_t *) name_sb.buff;
|
||||
//fwprintf(stderr, L"Name is %ls\n", name);
|
||||
|
||||
|
||||
al_init(&indexes);
|
||||
retval = parse_fill_indexes(&indexes, dest);
|
||||
if (retval < 0)
|
||||
@@ -477,7 +594,7 @@ int builtin_set( wchar_t **argv )
|
||||
int scope = (local ? ENV_LOCAL : 0) | (global ? ENV_GLOBAL : 0) | (export ? ENV_EXPORT : 0) | (unexport ? ENV_UNEXPORT : 0) | (universal ? ENV_UNIVERSAL:0) | ENV_USER;
|
||||
if( list )
|
||||
{
|
||||
/* Maybe we should issue an error if there are any other arguments */
|
||||
/* Maybe we should issue an error if there are any other arguments? */
|
||||
print_variables(0, 0, scope);
|
||||
finished=1;
|
||||
}
|
||||
@@ -512,7 +629,7 @@ int builtin_set( wchar_t **argv )
|
||||
!erase &&
|
||||
!list )
|
||||
{
|
||||
env_set( name, 0, scope );
|
||||
my_env_set( name, 0, scope );
|
||||
finished = 1;
|
||||
}
|
||||
}
|
||||
@@ -572,7 +689,8 @@ int builtin_set( wchar_t **argv )
|
||||
else
|
||||
{
|
||||
fill_buffer_from_list(&result_sb, &val_l);
|
||||
env_set(name, (wchar_t *) result_sb.buff, scope);
|
||||
|
||||
my_env_set(name, (wchar_t *) result_sb.buff, scope);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -585,7 +703,7 @@ int builtin_set( wchar_t **argv )
|
||||
fill_buffer_from_list( &result_sb,
|
||||
&val_l );
|
||||
|
||||
env_set(name,
|
||||
my_env_set(name,
|
||||
(wchar_t *) result_sb.buff,
|
||||
scope);
|
||||
}
|
||||
@@ -601,7 +719,7 @@ int builtin_set( wchar_t **argv )
|
||||
}
|
||||
|
||||
/* Common cleanup */
|
||||
//fwprintf(stderr, L"Cleanup\n");
|
||||
|
||||
free(dest);
|
||||
sb_destroy(&name_sb);
|
||||
al_destroy( &values );
|
||||
|
||||
108
common.c
108
common.c
@@ -400,119 +400,17 @@ wchar_t **strv2wcsv( const char **in )
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*$OpenBSD: strlcat.c,v 1.11 2003/06/17 21:56:24 millert Exp $*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
size_t
|
||||
wcslcat(wchar_t *dst, const wchar_t *src, size_t siz)
|
||||
{
|
||||
|
||||
register wchar_t *d = dst;
|
||||
register const wchar_t *s = src;
|
||||
register size_t n = siz;
|
||||
size_t dlen;
|
||||
|
||||
/* Find the end of dst and adjust bytes left but don't go past end */
|
||||
while (n-- != 0 && *d != '\0')
|
||||
d++;
|
||||
|
||||
dlen = d - dst;
|
||||
n = siz - dlen;
|
||||
|
||||
if (n == 0)
|
||||
return(dlen + wcslen(s));
|
||||
|
||||
while (*s != '\0')
|
||||
{
|
||||
if (n != 1)
|
||||
{
|
||||
*d++ = *s;
|
||||
n--;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
*d = '\0';
|
||||
|
||||
return(dlen + (s - src));
|
||||
/* count does not include NUL */
|
||||
}
|
||||
|
||||
/*$OpenBSD: strlcpy.c,v 1.8 2003/06/17 21:56:24 millert Exp $*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
size_t
|
||||
wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz)
|
||||
{
|
||||
register wchar_t *d = dst;
|
||||
register const wchar_t *s = src;
|
||||
register size_t n = siz;
|
||||
|
||||
/* Copy as many bytes as will fit */
|
||||
if (n != 0 && --n != 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
if ((*d++ = *s++) == 0)
|
||||
break;
|
||||
}
|
||||
while (--n != 0);
|
||||
}
|
||||
|
||||
/* Not enough room in dst, add NUL and traverse rest of src */
|
||||
if (n == 0)
|
||||
{
|
||||
if (siz != 0)
|
||||
*d = '\0';
|
||||
/* NUL-terminate dst */
|
||||
while (*s++)
|
||||
;
|
||||
}
|
||||
return(s - src - 1);
|
||||
/* count does not include NUL */
|
||||
}
|
||||
|
||||
int wcsvarname( wchar_t *str )
|
||||
wchar_t *wcsvarname( wchar_t *str )
|
||||
{
|
||||
while( *str )
|
||||
{
|
||||
if( (!iswalnum(*str)) && (*str != L'_' ) )
|
||||
{
|
||||
return 0;
|
||||
return str;
|
||||
}
|
||||
str++;
|
||||
}
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
33
common.h
33
common.h
@@ -134,35 +134,18 @@ wchar_t *wcsdupcat( const wchar_t *a, const wchar_t *b );
|
||||
*/
|
||||
wchar_t *wcsdupcat2( const wchar_t *a, ... );
|
||||
|
||||
|
||||
/**
|
||||
Appends src to string dst of size siz (unlike wcsncat, siz is the
|
||||
full size of dst, not space left). At most siz-1 characters will be
|
||||
copied. Always NUL terminates (unless siz <= wcslen(dst)). Returns
|
||||
wcslen(src) + MIN(siz, wcslen(initial dst)). If retval >= siz,
|
||||
truncation occurred.
|
||||
|
||||
This is the OpenBSD strlcat function, modified for wide characters,
|
||||
and renamed to reflect this change.
|
||||
|
||||
*/
|
||||
size_t wcslcat( wchar_t *dst, const wchar_t *src, size_t siz );
|
||||
|
||||
/**
|
||||
Copy src to string dst of size siz. At most siz-1 characters will
|
||||
be copied. Always NUL terminates (unless siz == 0). Returns
|
||||
wcslen(src); if retval >= siz, truncation occurred.
|
||||
|
||||
This is the OpenBSD strlcpy function, modified for wide characters,
|
||||
and renamed to reflect this change.
|
||||
*/
|
||||
size_t wcslcpy( wchar_t *dst, const wchar_t *src, size_t siz );
|
||||
|
||||
/**
|
||||
Test if the given string is a valid variable name
|
||||
*/
|
||||
|
||||
int wcsvarname( wchar_t *str );
|
||||
|
||||
/**
|
||||
Test if the given string is a valid variable name.
|
||||
|
||||
\return null if this is a valid name, and a pointer to the first invalid character otherwise
|
||||
*/
|
||||
|
||||
wchar_t *wcsvarname( wchar_t *str );
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(fish,1.21.4,fish-users@lists.sf.net)
|
||||
AC_INIT(fish,1.21.6,fish-users@lists.sf.net)
|
||||
|
||||
# If needed, run autoconf to regenerate the configure file
|
||||
AC_MSG_CHECKING([if autoconf needs to be run])
|
||||
@@ -12,7 +12,7 @@ if test configure -ot configure.ac; then
|
||||
if autoconf; then
|
||||
./configure "$@"
|
||||
fi
|
||||
exit
|
||||
exit
|
||||
else
|
||||
AC_MSG_ERROR( [cannot find the autoconf program in your path.
|
||||
This program needs to be run whenever the configure.ac file is modified.
|
||||
@@ -85,7 +85,7 @@ AC_PROG_INSTALL
|
||||
# Check for doxygen, which is needed to build
|
||||
AC_CHECK_PROG( has_doxygen, [doxygen], "true")
|
||||
|
||||
if ! test $has_doxygen = "true"; then
|
||||
if ! test "$has_doxygen" = "true"; then
|
||||
AC_MSG_ERROR( [cannot find the Doxygen program in your path.
|
||||
This program is needed to build fish.
|
||||
Please install it and try again.])
|
||||
@@ -276,7 +276,7 @@ AC_CHECK_HEADER([regex.h],
|
||||
# Check for presense of various functions
|
||||
AC_CHECK_FUNCS( wcsdup wcsndup wcslen wcscasecmp wcsncasecmp gettext fwprintf )
|
||||
AC_CHECK_FUNCS( futimes wcwidth wcswidth getopt_long wcstok fputwc fgetwc )
|
||||
AC_CHECK_FUNCS( wcstol dcgettext )
|
||||
AC_CHECK_FUNCS( wcstol dcgettext wcslcat wcslcpy )
|
||||
|
||||
# Here follows a list of small programs used to test for various
|
||||
# features that Autoconf doesn't tell us about
|
||||
|
||||
@@ -11,6 +11,22 @@ wildcarded values. The \c case statement is used together with the \c
|
||||
switch statement in order to determine which block should be
|
||||
performed.
|
||||
|
||||
Each \c case command is given one or more parameter. The first \c case
|
||||
command with a parameter that matches the string specified in the
|
||||
switch command will be evaluated. \c case parameters may contain
|
||||
wildcards. These need to be escaped or quoted in order to avoid
|
||||
regular wildcard expansion using filenames.
|
||||
|
||||
Note that fish does not fall through on case statements. Though the
|
||||
syntax may look a bit like C switch statements, it behaves more like
|
||||
the case stamantes of traditional shells.
|
||||
|
||||
Also note that command substitutions in a case statement will be
|
||||
evaluated even if it's body is not taken. This may seem
|
||||
counterintuitive at first, but it is unavoidable, since it would be
|
||||
impossible to know if a case command will evaluate to true before all
|
||||
forms of parameter expansion have been performed for the case command.
|
||||
|
||||
\subsection case-example Example
|
||||
|
||||
If the variable \$animal contains the name of an animal, the following
|
||||
@@ -27,9 +43,11 @@ switch $animal
|
||||
echo bird
|
||||
case shark trout stingray
|
||||
echo fish
|
||||
case '*'
|
||||
echo I have no idea what a $animal is
|
||||
end
|
||||
</pre>
|
||||
</p>
|
||||
<p>
|
||||
If the above code was run with \$animal set to \c whale, the output would be \c mammal.
|
||||
If the above code was run with \c \$animal set to \c whale, the output would be \c mammal.
|
||||
</p>
|
||||
|
||||
@@ -1284,7 +1284,7 @@ Examples:
|
||||
|
||||
- Here documents are too similar to using echo inside of a pipeline.
|
||||
- Subshells, command substitution and process substitution are strongly related. \c fish only supports command substitution, the others can be achived either using a block or the psub shellscript function.
|
||||
- Having both aliases and functions is confusing, especially since both of them have limitations and problems. \c fish sunctions have none of the drawbacks of either syntax.
|
||||
- Having both aliases and functions is confusing, especially since both of them have limitations and problems. \c fish functions have none of the drawbacks of either syntax.
|
||||
- The many Posix quoting styles are silly, especially \$''.
|
||||
|
||||
|
||||
@@ -1377,14 +1377,14 @@ Examples:
|
||||
|
||||
\subsection disc The law of discoverability
|
||||
|
||||
The shell should implement it's features in a way that makes them as
|
||||
easy as possible for the user to discover for her/himself.
|
||||
A program should be designed to make its features as
|
||||
easy as possible to discover for the user.
|
||||
|
||||
Rationale:
|
||||
|
||||
A program whose features are discoverable makes a new user into an
|
||||
expert in a shorter span of time, since the user will learn how to use
|
||||
the program simply by using it.
|
||||
A program whose features are discoverable turns a new user into an
|
||||
expert in a shorter span of time, since the user will become an expert
|
||||
on the program simply by using it.
|
||||
|
||||
The main benefit of a graphical program over a command line-based
|
||||
program is discoverability. In a graphical program, one can discover
|
||||
|
||||
@@ -8,10 +8,13 @@
|
||||
The <tt>read</tt> builtin causes fish to read one line from standard
|
||||
input and store the result in one or more environment variables.
|
||||
|
||||
- <tt>-c CMD</tt> or <tt>--command=CMD</tt> specifies that the initial string in the interactive mode command buffer should be CMD.
|
||||
- <tt>-e</tt> or <tt>--export</tt> specifies that the variables will be exported to subshells.
|
||||
- <tt>-g</tt> or <tt>--global</tt> specifies that the variables will be made global.
|
||||
- <tt>-pPROMPT_CMD</tt> or <tt>--prompt=PROMPT_CMD</tt> specifies that the output of the shell command PROMPT_CMD should be used as the prompt for the interactive mode prompt. The default prompt command is <tt>set_color green; echo read; set_color normal; echo "> "</tt>.
|
||||
- <tt>-cCMD</tt> or <tt>--command=CMD</tt> specifies that the initial string in the interactive mode command buffer should be CMD.
|
||||
- <tt>-p PROMPT_CMD</tt> or <tt>--prompt=PROMPT_CMD</tt> specifies that the output of the shell command PROMPT_CMD should be used as the prompt for the interactive mode prompt. The default prompt command is <tt>set_color green; echo read; set_color normal; echo "> "</tt>.
|
||||
- <code>-u</code> or <code>--unexport</code> causes the specified environment not to be exported to child processes
|
||||
- <code>-U</code> or <code>--universal</code> causes the specified environment variable to be made universal. If this option is supplied, the variable will be shared between all the current users fish instances on the current computer, and will be preserved across restarts of the shell.
|
||||
- <code>-x</code> or <code>--export</code> causes the specified environment variable to be exported to child processes
|
||||
|
||||
Read starts by reading a single line of input from stdin, the line is
|
||||
then tokenized using the <tt>IFS</tt> environment variable. Each variable
|
||||
|
||||
@@ -8,7 +8,19 @@
|
||||
|
||||
The \c switch statement is used to perform one of several blocks of
|
||||
commands depending on whether a specified value equals one of several
|
||||
wildcarded values.
|
||||
wildcarded values. The \c case statement is used together with the \c
|
||||
switch statement in order to determine which block should be
|
||||
performed.
|
||||
|
||||
Each \c case command is given one or more parameter. The first \c case
|
||||
command with a parameter that matches the string specified in the
|
||||
switch command will be evaluated. \c case parameters may contain
|
||||
wildcards. These need to be escaped or quoted in order to avoid
|
||||
regular wildcard expansion using filenames.
|
||||
|
||||
Note that fish does not fall through on case statements. Though the
|
||||
syntax may look a bit like C switch statements, it behaves more like
|
||||
the case stamantes of traditional shells.
|
||||
|
||||
\subsection switch-example Example
|
||||
|
||||
@@ -26,12 +38,14 @@ switch $animal
|
||||
echo bird
|
||||
case shark trout stingray
|
||||
echo fish
|
||||
case '*'
|
||||
echo I have no idea what a $animal is
|
||||
end
|
||||
</pre>
|
||||
</p>
|
||||
<p>
|
||||
|
||||
If the above code was run with \$animal set to \c whale, the output
|
||||
If the above code was run with \c \$animal set to \c whale, the output
|
||||
would be \c mammal.
|
||||
|
||||
</p>
|
||||
|
||||
17
env.c
17
env.c
@@ -104,7 +104,7 @@ typedef struct env_node
|
||||
typedef struct var_entry
|
||||
{
|
||||
int export; /**< Whether the variable should be exported */
|
||||
wchar_t val[0]; /**< The value of the variable */
|
||||
wchar_t val[1]; /**< The value of the variable */
|
||||
}
|
||||
var_entry_t;
|
||||
|
||||
@@ -608,9 +608,9 @@ static env_node_t *env_get_node( const wchar_t *key )
|
||||
return 0;
|
||||
}
|
||||
|
||||
void env_set( const wchar_t *key,
|
||||
const wchar_t *val,
|
||||
int var_mode )
|
||||
int env_set( const wchar_t *key,
|
||||
const wchar_t *val,
|
||||
int var_mode )
|
||||
{
|
||||
int free_val = 0;
|
||||
var_entry_t *entry;
|
||||
@@ -626,7 +626,7 @@ void env_set( const wchar_t *key,
|
||||
if( (var_mode & ENV_USER ) &&
|
||||
hash_get( &env_read_only, key ) )
|
||||
{
|
||||
return;
|
||||
return ENV_PERM;
|
||||
}
|
||||
|
||||
if( wcscmp( key, L"umask" ) == 0)
|
||||
@@ -650,7 +650,7 @@ void env_set( const wchar_t *key,
|
||||
/*
|
||||
Do not actually create a umask variable, on env_get, it will be calculated dynamically
|
||||
*/
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -749,7 +749,7 @@ void env_set( const wchar_t *key,
|
||||
node = top;
|
||||
while( node->next && !node->new_scope )
|
||||
node = node->next;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -809,7 +809,8 @@ void env_set( const wchar_t *key,
|
||||
{
|
||||
handle_locale();
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
13
env.h
13
env.h
@@ -41,6 +41,11 @@
|
||||
*/
|
||||
#define ENV_UNIVERSAL 32
|
||||
|
||||
/**
|
||||
Error code for trying to alter read-only variable
|
||||
*/
|
||||
#define ENV_PERM 1
|
||||
|
||||
/**
|
||||
Initialize environment variable data
|
||||
*/
|
||||
@@ -61,9 +66,15 @@ void env_destroy();
|
||||
\param val The value
|
||||
\param mode The type of the variable. Can be any combination of ENV_GLOBAL, ENV_LOCAL, ENV_EXPORT and ENV_USER. If mode is zero, the current variable space is searched and the current mode is used. If no current variable with the same name is found, ENV_LOCAL is assumed.
|
||||
|
||||
\returns 0 on suicess or an error code on failiure.
|
||||
|
||||
The current error codes are:
|
||||
|
||||
* ENV_PERM, can only be returned when setting as a user, e.g. ENV_USER is set. This means that the user tried to change a read-only variable.
|
||||
|
||||
*/
|
||||
|
||||
void env_set( const wchar_t *key,
|
||||
int env_set( const wchar_t *key,
|
||||
const wchar_t *val,
|
||||
int mode );
|
||||
|
||||
|
||||
28
expand.c
28
expand.c
@@ -429,7 +429,6 @@ static int find_process( const wchar_t *proc,
|
||||
{
|
||||
result = malloc(sizeof(wchar_t)*16 );
|
||||
swprintf( result, 16, L"%d", j->pgid );
|
||||
//fwprintf( stderr, L"pid %d %ls\n", j->pgid, result );
|
||||
al_push( out, result );
|
||||
found = 1;
|
||||
}
|
||||
@@ -441,12 +440,9 @@ static int find_process( const wchar_t *proc,
|
||||
|
||||
for( j=first_job; j != 0; j=j->next )
|
||||
{
|
||||
// fwprintf( stderr, L"..." );
|
||||
if( j->command == 0 )
|
||||
continue;
|
||||
|
||||
// fwprintf( stderr, L"match '%ls' '%ls'\n\n\n", j->command, proc );
|
||||
|
||||
if( match_pid( j->command, proc, flags ) )
|
||||
{
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
@@ -455,8 +451,6 @@ static int find_process( const wchar_t *proc,
|
||||
COMPLETE_SEP_STR,
|
||||
COMPLETE_JOB_DESC,
|
||||
(void *)0 );
|
||||
// fwprintf( stderr, L"Woot %ls\n", res );
|
||||
|
||||
al_push( out, res );
|
||||
}
|
||||
else
|
||||
@@ -482,12 +476,9 @@ static int find_process( const wchar_t *proc,
|
||||
for( p=j->first_process; p; p=p->next )
|
||||
{
|
||||
|
||||
// fwprintf( stderr, L"..." );
|
||||
if( p->actual_cmd == 0 )
|
||||
continue;
|
||||
|
||||
// fwprintf( stderr, L"match '%ls' '%ls'\n\n\n", j->command, proc );
|
||||
|
||||
if( match_pid( p->actual_cmd, proc, flags ) )
|
||||
{
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
@@ -687,27 +678,22 @@ static int expand_pid( wchar_t *in,
|
||||
}
|
||||
}
|
||||
|
||||
// fwprintf( stderr, L"expand_pid() %ls\n", in );
|
||||
int prev = al_get_count( out );
|
||||
if( !find_process( in+1, flags, out ) )
|
||||
return 0;
|
||||
|
||||
if( prev == al_get_count( out ) )
|
||||
{
|
||||
// fwprintf( stderr, L"no match\n" );
|
||||
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
free( in );
|
||||
else
|
||||
{
|
||||
*in = L'%';
|
||||
// fwprintf( stderr, L"return %ls\n", in );
|
||||
al_push( out, in );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// fwprintf( stderr, L"match\n" );
|
||||
free( in );
|
||||
}
|
||||
|
||||
@@ -967,7 +953,7 @@ static int expand_variables( wchar_t *in, array_list_t *out, int last_idx )
|
||||
else
|
||||
{
|
||||
|
||||
wcsncpy( new_in, in, start_pos-1 );
|
||||
wcslcpy( new_in, in, start_pos );
|
||||
|
||||
if(start_pos>1 && new_in[start_pos-2]!=VARIABLE_EXPAND)
|
||||
{
|
||||
@@ -980,7 +966,6 @@ static int expand_variables( wchar_t *in, array_list_t *out, int last_idx )
|
||||
wcscat( new_in, next );
|
||||
wcscat( new_in, &in[stop_pos] );
|
||||
|
||||
// fwprintf( stderr, L"New value %ls\n", new_in );
|
||||
is_ok &= expand_variables( new_in, out, i );
|
||||
}
|
||||
}
|
||||
@@ -1059,9 +1044,6 @@ static int expand_brackets( wchar_t *in, int flags, array_list_t *out )
|
||||
wchar_t *item_begin;
|
||||
int len1, len2, tot_len;
|
||||
|
||||
// fwprintf( stderr, L"expand %ls\n", in );
|
||||
|
||||
|
||||
for( pos=in;
|
||||
(!bracket_end) && (*pos) && !syntax_error;
|
||||
pos++ )
|
||||
@@ -1153,8 +1135,8 @@ static int expand_brackets( wchar_t *in, int flags, array_list_t *out )
|
||||
int item_len = pos-item_begin;
|
||||
|
||||
whole_item = malloc( sizeof(wchar_t)*(tot_len + item_len + 1) );
|
||||
wcsncpy( whole_item, in, len1 );
|
||||
wcsncpy( whole_item+len1, item_begin, item_len );
|
||||
wcslcpy( whole_item, in, len1+1 );
|
||||
wcslcpy( whole_item+len1, item_begin, item_len+1 );
|
||||
wcscpy( whole_item+len1+item_len, bracket_end+1 );
|
||||
|
||||
expand_brackets( whole_item, flags, out );
|
||||
@@ -1234,7 +1216,7 @@ static int expand_subshell( wchar_t *in, array_list_t *out )
|
||||
return 0;
|
||||
}
|
||||
|
||||
wcsncpy( subcmd, paran_begin+1, paran_end-paran_begin-1 );
|
||||
wcslcpy( subcmd, paran_begin+1, paran_end-paran_begin );
|
||||
subcmd[ paran_end-paran_begin-1]=0;
|
||||
|
||||
if( exec_subshell( subcmd, &sub_res)==-1 )
|
||||
@@ -1310,7 +1292,6 @@ static wchar_t * expand_tilde_internal( wchar_t *in )
|
||||
wchar_t *new_in=0;
|
||||
wchar_t *old_in=0;
|
||||
|
||||
// fwprintf( stderr, L"Tilde expand ~%ls\n", (*ptr)+1 );
|
||||
if( in[1] == '/' || in[1] == '\0' )
|
||||
{
|
||||
/* Current users home directory */
|
||||
@@ -1439,7 +1420,6 @@ int expand_string( void *context,
|
||||
|
||||
// debug( 1, L"Expand %ls", str );
|
||||
|
||||
|
||||
if( (!(flags & ACCEPT_INCOMPLETE)) && is_clean( str ) )
|
||||
{
|
||||
halloc_register( context, str );
|
||||
|
||||
112
fallback.c
112
fallback.c
@@ -818,8 +818,7 @@ wchar_t *wcsndup( const wchar_t *in, int c )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
wcsncpy( res, in, c+1 );
|
||||
res[c] = L'\0';
|
||||
wcslcpy( res, in, c+1 );
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
@@ -888,6 +887,113 @@ long wcstol(const wchar_t *nptr,
|
||||
nptr++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifndef HAVE_WCSLCAT
|
||||
|
||||
/*$OpenBSD: strlcat.c,v 1.11 2003/06/17 21:56:24 millert Exp $*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
size_t
|
||||
wcslcat(wchar_t *dst, const wchar_t *src, size_t siz)
|
||||
{
|
||||
|
||||
register wchar_t *d = dst;
|
||||
register const wchar_t *s = src;
|
||||
register size_t n = siz;
|
||||
size_t dlen;
|
||||
|
||||
/* Find the end of dst and adjust bytes left but don't go past end */
|
||||
while (n-- != 0 && *d != '\0')
|
||||
d++;
|
||||
|
||||
dlen = d - dst;
|
||||
n = siz - dlen;
|
||||
|
||||
if (n == 0)
|
||||
return(dlen + wcslen(s));
|
||||
|
||||
while (*s != '\0')
|
||||
{
|
||||
if (n != 1)
|
||||
{
|
||||
*d++ = *s;
|
||||
n--;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
*d = '\0';
|
||||
|
||||
return(dlen + (s - src));
|
||||
/* count does not include NUL */
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifndef HAVE_WCSLCPY
|
||||
|
||||
/*$OpenBSD: strlcpy.c,v 1.8 2003/06/17 21:56:24 millert Exp $*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
size_t
|
||||
wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz)
|
||||
{
|
||||
register wchar_t *d = dst;
|
||||
register const wchar_t *s = src;
|
||||
register size_t n = siz;
|
||||
|
||||
/* Copy as many bytes as will fit */
|
||||
if (n != 0 && --n != 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
if ((*d++ = *s++) == 0)
|
||||
break;
|
||||
}
|
||||
while (--n != 0);
|
||||
}
|
||||
|
||||
/* Not enough room in dst, add NUL and traverse rest of src */
|
||||
if (n == 0)
|
||||
{
|
||||
if (siz != 0)
|
||||
*d = '\0';
|
||||
/* NUL-terminate dst */
|
||||
while (*s++)
|
||||
;
|
||||
}
|
||||
return(s - src - 1);
|
||||
/* count does not include NUL */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
29
fallback.h
29
fallback.h
@@ -231,6 +231,35 @@ long wcstol(const wchar_t *nptr,
|
||||
wchar_t **endptr,
|
||||
int base);
|
||||
|
||||
#endif
|
||||
#ifndef HAVE_WCSLCAT
|
||||
|
||||
/**
|
||||
Appends src to string dst of size siz (unlike wcsncat, siz is the
|
||||
full size of dst, not space left). At most siz-1 characters will be
|
||||
copied. Always NUL terminates (unless siz <= wcslen(dst)). Returns
|
||||
wcslen(src) + MIN(siz, wcslen(initial dst)). If retval >= siz,
|
||||
truncation occurred.
|
||||
|
||||
This is the OpenBSD strlcat function, modified for wide characters,
|
||||
and renamed to reflect this change.
|
||||
|
||||
*/
|
||||
size_t wcslcat( wchar_t *dst, const wchar_t *src, size_t siz );
|
||||
|
||||
#endif
|
||||
#ifndef HAVE_WCSLCPY
|
||||
|
||||
/**
|
||||
Copy src to string dst of size siz. At most siz-1 characters will
|
||||
be copied. Always NUL terminates (unless siz == 0). Returns
|
||||
wcslen(src); if retval >= siz, truncation occurred.
|
||||
|
||||
This is the OpenBSD strlcpy function, modified for wide characters,
|
||||
and renamed to reflect this change.
|
||||
*/
|
||||
size_t wcslcpy( wchar_t *dst, const wchar_t *src, size_t siz );
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -202,6 +202,10 @@ static void history_to_hash()
|
||||
{
|
||||
history_data *d;
|
||||
|
||||
if( !history_last )
|
||||
return;
|
||||
|
||||
|
||||
d = (history_data *)hash_get( &history_table,
|
||||
mode_name );
|
||||
|
||||
|
||||
7
main.c
7
main.c
@@ -61,6 +61,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#include "output.h"
|
||||
#include "translate.h"
|
||||
#include "halloc_util.h"
|
||||
#include "history.h"
|
||||
|
||||
|
||||
/**
|
||||
@@ -266,6 +267,7 @@ int main( int argc, char **argv )
|
||||
env_init();
|
||||
complete_init();
|
||||
reader_init();
|
||||
history_init();
|
||||
|
||||
if( read_init() )
|
||||
{
|
||||
@@ -297,10 +299,10 @@ int main( int argc, char **argv )
|
||||
return 1;
|
||||
}
|
||||
|
||||
sb_init( &sb );
|
||||
|
||||
if( *(argv+2))
|
||||
{
|
||||
sb_init( &sb );
|
||||
|
||||
for( i=1,ptr = argv+2; *ptr; i++, ptr++ )
|
||||
{
|
||||
if( i != 1 )
|
||||
@@ -337,6 +339,7 @@ int main( int argc, char **argv )
|
||||
|
||||
proc_fire_event( L"PROCESS_EXIT", EVENT_EXIT, getpid(), res );
|
||||
|
||||
history_destroy();
|
||||
complete_destroy();
|
||||
proc_destroy();
|
||||
env_destroy();
|
||||
|
||||
222
parser.c
222
parser.c
@@ -101,12 +101,12 @@ The fish parser. Contains functions for parsing code.
|
||||
/**
|
||||
Error message when a non-string token is found when expecting a command name
|
||||
*/
|
||||
#define CMD_OR_ERR_MSG _( L"Expected a command name, got token of type '%ls'. Did you mean 'COMMAND; or COMMAND'? For more information on the 'or' builtin command, see the help section for 'or' by typing 'help or'.")
|
||||
#define CMD_OR_ERR_MSG _( L"Expected a command name, got token of type '%ls'. Did you mean 'COMMAND; or COMMAND'? See the help section for the 'or' builtin command by typing 'help or'.")
|
||||
|
||||
/**
|
||||
Error message when a non-string token is found when expecting a command name
|
||||
*/
|
||||
#define CMD_AND_ERR_MSG _( L"Expected a command name, got token of type '%ls'. Did you mean 'COMMAND; and COMMAND'? For more information on the 'and' builtin command, see the help section for 'and' by typing 'help and'.")
|
||||
#define CMD_AND_ERR_MSG _( L"Expected a command name, got token of type '%ls'. Did you mean 'COMMAND; and COMMAND'? See the help section for the 'and' builtin command by typing 'help and'.")
|
||||
|
||||
/**
|
||||
Error message when encountering an illegal command name
|
||||
@@ -165,7 +165,7 @@ The fish parser. Contains functions for parsing code.
|
||||
|
||||
|
||||
/**
|
||||
Error for wrong token type
|
||||
Error for wrong token type
|
||||
*/
|
||||
#define UNEXPECTED_TOKEN_ERR_MSG _( L"Unexpected token of type '%ls'")
|
||||
|
||||
@@ -176,78 +176,78 @@ The fish parser. Contains functions for parsing code.
|
||||
|
||||
|
||||
/**
|
||||
While block description
|
||||
While block description
|
||||
*/
|
||||
#define WHILE_BLOCK _( L"'while' block" )
|
||||
|
||||
|
||||
/**
|
||||
For block description
|
||||
For block description
|
||||
*/
|
||||
#define FOR_BLOCK _( L"'for' block" )
|
||||
|
||||
|
||||
/**
|
||||
If block description
|
||||
If block description
|
||||
*/
|
||||
#define IF_BLOCK _( L"'if' conditional block" )
|
||||
|
||||
|
||||
/**
|
||||
function definition block description
|
||||
Function definition block description
|
||||
*/
|
||||
#define FUNCTION_DEF_BLOCK _( L"function definition block" )
|
||||
|
||||
|
||||
/**
|
||||
Function invocation block description
|
||||
Function invocation block description
|
||||
*/
|
||||
#define FUNCTION_CALL_BLOCK _( L"function invocation block" )
|
||||
|
||||
|
||||
/**
|
||||
Switch block description
|
||||
Switch block description
|
||||
*/
|
||||
#define SWITCH_BLOCK _( L"'switch' block" )
|
||||
|
||||
|
||||
/**
|
||||
Fake block description
|
||||
Fake block description
|
||||
*/
|
||||
#define FAKE_BLOCK _( L"unexecutable block" )
|
||||
|
||||
|
||||
/**
|
||||
Top block description
|
||||
Top block description
|
||||
*/
|
||||
#define TOP_BLOCK _( L"global root block" )
|
||||
|
||||
|
||||
/**
|
||||
Command substitution block description
|
||||
Command substitution block description
|
||||
*/
|
||||
#define SUBST_BLOCK _( L"command substitution block" )
|
||||
|
||||
|
||||
/**
|
||||
Begin block description
|
||||
Begin block description
|
||||
*/
|
||||
#define BEGIN_BLOCK _( L"'begin' unconditional block" )
|
||||
|
||||
|
||||
/**
|
||||
Source block description
|
||||
Source block description
|
||||
*/
|
||||
#define SOURCE_BLOCK _( L"Block created by the . builtin" )
|
||||
|
||||
/**
|
||||
Source block description
|
||||
Source block description
|
||||
*/
|
||||
#define EVENT_BLOCK _( L"event handler block" )
|
||||
|
||||
|
||||
/**
|
||||
Unknown block description
|
||||
Unknown block description
|
||||
*/
|
||||
#define UNKNOWN_BLOCK _( L"unknown/invalid block" )
|
||||
|
||||
@@ -724,75 +724,85 @@ wchar_t *get_filename( const wchar_t *cmd )
|
||||
else
|
||||
{
|
||||
path = env_get(L"PATH");
|
||||
if( path != 0 )
|
||||
if( path == 0 )
|
||||
{
|
||||
/*
|
||||
Allocate string long enough to hold the whole command
|
||||
*/
|
||||
wchar_t *new_cmd = malloc( sizeof(wchar_t)*(wcslen(cmd)+wcslen(path)+2) );
|
||||
/*
|
||||
We tokenize a copy of the path, since strtok modifies
|
||||
its arguments
|
||||
*/
|
||||
wchar_t *path_cpy = wcsdup( path );
|
||||
wchar_t *nxt_path = path;
|
||||
wchar_t *state;
|
||||
|
||||
if( (new_cmd==0) || (path_cpy==0) )
|
||||
if( contains_str( PREFIX L"/bin", L"/bin", L"/usr/bin", (void *)0 ) )
|
||||
{
|
||||
die_mem();
|
||||
path = L"/bin" ARRAY_SEP_STR L"/usr/bin";
|
||||
}
|
||||
|
||||
for( nxt_path = wcstok( path_cpy, ARRAY_SEP_STR, &state );
|
||||
nxt_path != 0;
|
||||
nxt_path = wcstok( 0, ARRAY_SEP_STR, &state) )
|
||||
else
|
||||
{
|
||||
int path_len = wcslen( nxt_path );
|
||||
wcscpy( new_cmd, nxt_path );
|
||||
if( new_cmd[path_len-1] != L'/' )
|
||||
{
|
||||
new_cmd[path_len++]=L'/';
|
||||
}
|
||||
wcscpy( &new_cmd[path_len], cmd );
|
||||
if( waccess( new_cmd, X_OK )==0 )
|
||||
{
|
||||
struct stat buff;
|
||||
if( wstat( new_cmd, &buff )==-1 )
|
||||
{
|
||||
if( errno != EACCES )
|
||||
{
|
||||
wperror( L"stat" );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if( S_ISREG(buff.st_mode) )
|
||||
{
|
||||
free( path_cpy );
|
||||
return new_cmd;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( errno )
|
||||
{
|
||||
case ENOENT:
|
||||
case ENAMETOOLONG:
|
||||
case EACCES:
|
||||
case ENOTDIR:
|
||||
break;
|
||||
default:
|
||||
{
|
||||
debug( 1,
|
||||
MISSING_COMMAND_ERR_MSG,
|
||||
new_cmd );
|
||||
wperror( L"access" );
|
||||
}
|
||||
}
|
||||
}
|
||||
path = L"/bin" ARRAY_SEP_STR L"/usr/bin" ARRAY_SEP_STR PREFIX L"/bin";
|
||||
}
|
||||
free( path_cpy );
|
||||
free( new_cmd );
|
||||
}
|
||||
|
||||
/*
|
||||
Allocate string long enough to hold the whole command
|
||||
*/
|
||||
wchar_t *new_cmd = malloc( sizeof(wchar_t)*(wcslen(cmd)+wcslen(path)+2) );
|
||||
/*
|
||||
We tokenize a copy of the path, since strtok modifies
|
||||
its arguments
|
||||
*/
|
||||
wchar_t *path_cpy = wcsdup( path );
|
||||
wchar_t *nxt_path = path;
|
||||
wchar_t *state;
|
||||
|
||||
if( (new_cmd==0) || (path_cpy==0) )
|
||||
{
|
||||
die_mem();
|
||||
}
|
||||
|
||||
for( nxt_path = wcstok( path_cpy, ARRAY_SEP_STR, &state );
|
||||
nxt_path != 0;
|
||||
nxt_path = wcstok( 0, ARRAY_SEP_STR, &state) )
|
||||
{
|
||||
int path_len = wcslen( nxt_path );
|
||||
wcscpy( new_cmd, nxt_path );
|
||||
if( new_cmd[path_len-1] != L'/' )
|
||||
{
|
||||
new_cmd[path_len++]=L'/';
|
||||
}
|
||||
wcscpy( &new_cmd[path_len], cmd );
|
||||
if( waccess( new_cmd, X_OK )==0 )
|
||||
{
|
||||
struct stat buff;
|
||||
if( wstat( new_cmd, &buff )==-1 )
|
||||
{
|
||||
if( errno != EACCES )
|
||||
{
|
||||
wperror( L"stat" );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if( S_ISREG(buff.st_mode) )
|
||||
{
|
||||
free( path_cpy );
|
||||
return new_cmd;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( errno )
|
||||
{
|
||||
case ENOENT:
|
||||
case ENAMETOOLONG:
|
||||
case EACCES:
|
||||
case ENOTDIR:
|
||||
break;
|
||||
default:
|
||||
{
|
||||
debug( 1,
|
||||
MISSING_COMMAND_ERR_MSG,
|
||||
new_cmd );
|
||||
wperror( L"access" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free( path_cpy );
|
||||
free( new_cmd );
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1101,8 +1111,8 @@ int parser_get_lineno()
|
||||
int lineno;
|
||||
|
||||
/* static const wchar_t *prev_str = 0;
|
||||
static int i=0;
|
||||
static int lineno=1;
|
||||
static int i=0;
|
||||
static int lineno=1;
|
||||
*/
|
||||
if( !current_tokenizer )
|
||||
return -1;
|
||||
@@ -1241,8 +1251,8 @@ wchar_t *parser_current_line()
|
||||
|
||||
// debug( 1, L"Current pos %d, line pos %d, file_length %d, is_interactive %d, offset %d\n", current_tokenizer_pos, current_line_pos, wcslen(whole_str), is_interactive, offset);
|
||||
/*
|
||||
Skip printing character position if we are in interactive mode
|
||||
and the error was on the first character of the line.
|
||||
Skip printing character position if we are in interactive mode
|
||||
and the error was on the first character of the line.
|
||||
*/
|
||||
if( !is_interactive || is_function() || (current_line_width!=0) )
|
||||
{
|
||||
@@ -1716,8 +1726,8 @@ static int parse_job( process_t *p,
|
||||
else
|
||||
{
|
||||
error( SYNTAX_ERROR,
|
||||
tok_get_pos( tok ),
|
||||
CMD_ERR_MSG,
|
||||
tok_get_pos( tok ),
|
||||
CMD_ERR_MSG,
|
||||
tok_get_desc( tok_last_type(tok) ) );
|
||||
}
|
||||
|
||||
@@ -1926,8 +1936,8 @@ static int parse_job( process_t *p,
|
||||
if( !p->type || (p->type == INTERNAL_EXEC) )
|
||||
{
|
||||
/*
|
||||
If we are not executing the current block, allow
|
||||
non-existent commands.
|
||||
If we are not executing the current block, allow
|
||||
non-existent commands.
|
||||
*/
|
||||
if( current_block->skip )
|
||||
{
|
||||
@@ -1971,7 +1981,8 @@ static int parse_job( process_t *p,
|
||||
else
|
||||
{
|
||||
int tmp;
|
||||
|
||||
wchar_t *cmd = (wchar_t *)al_get( args, 0 );
|
||||
|
||||
/*
|
||||
We couln't find the specified command.
|
||||
|
||||
@@ -1986,19 +1997,42 @@ static int parse_job( process_t *p,
|
||||
cause the job to silently not execute. We
|
||||
also print an error message.
|
||||
*/
|
||||
if( wcschr( (wchar_t *)al_get( args, 0 ), L'=' ) )
|
||||
if( wcschr( cmd, L'=' ) )
|
||||
{
|
||||
debug( 0,
|
||||
COMMAND_ASSIGN_ERR_MSG,
|
||||
(wchar_t *)al_get( args, 0 ) );
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
else if(cmd[0]==L'$')
|
||||
{
|
||||
wchar_t *val = env_get( cmd+1 );
|
||||
if( val )
|
||||
{
|
||||
debug( 0,
|
||||
_(L"Variables may not be used as commands. Instead, define a function like 'function %ls; %ls $argv; end'. See the help section for the function command by typing 'help function'." ),
|
||||
cmd+1,
|
||||
val,
|
||||
cmd );
|
||||
}
|
||||
else
|
||||
{
|
||||
debug( 0,
|
||||
_(L"Variables may not be used as commands. Instead, define a function. See the help section for the function command by typing 'help function'." ),
|
||||
cmd );
|
||||
}
|
||||
}
|
||||
else if(wcschr( cmd, L'$' ))
|
||||
{
|
||||
debug( 0,
|
||||
_(L"Commands may not contain variables. Use the eval builtin instead, like 'eval %ls'. See the help section for the eval command by typing 'help eval'." ),
|
||||
cmd,
|
||||
cmd );
|
||||
}
|
||||
else
|
||||
{
|
||||
debug( 0,
|
||||
_(L"Unknown command '%ls'"),
|
||||
(wchar_t *)al_get( args, 0 ) );
|
||||
cmd );
|
||||
}
|
||||
|
||||
tmp = current_tokenizer_pos;
|
||||
@@ -2482,7 +2516,7 @@ int eval( const wchar_t *cmd, io_data_t *io, int block_type )
|
||||
}
|
||||
|
||||
/*
|
||||
Restore previous eval state
|
||||
Restore previous eval state
|
||||
*/
|
||||
forbidden_function = prev_forbidden;
|
||||
current_tokenizer=previous_tokenizer;
|
||||
|
||||
2
reader.c
2
reader.c
@@ -1631,7 +1631,6 @@ static void reader_interactive_init()
|
||||
|
||||
|
||||
al_init( &prompt_list );
|
||||
history_init();
|
||||
|
||||
common_handle_winch(0);
|
||||
|
||||
@@ -1658,7 +1657,6 @@ static void reader_interactive_destroy()
|
||||
kill_destroy();
|
||||
al_foreach( &prompt_list, (void (*)(const void *))&free );
|
||||
al_destroy( &prompt_list );
|
||||
history_destroy();
|
||||
|
||||
writestr( L"\n" );
|
||||
set_color( FISH_COLOR_RESET, FISH_COLOR_RESET );
|
||||
|
||||
@@ -18,7 +18,7 @@ if test "$USER" = root
|
||||
end
|
||||
|
||||
for i in $path_list
|
||||
if not expr "$PATH" : .\*$i.\* >/dev/null
|
||||
if not expr "$PATH" : "$i/*" >/dev/null
|
||||
if test -d $i
|
||||
set PATH $PATH $i
|
||||
end
|
||||
@@ -43,8 +43,8 @@ end
|
||||
# Convenience functions
|
||||
#
|
||||
# The naming heuristic is that __fish_complete_* prints completions
|
||||
# and descriptions, while __fish_print_* only prints the completion,
|
||||
# without the description
|
||||
# and descriptions, while __fish_print_* only prints the completions
|
||||
# and no descriptions
|
||||
#
|
||||
|
||||
function __fish_complete_users -d "Print a list of local users, with the real user name as a description"
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
#
|
||||
# This file defines various shellscript functions. Most of them are
|
||||
# meant to be used directly by the user, but some of them, typically
|
||||
# the ones whose name start with '__fish_', are only meant to be used
|
||||
# internally by fish.
|
||||
#
|
||||
|
||||
function contains -d (N_ "Test if a key is contained in a set of values")
|
||||
while set -q argv
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
function type -d (N_ "Print the type of a command")
|
||||
|
||||
# Initialize
|
||||
set -l status 1
|
||||
set -l res 1
|
||||
set -l mode normal
|
||||
set -l selection all
|
||||
|
||||
@@ -66,7 +66,7 @@ function type -d (N_ "Print the type of a command")
|
||||
if test $selection != files
|
||||
|
||||
if contains -- $i (functions -na)
|
||||
set status 0
|
||||
set res 0
|
||||
set found 1
|
||||
switch $mode
|
||||
case normal
|
||||
@@ -86,7 +86,8 @@ function type -d (N_ "Print the type of a command")
|
||||
end
|
||||
|
||||
if contains -- $i (builtin -n)
|
||||
set status 0
|
||||
|
||||
set res 0
|
||||
set found 1
|
||||
switch $mode
|
||||
case normal
|
||||
@@ -107,7 +108,7 @@ function type -d (N_ "Print the type of a command")
|
||||
|
||||
set -l path (which $i ^/dev/null)
|
||||
if test -x (echo $path)
|
||||
set status 0
|
||||
set res 0
|
||||
set found 1
|
||||
switch $mode
|
||||
case normal
|
||||
@@ -130,6 +131,6 @@ function type -d (N_ "Print the type of a command")
|
||||
|
||||
end
|
||||
|
||||
return $status
|
||||
return $res
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user