mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-23 13:11:15 -03:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8d58e58d7b | ||
|
|
c8c3715aac | ||
|
|
7ffcebb9f8 | ||
|
|
831d95b600 | ||
|
|
0ffeb41c28 | ||
|
|
e8d02159da | ||
|
|
b78fba810c | ||
|
|
43213ee458 | ||
|
|
da316dd588 | ||
|
|
c8bc79005c | ||
|
|
5ba0affdd7 | ||
|
|
721f616964 | ||
|
|
ef4345968e | ||
|
|
319956c26b |
@@ -106,7 +106,7 @@ CMD_DOC_SRC := doc_src/count.txt doc_src/dirh.txt doc_src/dirs.txt \
|
||||
doc_src/nextd.txt doc_src/open.txt doc_src/popd.txt \
|
||||
doc_src/prevd.txt doc_src/psub.txt doc_src/pushd.txt \
|
||||
doc_src/set_color.txt doc_src/tokenize.txt doc_src/type.txt \
|
||||
doc_src/umask.txt
|
||||
doc_src/umask.txt doc_src/vared.txt
|
||||
|
||||
#
|
||||
# Files generated by running doxygen on the files in $(CMD_DOC_SRC)
|
||||
|
||||
@@ -2573,7 +2573,8 @@ static int builtin_end( wchar_t **argv )
|
||||
parser_get_job_pos()-current_block->tok_pos );
|
||||
|
||||
//fwprintf( stderr, L"Function: %ls\n", def );
|
||||
if( !parser_test( def, 1 ) )
|
||||
|
||||
if( !is_interactive || !parser_test( def, 1 ) )
|
||||
{
|
||||
function_add( current_block->param1.function_name,
|
||||
def,
|
||||
|
||||
2
common.c
2
common.c
@@ -299,7 +299,7 @@ char *wcs2str( const wchar_t *in )
|
||||
in,
|
||||
MAX_UTF8_BYTES*wcslen(in)+1 );
|
||||
|
||||
res = realloc( res, strlen( res )+1 );
|
||||
// res = realloc( res, strlen( res )+1 );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
12
configure.ac
12
configure.ac
@@ -1,5 +1,5 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(fish,1.16.1,axel@liljencrantz.se)
|
||||
AC_INIT(fish,1.16.2,axel@liljencrantz.se)
|
||||
|
||||
AC_CANONICAL_TARGET
|
||||
|
||||
@@ -36,20 +36,14 @@ else
|
||||
fi
|
||||
|
||||
if [[ "$prefix" = NONE ]]; then
|
||||
AC_DEFINE_UNQUOTED( [PREFIX], L"/usr/local", [Installation directory])
|
||||
AC_DEFINE_UNQUOTED( [PREFIX], L"/usr/local", [Installation directory])
|
||||
AC_SUBST( PREFIX, /usr/local)
|
||||
AC_SUBST(sysconfdir,[/etc])
|
||||
export prefix=/usr/local
|
||||
else
|
||||
AC_DEFINE_UNQUOTED( [PREFIX], L"$prefix", [Installation directory])
|
||||
AC_SUBST( PREFIX, [$prefix])
|
||||
AC_SUBST(sysconfdir,[/etc])
|
||||
fi
|
||||
|
||||
if echo $prefix | grep \^$HOME >/dev/null; then
|
||||
AC_SUBST(sysconfdir,[$HOME/etc])
|
||||
AC_MSG_NOTICE(["Install in $HOME"])
|
||||
fi
|
||||
AC_SUBST(fishdir,[/fish.d])
|
||||
AC_SUBST(fishfile,[/fish])
|
||||
AC_SUBST(fishinputfile,[/fish_inputrc])
|
||||
@@ -61,7 +55,7 @@ if test -z $docdir; then
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED( DOCDIR, [L"$(eval echo $docdir)"], [Documentation directory] )
|
||||
AC_DEFINE_UNQUOTED( SYSCONFDIR, [L"$sysconfdir"], [System configuration directory] )
|
||||
AC_DEFINE_UNQUOTED( SYSCONFDIR, [L"$(eval echo $sysconfdir)"], [System configuration directory] )
|
||||
|
||||
# See if Linux procfs is present
|
||||
AC_CHECK_FILES([/proc/self/stat])
|
||||
|
||||
15
doc_src/vared.txt
Normal file
15
doc_src/vared.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
\section vared vared - Interactively edit the value of an environment variable
|
||||
|
||||
\subsection vared-synopsis Synopsis
|
||||
<tt>vared VARIABLE_NAME</tt>
|
||||
|
||||
\subsection vared-description Description
|
||||
|
||||
vared is used to interactively edit the value of an environment
|
||||
variable. Array variables as a whole can not be edited using vared,
|
||||
but individual array elements can.
|
||||
|
||||
\subsection vared-example Example
|
||||
|
||||
<code>vared PATH[3]</code> edits the third element of the PATH array
|
||||
62
exec.c
62
exec.c
@@ -103,7 +103,7 @@ void exec_close( int fd )
|
||||
int exec_pipe( int fd[2])
|
||||
{
|
||||
int res;
|
||||
|
||||
|
||||
while( ( res=pipe( fd ) ) )
|
||||
{
|
||||
if( errno != EINTR )
|
||||
@@ -111,23 +111,18 @@ int exec_pipe( int fd[2])
|
||||
wperror(L"pipe");
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug( 4, L"Created pipe using fds %d and %d", fd[0], fd[1]);
|
||||
|
||||
if( open_fds == 0 )
|
||||
{
|
||||
open_fds = malloc( sizeof( array_list_t ) );
|
||||
if(!open_fds )
|
||||
die_mem();
|
||||
al_init( open_fds );
|
||||
open_fds = al_new();
|
||||
}
|
||||
|
||||
if( res != -1 )
|
||||
{
|
||||
debug( 4, L"Created pipe using fds %d and %d", fd[0], fd[1]);
|
||||
|
||||
al_push( open_fds, (void *)(long)fd[0] );
|
||||
al_push( open_fds, (void *)(long)fd[1] );
|
||||
}
|
||||
al_push( open_fds, (void *)(long)fd[0] );
|
||||
al_push( open_fds, (void *)(long)fd[1] );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -183,7 +178,6 @@ static void close_unused_internal_pipes( io_data_t *io )
|
||||
|
||||
void exec_init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void exec_destroy()
|
||||
@@ -672,7 +666,7 @@ void exec( job_t *j )
|
||||
pipe_write.io_mode=IO_PIPE;
|
||||
pipe_read.next=0;
|
||||
pipe_write.next=0;
|
||||
pipe_write.param1.pipe_fd[0]=pipe_write.param1.pipe_fd[1]=0;
|
||||
pipe_write.param1.pipe_fd[0]=pipe_write.param1.pipe_fd[1]=-1;
|
||||
|
||||
//fwprintf( stderr, L"Run command %ls\n", j->command );
|
||||
|
||||
@@ -696,7 +690,7 @@ void exec( job_t *j )
|
||||
The loop also has to handle pipelining between the jobs.
|
||||
*/
|
||||
|
||||
for (p = j->first_process; p; p = p->next)
|
||||
for( p=j->first_process; p; p = p->next )
|
||||
{
|
||||
mypipe[1]=-1;
|
||||
skip_fork=0;
|
||||
@@ -722,9 +716,11 @@ void exec( job_t *j )
|
||||
j->io = io_add( j->io, &pipe_read );
|
||||
}
|
||||
|
||||
if (p->next)
|
||||
if( p->next )
|
||||
{
|
||||
if (exec_pipe( mypipe ) == -1)
|
||||
// debug( 1, L"%ls|%ls" , p->argv[0], p->next->argv[0]);
|
||||
|
||||
if( exec_pipe( mypipe ) == -1 )
|
||||
{
|
||||
debug( 1, PIPE_ERROR );
|
||||
wperror (L"pipe");
|
||||
@@ -775,7 +771,7 @@ void exec( job_t *j )
|
||||
{
|
||||
sb_init( &sb );
|
||||
|
||||
for( i=1,arg = p->argv+1; *arg; i++, arg++ )
|
||||
for( i=1, arg=p->argv+1; *arg; i++, arg++ )
|
||||
{
|
||||
if( i != 1 )
|
||||
sb_append( &sb, ARRAY_SEP_STR );
|
||||
@@ -948,7 +944,7 @@ void exec( job_t *j )
|
||||
to buffer such io, since otherwisethe internal pipe
|
||||
buffer might overflow.
|
||||
*/
|
||||
if( !io_buffer)
|
||||
if( !io_buffer )
|
||||
{
|
||||
p->completed = 1;
|
||||
break;
|
||||
@@ -962,8 +958,8 @@ void exec( job_t *j )
|
||||
{
|
||||
|
||||
|
||||
pid = fork ();
|
||||
if (pid == 0)
|
||||
pid = fork();
|
||||
if( pid == 0 )
|
||||
{
|
||||
/*
|
||||
This is the child process. Write out the contents of the pipeline.
|
||||
@@ -975,7 +971,7 @@ void exec( job_t *j )
|
||||
io_buffer->param2.out_buffer->used );
|
||||
exit( status );
|
||||
}
|
||||
else if (pid < 0)
|
||||
else if( pid < 0 )
|
||||
{
|
||||
/* The fork failed. */
|
||||
debug( 0, FORK_ERROR );
|
||||
@@ -1024,7 +1020,7 @@ void exec( job_t *j )
|
||||
|
||||
io_data_t *io = io_get( j->io, 1 );
|
||||
int buffer_stdout = io && io->io_mode == IO_BUFFER;
|
||||
|
||||
|
||||
if( ( !sb_err->used ) &&
|
||||
( !p->next ) &&
|
||||
( sb_out->used ) &&
|
||||
@@ -1050,10 +1046,9 @@ void exec( job_t *j )
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
pid = fork ();
|
||||
if (pid == 0)
|
||||
pid = fork();
|
||||
if( pid == 0 )
|
||||
{
|
||||
/*
|
||||
This is the child process.
|
||||
@@ -1068,7 +1063,7 @@ void exec( job_t *j )
|
||||
exit( p->status );
|
||||
|
||||
}
|
||||
else if (pid < 0)
|
||||
else if( pid < 0 )
|
||||
{
|
||||
/* The fork failed. */
|
||||
debug( 0, FORK_ERROR );
|
||||
@@ -1098,7 +1093,7 @@ void exec( job_t *j )
|
||||
// fwprintf( stderr,
|
||||
// L"fork on %ls\n", j->command );
|
||||
pid = fork ();
|
||||
if (pid == 0)
|
||||
if( pid == 0 )
|
||||
{
|
||||
/*
|
||||
This is the child process.
|
||||
@@ -1111,7 +1106,7 @@ void exec( job_t *j )
|
||||
launch_process _never_ returns...
|
||||
*/
|
||||
}
|
||||
else if (pid < 0)
|
||||
else if( pid < 0 )
|
||||
{
|
||||
/* The fork failed. */
|
||||
debug( 0, FORK_ERROR );
|
||||
@@ -1138,11 +1133,10 @@ void exec( job_t *j )
|
||||
}
|
||||
|
||||
|
||||
if(p->type == INTERNAL_BUILTIN)
|
||||
if( p->type == INTERNAL_BUILTIN )
|
||||
builtin_pop_io();
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Close the pipe the current process uses to read from the previous process_t
|
||||
*/
|
||||
@@ -1223,7 +1217,7 @@ int exec_subshell( const wchar_t *cmd,
|
||||
b_append( io_buffer->param2.out_buffer, &z, 1 );
|
||||
|
||||
begin=end=io_buffer->param2.out_buffer->buff;
|
||||
|
||||
|
||||
if( l )
|
||||
{
|
||||
while( 1 )
|
||||
|
||||
73
expand.c
73
expand.c
@@ -78,7 +78,43 @@ parameter expansion.
|
||||
#define LAST_STR L"last"
|
||||
|
||||
/**
|
||||
Return the environment variable value for the string starting at in
|
||||
Characters which make a string unclean if they are the first
|
||||
character of the string. See \c is_clean().
|
||||
*/
|
||||
#define UNCLEAN_FIRST L"~%"
|
||||
/**
|
||||
Unclean characters. See \c is_clean().
|
||||
*/
|
||||
#define UNCLEAN L"$*?\\\"'({})"
|
||||
|
||||
/**
|
||||
Test if the specified argument is clean, i.e. it does not contain
|
||||
any tokens which need to be expanded or otherwise altered. Clean
|
||||
strings can be passed through expand_string and expand_one without
|
||||
changing them. About 90% of all strings are clean, so skipping
|
||||
expantion on them actually does save a small amount of time.
|
||||
*/
|
||||
static int is_clean( const wchar_t *in )
|
||||
{
|
||||
|
||||
const wchar_t * str = in;
|
||||
|
||||
if( wcschr( UNCLEAN_FIRST, *str ) )
|
||||
return 0;
|
||||
while( *str )
|
||||
{
|
||||
if( wcschr( UNCLEAN, *str ) )
|
||||
return 0;
|
||||
str++;
|
||||
}
|
||||
|
||||
// debug( 1, L"%ls", in );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
Return the environment variable value for the string starting at \c in.
|
||||
*/
|
||||
static wchar_t *expand_var( wchar_t *in )
|
||||
{
|
||||
@@ -1085,9 +1121,7 @@ static int expand_subshell( wchar_t *in, array_list_t *out )
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
len1 = (paran_begin-in);
|
||||
len2 = wcslen(paran_end)-1;
|
||||
@@ -1111,10 +1145,10 @@ static int expand_subshell( wchar_t *in, array_list_t *out )
|
||||
free( subcmd );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
al_init( &tail_expand );
|
||||
expand_subshell( wcsdup(paran_end+1), &tail_expand );
|
||||
|
||||
|
||||
for( i=0; i<al_get_count( &sub_res ); i++ )
|
||||
{
|
||||
wchar_t *sub_item, *sub_item2;
|
||||
@@ -1122,20 +1156,20 @@ static int expand_subshell( wchar_t *in, array_list_t *out )
|
||||
sub_item2 = expand_escape( sub_item, 1 );
|
||||
free(sub_item);
|
||||
int item_len = wcslen( sub_item2 );
|
||||
|
||||
|
||||
for( j=0; j<al_get_count( &tail_expand ); j++ )
|
||||
{
|
||||
string_buffer_t whole_item;
|
||||
wchar_t *tail_item = (wchar_t *)al_get( &tail_expand, j );
|
||||
|
||||
|
||||
sb_init( &whole_item );
|
||||
|
||||
|
||||
sb_append_substring( &whole_item, in, len1 );
|
||||
sb_append_char( &whole_item, INTERNAL_SEPARATOR );
|
||||
sb_append_substring( &whole_item, sub_item2, item_len );
|
||||
sb_append_char( &whole_item, INTERNAL_SEPARATOR );
|
||||
sb_append( &whole_item, tail_item );
|
||||
|
||||
|
||||
al_push( out, whole_item.buff );
|
||||
}
|
||||
|
||||
@@ -1147,7 +1181,7 @@ static int expand_subshell( wchar_t *in, array_list_t *out )
|
||||
|
||||
al_foreach( &tail_expand, (void (*)(const void *))&free );
|
||||
al_destroy( &tail_expand );
|
||||
|
||||
|
||||
free( subcmd );
|
||||
return 1;
|
||||
}
|
||||
@@ -1210,7 +1244,7 @@ static int tilde_expand( wchar_t **ptr )
|
||||
old_in = name_end;
|
||||
|
||||
char *name_str = wcs2str( name );
|
||||
|
||||
|
||||
struct passwd *userinfo =
|
||||
getpwnam( name_str );
|
||||
|
||||
@@ -1311,7 +1345,13 @@ int expand_string( wchar_t *str,
|
||||
|
||||
int i;
|
||||
int subshell_ok = 1;
|
||||
|
||||
|
||||
if( (!(flags & ACCEPT_INCOMPLETE)) && is_clean( str ) )
|
||||
{
|
||||
al_push( end_out, str );
|
||||
return 1;
|
||||
}
|
||||
|
||||
al_init( &list1 );
|
||||
al_init( &list2 );
|
||||
|
||||
@@ -1355,7 +1395,7 @@ int expand_string( wchar_t *str,
|
||||
for( i=0; i<al_get_count( in ); i++ )
|
||||
{
|
||||
wchar_t *next;
|
||||
|
||||
|
||||
next = expand_unescape( (wchar_t *)al_get( in, i ),
|
||||
1);
|
||||
|
||||
@@ -1501,6 +1541,9 @@ wchar_t *expand_one( wchar_t *string, int flags )
|
||||
array_list_t l;
|
||||
int res;
|
||||
wchar_t *one;
|
||||
|
||||
if( (!(flags & ACCEPT_INCOMPLETE)) && is_clean( string ) )
|
||||
return string;
|
||||
|
||||
al_init( &l );
|
||||
res = expand_string( string, &l, flags );
|
||||
@@ -1520,7 +1563,7 @@ wchar_t *expand_one( wchar_t *string, int flags )
|
||||
al_set( &l, 0, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
al_foreach( &l, (void(*)(const void *))&free );
|
||||
al_destroy( &l );
|
||||
return one;
|
||||
|
||||
@@ -38,6 +38,9 @@
|
||||
#include "expand.h"
|
||||
#include "parser.h"
|
||||
#include "tokenizer.h"
|
||||
#include "output.h"
|
||||
#include "exec.h"
|
||||
#include "event.h"
|
||||
|
||||
/**
|
||||
Number of laps to run performance testing loop
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
#Completions for make
|
||||
complete -x -c make -a "(grep -h -E '^[^#%=\t$][^#%=$]*:([^=]|$)' Makefile makefile GNUmakefile | cut -d ":" -f 1 | sed -r 's/^ *//;s/ *$//;s/ +/\n/g' ^/dev/null)" -d "Target"
|
||||
|
||||
function __fish_print_make_targets
|
||||
set files Makefile makefile GNUmakefile
|
||||
grep -h -E '^[^#%=$[:space:]][^#%=$]*:([^=]|$)' $files | cut -d ":" -f 1 | sed -r 's/^ *//;s/ *$//;s/ +/\n/g' ^/dev/null
|
||||
end
|
||||
|
||||
complete -x -c make -a "(__fish_print_make_targets)" -d "Target"
|
||||
complete -r -c make -s f -d "Use file as makefile" -r
|
||||
complete -x -c make -s C -x -a "(__fish_complete_directory (commandline -ct))" -d "Change directory"
|
||||
complete -c make -s d -d "Debug"
|
||||
|
||||
@@ -32,7 +32,7 @@ function _contains_help -d "Helper function for contains"
|
||||
end
|
||||
|
||||
function contains -d "Test if a key is contained in a set of values"
|
||||
while count $argv >/dev/null
|
||||
while set -q argv
|
||||
switch $argv[1]
|
||||
case '-h' '--h' '--he' '--hel' '--help'
|
||||
_contains_help
|
||||
@@ -56,8 +56,7 @@ function contains -d "Test if a key is contained in a set of values"
|
||||
set -e argv[1]
|
||||
end
|
||||
|
||||
if count $argv >/dev/null
|
||||
else
|
||||
if not set -q argv
|
||||
echo "contains: Key not specified"
|
||||
return 1
|
||||
end
|
||||
@@ -288,18 +287,18 @@ function vared -d "Edit variable value"
|
||||
else
|
||||
|
||||
printf "vared: %s is an array variable. Use " $argv
|
||||
set_color $FISH_COLOR_COMMAND
|
||||
set_color $fish_color_command
|
||||
printf vared
|
||||
set_color $FISH_COLOR_NORMAL
|
||||
set_color $fish_color_normal
|
||||
printf " %s[n] to edit the n:th element of %s\n" $argv $argv
|
||||
|
||||
end
|
||||
end
|
||||
else
|
||||
printf "vared: Expected exactly one argument, got %s.\n\nSynopsis:\n\t" (count $argv)
|
||||
set_color $FISH_COLOR_COMMAND
|
||||
set_color $fish_color_command
|
||||
printf vared
|
||||
set_color $FISH_COLOR_NORMAL
|
||||
set_color $fish_color_normal
|
||||
printf " VARIABLE\n"
|
||||
end
|
||||
end
|
||||
@@ -928,6 +927,9 @@ end
|
||||
|
||||
function psub -d "Read from stdin into a file and output the filename. Remove the file when the command that calles psub exits."
|
||||
|
||||
set -l filename
|
||||
set -l funcname
|
||||
|
||||
if count $argv >/dev/null
|
||||
switch $argv[1]
|
||||
case '-h*' --h --he --hel --help
|
||||
|
||||
@@ -58,7 +58,7 @@ function set_default_color -d "Set an universal variable, unless it has already
|
||||
set -U -- $argv
|
||||
return
|
||||
end
|
||||
if contains $$argv[1] (set_color --print-colors)
|
||||
if contains -- $$argv[1] (set_color --print-colors)
|
||||
return
|
||||
end
|
||||
set -U -- $argv
|
||||
|
||||
1
io.c
1
io.c
@@ -95,7 +95,6 @@ io_data_t *io_buffer_create()
|
||||
b_init( buffer_redirect->param2.out_buffer );
|
||||
buffer_redirect->fd=1;
|
||||
|
||||
|
||||
if( exec_pipe( buffer_redirect->param1.pipe_fd ) == -1 )
|
||||
{
|
||||
debug( 1, PIPE_ERROR );
|
||||
|
||||
9
main.c
9
main.c
@@ -202,25 +202,26 @@ int main( int argc, char **argv )
|
||||
is_interactive_session &= (cmd == 0);
|
||||
is_interactive_session &= (my_optind == argc);
|
||||
is_interactive_session &= isatty(STDIN_FILENO);
|
||||
|
||||
|
||||
// fwprintf( stderr, L"%d %d %d\n", cmd==0, my_optind == argc, isatty(STDIN_FILENO) );
|
||||
|
||||
if( force_interactive )
|
||||
is_interactive_session=1;
|
||||
|
||||
|
||||
proc_init();
|
||||
output_init();
|
||||
event_init();
|
||||
exec_init();
|
||||
wutil_init();
|
||||
parser_init();
|
||||
builtin_init();
|
||||
function_init();
|
||||
env_init();
|
||||
complete_init();
|
||||
reader_init();
|
||||
|
||||
|
||||
reader_push_current_filename( L"(internal)" );
|
||||
|
||||
|
||||
if( read_init() )
|
||||
{
|
||||
if( cmd != 0 )
|
||||
|
||||
1
proc.c
1
proc.c
@@ -486,7 +486,6 @@ static void fire_process_event( const wchar_t *msg, int type, pid_t pid, int sta
|
||||
{
|
||||
static event_t ev;
|
||||
event_t e;
|
||||
|
||||
|
||||
e.function_name=0;
|
||||
|
||||
|
||||
7
reader.c
7
reader.c
@@ -93,7 +93,7 @@ commence.
|
||||
|
||||
/**
|
||||
The maximum number of characters to read from the keyboard without
|
||||
repainting. Note that this readahead wil only occur if new
|
||||
repainting. Note that this readahead will only occur if new
|
||||
characters are avaialble for reading, fish will never block for
|
||||
more input without repainting.
|
||||
*/
|
||||
@@ -1007,12 +1007,13 @@ static int insert_str(wchar_t *str)
|
||||
}
|
||||
else
|
||||
{
|
||||
int old_len = data->buff_len;
|
||||
|
||||
data->buff_len += len;
|
||||
check_size();
|
||||
|
||||
/* Insert space for extra character at the right position */
|
||||
if( data->buff_pos < data->buff_len )
|
||||
/* Insert space for extra characters at the right position */
|
||||
if( data->buff_pos < old_len )
|
||||
{
|
||||
memmove( &data->buff[data->buff_pos+len],
|
||||
&data->buff[data->buff_pos],
|
||||
|
||||
2
signal.c
2
signal.c
@@ -500,5 +500,3 @@ void signal_unblock()
|
||||
|
||||
sigprocmask(SIG_UNBLOCK, &chldset, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
21
tokenizer.c
21
tokenizer.c
@@ -46,7 +46,7 @@
|
||||
/**
|
||||
Characters that separate tokens. They are ordered by frequency of occurrence to increase parsing speed.
|
||||
*/
|
||||
#define SEP L" \n;|#\t\r<>^&"
|
||||
#define SEP L" \n|\t;#\r<>^&"
|
||||
/**
|
||||
Tests if the tokenizer buffer is large enough to hold contents of
|
||||
the specified length, and if not, reallocates the tokenizer buffer.
|
||||
@@ -192,8 +192,18 @@ static int is_string_char( wchar_t c )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
/**
|
||||
Quick test to catch the most common 'non-magical' characters, makes
|
||||
read_string slightly faster by adding a fast path for the most
|
||||
common characters. This is obviously not a suitable replacement for
|
||||
iswalpha.
|
||||
*/
|
||||
static int myal( wchar_t c )
|
||||
{
|
||||
return (c>=L'a' && c<=L'z') || (c>=L'A'&&c<=L'Z');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -212,6 +222,11 @@ static void read_string( tokenizer *tok )
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
|
||||
if( !myal( *tok->buff ) )
|
||||
{
|
||||
// debug(1, L"%lc", *tok->buff );
|
||||
|
||||
if( *tok->buff == L'\\' )
|
||||
{
|
||||
tok->buff++;
|
||||
@@ -338,6 +353,8 @@ static void read_string( tokenizer *tok )
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( !do_loop )
|
||||
break;
|
||||
|
||||
57
util.c
57
util.c
@@ -27,11 +27,16 @@
|
||||
#include "wutil.h"
|
||||
|
||||
/**
|
||||
Minimum allocated size for data structures. Used to avoid excessive
|
||||
memory allocations for lists, hash tables, etc, which are nearly
|
||||
empty.
|
||||
Minimum allocated size for data structures. Used to avoid excessive
|
||||
memory allocations for lists, hash tables, etc, which are nearly
|
||||
empty.
|
||||
*/
|
||||
#define MIN_SIZE 128
|
||||
#define MIN_SIZE 32
|
||||
|
||||
/**
|
||||
Minimum size for hash tables
|
||||
*/
|
||||
#define HASH_MIN_SIZE 7
|
||||
|
||||
/**
|
||||
Maximum number of characters that can be inserted using a single
|
||||
@@ -191,7 +196,11 @@ void hash_init( hash_table_t *h,
|
||||
int (*hash_func)(const void *key),
|
||||
int (*compare_func)(const void *key1, const void *key2) )
|
||||
{
|
||||
hash_init2( h, hash_func, compare_func, 31 );
|
||||
h->arr = 0;
|
||||
h->size = 0;
|
||||
h->count=0;
|
||||
h->hash_func = hash_func;
|
||||
h->compare_func = compare_func;
|
||||
}
|
||||
|
||||
|
||||
@@ -207,8 +216,11 @@ void hash_destroy( hash_table_t *h )
|
||||
static int hash_search( hash_table_t *h,
|
||||
const void *key )
|
||||
{
|
||||
int hv = h->hash_func( key );
|
||||
int pos = abs(hv) % h->size;
|
||||
int hv;
|
||||
int pos;
|
||||
|
||||
hv = h->hash_func( key );
|
||||
pos = abs(hv) % h->size;
|
||||
while(1)
|
||||
{
|
||||
if( (h->arr[pos].key == 0 ) ||
|
||||
@@ -229,13 +241,13 @@ static int hash_realloc( hash_table_t *h,
|
||||
{
|
||||
|
||||
/* Avoid reallocating when using pathetically small tables */
|
||||
if( ( sz < h->size ) && (h->size < MIN_SIZE))
|
||||
if( ( sz < h->size ) && (h->size < HASH_MIN_SIZE))
|
||||
return 1;
|
||||
sz = maxi( sz, MIN_SIZE );
|
||||
|
||||
sz = maxi( sz, HASH_MIN_SIZE );
|
||||
|
||||
hash_struct_t *old_arr = h->arr;
|
||||
int old_size = h->size;
|
||||
|
||||
|
||||
int i;
|
||||
|
||||
h->arr = malloc( sizeof( hash_struct_t) * sz );
|
||||
@@ -294,7 +306,10 @@ int hash_put( hash_table_t *h,
|
||||
const void *hash_get( hash_table_t *h,
|
||||
const void *key )
|
||||
{
|
||||
int pos = hash_search( h, key );
|
||||
if( !h->count )
|
||||
return 0;
|
||||
|
||||
int pos = hash_search( h, key );
|
||||
if( h->arr[pos].key == 0 )
|
||||
return 0;
|
||||
else
|
||||
@@ -303,7 +318,10 @@ const void *hash_get( hash_table_t *h,
|
||||
|
||||
const void *hash_get_key( hash_table_t *h,
|
||||
const void *key )
|
||||
{
|
||||
{
|
||||
if( !h->count )
|
||||
return 0;
|
||||
|
||||
int pos = hash_search( h, key );
|
||||
if( h->arr[pos].key == 0 )
|
||||
return 0;
|
||||
@@ -321,6 +339,16 @@ void hash_remove( hash_table_t *h,
|
||||
const void **old_key,
|
||||
const void **old_val )
|
||||
{
|
||||
if( !h->count )
|
||||
{
|
||||
|
||||
if( old_key != 0 )
|
||||
*old_key = 0;
|
||||
if( old_val != 0 )
|
||||
*old_val = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
int pos = hash_search( h, key );
|
||||
int next_pos;
|
||||
|
||||
@@ -377,6 +405,9 @@ void hash_remove( hash_table_t *h,
|
||||
int hash_contains( hash_table_t *h,
|
||||
const void *key )
|
||||
{
|
||||
if( !h->count )
|
||||
return 0;
|
||||
|
||||
int pos = hash_search( h, key );
|
||||
return h->arr[pos].key != 0;
|
||||
}
|
||||
|
||||
77
util.h
77
util.h
@@ -136,14 +136,17 @@ typedef buffer_t string_buffer_t;
|
||||
Returns the larger of two ints
|
||||
*/
|
||||
int maxi( int a, int b );
|
||||
|
||||
/**
|
||||
Returns the smaller of two ints
|
||||
*/
|
||||
int mini( int a, int b );
|
||||
|
||||
/**
|
||||
Returns the larger of two floats
|
||||
*/
|
||||
float maxf( float a, float b );
|
||||
|
||||
/**
|
||||
Returns the smaller of two floats
|
||||
*/
|
||||
@@ -161,14 +164,19 @@ float minf( float a, float b );
|
||||
returned.
|
||||
*/
|
||||
void q_init( dyn_queue_t *q );
|
||||
|
||||
/** Destroy the queue */
|
||||
void q_destroy( dyn_queue_t *q );
|
||||
|
||||
/** Insert element into queue */
|
||||
int q_put( dyn_queue_t *q, void *e );
|
||||
|
||||
/** Remove and return next element from queue */
|
||||
void *q_get( dyn_queue_t *q);
|
||||
|
||||
/** Return next element from queue without removing it */
|
||||
void *q_peek( dyn_queue_t *q);
|
||||
|
||||
/** Returns 1 if the queue is empty, 0 otherwise */
|
||||
int q_empty( dyn_queue_t *q );
|
||||
|
||||
@@ -224,6 +232,7 @@ void hash_remove( hash_table_t *h,
|
||||
const void *key,
|
||||
const void **old_key,
|
||||
const void **old_data );
|
||||
|
||||
/**
|
||||
Checks whether the specified key is in the hash table
|
||||
*/
|
||||
@@ -235,16 +244,23 @@ int hash_contains( hash_table_t *h,
|
||||
*/
|
||||
void hash_get_keys( hash_table_t *h,
|
||||
array_list_t *arr );
|
||||
|
||||
/**
|
||||
Appends all data elements in the table to the specified list
|
||||
*/
|
||||
void hash_get_data( hash_table_t *h,
|
||||
array_list_t *arr );
|
||||
/** Call the function func for each key/data pair in the table*/
|
||||
|
||||
/**
|
||||
Call the function func for each key/data pair in the table
|
||||
*/
|
||||
void hash_foreach( hash_table_t *h,
|
||||
void (*func)( const void *, const void * ) );
|
||||
/** Same as hash_foreach, but the function func takes an additional
|
||||
* argument, which is provided by the caller in the variable aux */
|
||||
|
||||
/**
|
||||
Same as hash_foreach, but the function func takes an additional
|
||||
argument, which is provided by the caller in the variable aux
|
||||
*/
|
||||
void hash_foreach2( hash_table_t *h, void (*func)( const void *,
|
||||
const void *,
|
||||
void *),
|
||||
@@ -269,10 +285,11 @@ int hash_wcs_func( const void *data );
|
||||
*/
|
||||
int hash_wcs_cmp( const void *a, const void *b );
|
||||
|
||||
/** Initialize the priority queue
|
||||
|
||||
\param q the queue to initialize
|
||||
\param compare a comparison function that can compare two entries in the queue
|
||||
/**
|
||||
Initialize the priority queue
|
||||
|
||||
\param q the queue to initialize
|
||||
\param compare a comparison function that can compare two entries in the queue
|
||||
*/
|
||||
void pq_init( priority_queue_t *q,
|
||||
int (*compare)(void *e1, void *e2) );
|
||||
@@ -289,6 +306,7 @@ int pq_put( priority_queue_t *q,
|
||||
Removes and returns the last entry in the priority queue
|
||||
*/
|
||||
void *pq_get( priority_queue_t *q );
|
||||
|
||||
/**
|
||||
Returns the last entry in the priority queue witout removing it.
|
||||
*/
|
||||
@@ -314,10 +332,16 @@ void pq_destroy( priority_queue_t *q );
|
||||
*/
|
||||
array_list_t *al_new();
|
||||
|
||||
/** Initialize the list. */
|
||||
/**
|
||||
Initialize the list.
|
||||
*/
|
||||
void al_init( array_list_t *l );
|
||||
/** Destroy the list and free memory used by it.*/
|
||||
|
||||
/**
|
||||
Destroy the list and free memory used by it.
|
||||
*/
|
||||
void al_destroy( array_list_t *l );
|
||||
|
||||
/**
|
||||
Append element to list
|
||||
|
||||
@@ -327,6 +351,7 @@ void al_destroy( array_list_t *l );
|
||||
\return 1 if succesfull, 0 otherwise
|
||||
*/
|
||||
int al_push( array_list_t *l, const void *o );
|
||||
|
||||
/**
|
||||
Append all elements of a list to another
|
||||
|
||||
@@ -335,6 +360,7 @@ int al_push( array_list_t *l, const void *o );
|
||||
\return 1 if succesfull, 0 otherwise
|
||||
*/
|
||||
int al_push_all( array_list_t *a, array_list_t *b );
|
||||
|
||||
/**
|
||||
Sets the element at the specified index
|
||||
|
||||
@@ -343,6 +369,7 @@ int al_push_all( array_list_t *a, array_list_t *b );
|
||||
\param o The element
|
||||
*/
|
||||
int al_set( array_list_t *l, int pos, const void *o );
|
||||
|
||||
/**
|
||||
Returns the element at the specified index
|
||||
|
||||
@@ -351,26 +378,37 @@ int al_set( array_list_t *l, int pos, const void *o );
|
||||
\return The element
|
||||
*/
|
||||
const void *al_get( array_list_t *l, int pos );
|
||||
|
||||
/**
|
||||
Truncates the list to new_sz items.
|
||||
*/
|
||||
void al_truncate( array_list_t *l, int new_sz );
|
||||
|
||||
/**
|
||||
Removes and returns the last entry in the list
|
||||
*/
|
||||
const void *al_pop( array_list_t *l );
|
||||
|
||||
/**
|
||||
Returns the number of elements in the list
|
||||
*/
|
||||
int al_get_count( array_list_t *l );
|
||||
|
||||
/**
|
||||
Returns the last entry in the list witout removing it.
|
||||
*/
|
||||
const void *al_peek( array_list_t *l );
|
||||
/** Returns 1 if the list is empty, 0 otherwise*/
|
||||
|
||||
/**
|
||||
Returns 1 if the list is empty, 0 otherwise
|
||||
*/
|
||||
int al_empty( array_list_t *l);
|
||||
/** Call the function func for each entry in the list*/
|
||||
|
||||
/**
|
||||
Call the function func for each entry in the list
|
||||
*/
|
||||
void al_foreach( array_list_t *l, void (*func)(const void * ));
|
||||
|
||||
/**
|
||||
Same as al_foreach, but the function func takes an additional
|
||||
argument, which is provided by the caller in the variable aux
|
||||
@@ -400,7 +438,9 @@ void al_foreach2( array_list_t *l, void (*func)(const void *, void *), void *aux
|
||||
|
||||
Which most people would find more intuitive.
|
||||
|
||||
The system breaks down if the user is using numbers of a base larger than 10.
|
||||
This won't return the optimum results for numbers in bases higher
|
||||
than ten, such as hexadecimal, but at least a stable sort order
|
||||
will result.
|
||||
*/
|
||||
int wcsfilecmp( const wchar_t *a, const wchar_t *b );
|
||||
|
||||
@@ -432,19 +472,21 @@ void sb_append_char( string_buffer_t *, wchar_t );
|
||||
Append a null terminated list of strings to the buffer.
|
||||
Example:
|
||||
|
||||
sb_append2( my_buff, L"foo", L"bar", 0 );
|
||||
sb_append2( my_buff, L"foo", L"bar", (void *)0 );
|
||||
|
||||
Do not forget to cast the last 0 to (void *), or you might encounter errors on 64-bit platforms!
|
||||
*/
|
||||
void sb_append2( string_buffer_t *, ... );
|
||||
|
||||
/**
|
||||
Append formated string data to the buffer. This function internally
|
||||
relies on \c vswprintf, so any filter options supported by that
|
||||
function is also supported by this function
|
||||
function is also supported by this function.
|
||||
*/
|
||||
int sb_printf( string_buffer_t *buffer, const wchar_t *format, ... );
|
||||
|
||||
/**
|
||||
Vararg version of sb_printf
|
||||
Vararg version of sb_printf.
|
||||
*/
|
||||
int sb_vprintf( string_buffer_t *buffer, const wchar_t *format, va_list va_orig );
|
||||
|
||||
@@ -454,15 +496,16 @@ int sb_vprintf( string_buffer_t *buffer, const wchar_t *format, va_list va_orig
|
||||
void sb_destroy( string_buffer_t * );
|
||||
|
||||
/**
|
||||
Truncate the buffer.
|
||||
Truncate the buffer. This will not deallocate the memory used, it will only set the contents of the string to L"\0".
|
||||
*/
|
||||
void sb_clear( string_buffer_t * );
|
||||
|
||||
|
||||
/**
|
||||
Initialize the specified buffer_t
|
||||
*/
|
||||
*/
|
||||
void b_init( buffer_t *b);
|
||||
|
||||
/**
|
||||
Destroy the specified buffer_t
|
||||
*/
|
||||
|
||||
@@ -64,7 +64,7 @@ extern wchar_t *woptarg;
|
||||
When `getopt' returns EOF, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
Otherwise, `woptind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
extern int woptind;
|
||||
@@ -149,7 +149,7 @@ struct woption
|
||||
#ifdef __GNU_LIBRARY__
|
||||
/**
|
||||
Get options from argument list. See the glibc manual for information on how to use this function.
|
||||
*/
|
||||
*/
|
||||
extern int wgetopt (int argc, wchar_t *const *argv, const wchar_t *shortopts);
|
||||
#else /* not __GNU_LIBRARY__ */
|
||||
|
||||
|
||||
40
wutil.c
40
wutil.c
@@ -22,28 +22,49 @@
|
||||
#include "common.h"
|
||||
#include "wutil.h"
|
||||
|
||||
#define TMP_LEN_MIN 256
|
||||
|
||||
/**
|
||||
Buffer for converting wide arguments to narrow arguments, used by
|
||||
the \c wutil_wcs2str() function.
|
||||
*/
|
||||
static char *tmp=0;
|
||||
/**
|
||||
Length of the \c tmp buffer.
|
||||
*/
|
||||
static size_t tmp_len=0;
|
||||
|
||||
int c = 0;
|
||||
/**
|
||||
Counts the number of calls to the wutil wrapper functions
|
||||
*/
|
||||
static int wutil_calls = 0;
|
||||
|
||||
void wutil_init()
|
||||
{
|
||||
}
|
||||
|
||||
void wutil_destroy()
|
||||
{
|
||||
free( tmp );
|
||||
tmp=0;
|
||||
tmp_len=0;
|
||||
debug( 3, L"wutil functions called %d times", c );
|
||||
debug( 3, L"wutil functions called %d times", wutil_calls );
|
||||
}
|
||||
|
||||
/**
|
||||
Convert the specified wide aharacter string to a narrow character
|
||||
string. This function uses an internal temporary buffer for storing
|
||||
the result so subsequent results will overwrite previous results.
|
||||
*/
|
||||
static char *wutil_wcs2str( const wchar_t *in )
|
||||
{
|
||||
c++;
|
||||
wutil_calls++;
|
||||
|
||||
size_t new_sz =MAX_UTF8_BYTES*wcslen(in)+1;
|
||||
if( tmp_len < new_sz )
|
||||
{
|
||||
free( tmp );
|
||||
tmp = malloc( new_sz );
|
||||
new_sz = maxi( new_sz, TMP_LEN_MIN );
|
||||
tmp = realloc( tmp, new_sz );
|
||||
if( !tmp )
|
||||
{
|
||||
die_mem();
|
||||
@@ -109,14 +130,17 @@ int wopen(const wchar_t *pathname, int flags, ...)
|
||||
|
||||
if( tmp )
|
||||
{
|
||||
va_start( argp, flags );
|
||||
|
||||
if( ! (flags & O_CREAT) )
|
||||
{
|
||||
res = open(tmp, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
va_start( argp, flags );
|
||||
res = open(tmp, flags, va_arg(argp, int) );
|
||||
|
||||
va_end( argp );
|
||||
va_end( argp );
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
Reference in New Issue
Block a user