Compare commits

...

14 Commits

Author SHA1 Message Date
axel
8d58e58d7b Minor performance tweaks
darcs-hash:20051102154159-ac50b-9a32fb6cc654c593048840ebd9f6abb97c2e0bb8.gz
2005-11-03 01:41:59 +10:00
axel
c8c3715aac Bump to 1.16.2
darcs-hash:20051102145930-ac50b-94dc822e0f57c2774ce93023415742f5655ec5c7.gz
2005-11-03 00:59:30 +10:00
axel
7ffcebb9f8 No special casing for installing to $HOME
darcs-hash:20051102145252-ac50b-ebb3471f18c53f2ae0d1ec78e0c6ca60b46ff07e.gz
2005-11-03 00:52:52 +10:00
jan.fader
831d95b600 Bugfixing for the last patch
darcs-hash:20051101215628-9ad71-5ca66671c1707ac16f280504ae2eebbe6e07b6e8.gz
2005-11-02 07:56:28 +10:00
jan.fader
0ffeb41c28 Patch for the stupid defaults of autoconf
darcs-hash:20051101205215-9ad71-a954e2626d13c91435ca3cddc6f6af6b61f75f72.gz
2005-11-02 06:52:15 +10:00
axel
e8d02159da Fix minor bug in completions for make, which caused it to fail completing targets beginning with 't'
darcs-hash:20051027152332-ac50b-cb3741f7ea0c74a6885e31f78f2aa79323ae48a1.gz
2005-10-28 01:23:32 +10:00
axel
b78fba810c Fix crash bug when pasting long text
darcs-hash:20051027152148-ac50b-b47b96bc8acae760ce53a2e42d23dc2d07bf2302.gz
2005-10-28 01:21:48 +10:00
James Vega
43213ee458 fish_tests.c: Include header files for missing function definitions.
darcs-hash:20051027122003-35ec8-439007fc422a260e1912c9ac06f6a64ce67d79b6.gz
2005-10-27 22:20:03 +10:00
axel
da316dd588 Do not override users sysconfdir setting
darcs-hash:20051027144510-ac50b-fc670196f1ec55c9703a8c44d1411a9380a8a0cf.gz
2005-10-28 00:45:10 +10:00
axel
c8bc79005c Minor performance tweak: Do not allocate any heap memory for hash_table_t until an element is inserted. That way, hash tables that never contain any data will not cause a call to malloc()
darcs-hash:20051026144823-ac50b-570dfe169a2ce693458c493e8f103884de3c5078.gz
2005-10-27 00:48:23 +10:00
axel
5ba0affdd7 Minor performance tweaks
darcs-hash:20051026105102-ac50b-ffa35c43fd9e1aad47229260e5d7da4249cacdcf.gz
2005-10-26 20:51:02 +10:00
axel
721f616964 Add documentation for the vared shellscript function
darcs-hash:20051025143355-ac50b-d7aaecf4b2de062fb2c56928bd6a6919ad6d223c.gz
2005-10-26 00:33:55 +10:00
axel
ef4345968e vared function used older uppercase names for fish colors
darcs-hash:20051025134851-ac50b-f21b7c3e876f98b39f1d2382e2919d77c38bfdb4.gz
2005-10-25 23:48:51 +10:00
axel
319956c26b Predecalre variables in psub
darcs-hash:20051025134043-ac50b-225c021c00211918b8c6957a10018497891cf456.gz
2005-10-25 23:40:43 +10:00
22 changed files with 300 additions and 123 deletions

View File

@@ -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)

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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
View 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
View File

@@ -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 )

View File

@@ -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;

View File

@@ -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

View File

@@ -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"

View File

@@ -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

View File

@@ -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
View File

@@ -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
View File

@@ -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
View File

@@ -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;

View File

@@ -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],

View File

@@ -500,5 +500,3 @@ void signal_unblock()
sigprocmask(SIG_UNBLOCK, &chldset, 0);
}

View File

@@ -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
View File

@@ -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
View File

@@ -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
*/

View File

@@ -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
View File

@@ -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;

View File

@@ -14,6 +14,12 @@
#include <sys/types.h>
/**
Call this function on startup to create internal wutil
resources. This function doesn't do anything.
*/
void wutil_init();
/**
Call this function on exit to free internal wutil resources
*/