From 5ba0affdd7b18ed970c039961b75da2cb925d6cd Mon Sep 17 00:00:00 2001 From: axel Date: Wed, 26 Oct 2005 20:51:02 +1000 Subject: [PATCH] Minor performance tweaks darcs-hash:20051026105102-ac50b-ffa35c43fd9e1aad47229260e5d7da4249cacdcf.gz --- expand.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- proc.c | 1 - reader.c | 2 +- tokenizer.c | 21 +++++++++++++++++++-- wgetopt.h | 4 ++-- 5 files changed, 69 insertions(+), 8 deletions(-) diff --git a/expand.c b/expand.c index 4236d2ab1..fce58d839 100644 --- a/expand.c +++ b/expand.c @@ -77,6 +77,42 @@ parameter expansion. */ #define LAST_STR L"last" +/** + 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 contin + any tokens which are expanded. 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 in */ @@ -1311,7 +1347,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 ); @@ -1501,6 +1543,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 +1565,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; diff --git a/proc.c b/proc.c index bc27a2147..9bae4774d 100644 --- a/proc.c +++ b/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; diff --git a/reader.c b/reader.c index 3057a35c1..98c9c2c66 100644 --- a/reader.c +++ b/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. */ diff --git a/tokenizer.c b/tokenizer.c index 42b2781a4..5e0fa42c7 100644 --- a/tokenizer.c +++ b/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; diff --git a/wgetopt.h b/wgetopt.h index 7856add5d..9c5c9947a 100644 --- a/wgetopt.h +++ b/wgetopt.h @@ -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__ */