Fifth phase of using a real struct for passing around completions - make expand.c and wildcard.c use the struct internally. This makes all completion code use the new struct.

darcs-hash:20070224081131-ac50b-aba4ff255c6dc1ce9ad375d6cd1acde919c7cbd6.gz
This commit is contained in:
axel 2007-02-24 18:11:31 +10:00
parent 6859e012d9
commit 73a67c2a43
3 changed files with 122 additions and 161 deletions

View file

@ -245,7 +245,8 @@ void completion_allocate( array_list_t *context,
{
completion_t *res = halloc( context, sizeof( completion_t) );
res->completion = halloc_wcsdup( context, comp );
res->description = halloc_wcsdup( context, desc );
if( desc )
res->description = halloc_wcsdup( context, desc );
res->flags = flags;
al_push( context, res );
}
@ -1135,24 +1136,6 @@ const wchar_t *complete_get_desc( const wchar_t *filename )
return (wchar_t *)get_desc_buff->buff;
}
/**
Convert all string completions in src into completion_t structs in
dest. All source strings will be free'd.
*/
static void completion_convert_list( array_list_t *src, array_list_t *dest )
{
int i;
for( i=0; i<al_get_count( src ); i++ )
{
wchar_t *next = (wchar_t *)al_get( src, i );
completion_allocate2( dest, next, COMPLETE_SEP );
free( next );
}
}
/**
Copy any strings in possible_comp which have the specified prefix
to the list comp_out. The prefix may contain wildcards. The output
@ -1180,10 +1163,6 @@ static void complete_strings( array_list_t *comp_out,
{
int i;
wchar_t *wc, *tmp;
array_list_t lst;
al_init( &lst );
tmp = expand_one( 0,
wcsdup(wc_escaped), EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_WILDCARDS);
@ -1197,11 +1176,11 @@ static void complete_strings( array_list_t *comp_out,
{
wchar_t *next_str = (wchar_t *)al_get( possible_comp, i );
if( next_str )
wildcard_complete( next_str, wc, desc, desc_func, &lst );
{
wildcard_complete( next_str, wc, desc, desc_func, comp_out );
}
}
completion_convert_list( &lst, comp_out );
al_destroy( &lst );
free( wc );
}

202
expand.c
View file

@ -85,7 +85,7 @@ parameter expansion.
/**
Description for short job. The job command is concatenated
*/
#define COMPLETE_JOB_DESC_VAL _( L"Job: ")
#define COMPLETE_JOB_DESC_VAL _( L"Job: %ls")
/**
Description for the shells own pid
@ -329,14 +329,14 @@ static int match_pid( const wchar_t *cmd,
Searches for a job with the specified job id, or a job or process
which has the string \c proc as a prefix of its commandline.
If accept_incomplete is true, the remaining string for any matches
If the ACCEPT_INCOMPLETE flag is set, the remaining string for any matches
are inserted.
If accept_incomplete is false, any job matching the specified
string is matched, and the job pgid is returned. If no job
matches, all child processes are searched. If no child processes
match, and <tt>fish</tt> can understand the contents of the /proc
filesystem, all the users processes are searched for matches.
Otherwise, any job matching the specified string is matched, and
the job pgid is returned. If no job matches, all child processes
are searched. If no child processes match, and <tt>fish</tt> can
understand the contents of the /proc filesystem, all the users
processes are searched for matches.
*/
static int find_process( const wchar_t *proc,
@ -372,14 +372,20 @@ static int find_process( const wchar_t *proc,
if( wcsncmp( proc, jid, wcslen(proc ) )==0 )
{
al_push( out,
wcsdupcat2( jid+wcslen(proc),
COMPLETE_SEP_STR,
COMPLETE_JOB_DESC_VAL,
j->command,
(void *)0 ) );
string_buffer_t desc_buff;
sb_init( &desc_buff );
sb_printf( &desc_buff,
COMPLETE_JOB_DESC_VAL,
j->command );
completion_allocate( out,
jid+wcslen(proc),
(wchar_t *)desc_buff.buff,
0 );
sb_destroy( &desc_buff );
}
}
@ -422,11 +428,10 @@ static int find_process( const wchar_t *proc,
{
if( flags & ACCEPT_INCOMPLETE )
{
wchar_t *res = wcsdupcat2( j->command + offset + wcslen(proc),
COMPLETE_SEP_STR,
COMPLETE_JOB_DESC,
(void *)0 );
al_push( out, res );
completion_allocate( out,
j->command + offset + wcslen(proc),
COMPLETE_JOB_DESC,
0 );
}
else
{
@ -459,11 +464,10 @@ static int find_process( const wchar_t *proc,
{
if( flags & ACCEPT_INCOMPLETE )
{
wchar_t *res = wcsdupcat2( p->actual_cmd + offset + wcslen(proc),
COMPLETE_SEP_STR,
COMPLETE_CHILD_PROCESS_DESC,
(void *)0);
al_push( out, res );
completion_allocate( out,
p->actual_cmd + offset + wcslen(proc),
COMPLETE_CHILD_PROCESS_DESC,
0 );
}
else
{
@ -575,13 +579,10 @@ static int find_process( const wchar_t *proc,
{
if( flags & ACCEPT_INCOMPLETE )
{
wchar_t *res = wcsdupcat2( cmd + offset + wcslen(proc),
COMPLETE_SEP_STR,
COMPLETE_PROCESS_DESC,
(void *)0);
if( res )
al_push( out, res );
completion_allocate( out,
cmd + offset + wcslen(proc),
COMPLETE_PROCESS_DESC,
0 );
}
else
{
@ -625,13 +626,17 @@ static int expand_pid( wchar_t *in,
{
if( wcsncmp( in+1, SELF_STR, wcslen(in+1) )==0 )
{
wchar_t *res = wcsdupcat2( SELF_STR+wcslen(in+1), COMPLETE_SEP_STR, COMPLETE_SELF_DESC, (void *)0 );
al_push( out, res );
completion_allocate( out,
SELF_STR+wcslen(in+1),
COMPLETE_SELF_DESC,
0 );
}
else if( wcsncmp( in+1, LAST_STR, wcslen(in+1) )==0 )
{
wchar_t *res = wcsdupcat2( LAST_STR+wcslen(in+1), COMPLETE_SEP_STR, COMPLETE_LAST_DESC, (void *)0 );
al_push( out, res );
completion_allocate( out,
LAST_STR+wcslen(in+1),
COMPLETE_LAST_DESC,
0 );
}
}
else
@ -1519,36 +1524,6 @@ static void remove_internal_separator( const void *s, int conv )
*out=0;
}
static void glorf( array_list_t *comp, int from )
{
int i;
for( i=from; i<al_get_count( comp ); i++ )
{
wchar_t *next = (wchar_t *)al_get( comp, i );
wchar_t *desc;
void *item;
int flags = 0;
desc = wcschr( next, COMPLETE_SEP );
if( desc )
{
*desc = 0;
desc++;
}
if( ( wcslen(next) > 0 ) && ( wcschr( L"/=@:", next[wcslen(next)-1] ) != 0 ) )
flags |= COMPLETE_NO_SPACE;
completion_allocate( comp, next, desc, flags );
item = al_pop( comp );
al_set( comp, i, item );
free( next );
}
}
/**
The real expansion function. expand_one is just a wrapper around this one.
@ -1566,8 +1541,6 @@ int expand_string( void *context,
int res = EXPAND_OK;
int start_count = al_get_count( end_out );
int end_out_count = al_get_count( end_out );
CHECK( str, EXPAND_ERROR );
CHECK( end_out, EXPAND_ERROR );
@ -1712,7 +1685,9 @@ int expand_string( void *context,
return EXPAND_OK;
}
else
{
al_push( out, next );
}
}
else
{
@ -1745,57 +1720,75 @@ int expand_string( void *context,
if( ((flags & ACCEPT_INCOMPLETE) && (!(flags & EXPAND_SKIP_WILDCARDS))) ||
wildcard_has( next, 1 ) )
{
wchar_t *start, *rest;
array_list_t *list = out;
if( next[0] == '/' )
{
wc_res = wildcard_expand( &next[1], L"/",flags, out );
start = L"/";
rest = &next[1];
}
else
{
wc_res = wildcard_expand( next, L"", flags, out );
start = L"";
rest = next;
}
free( next );
switch( wc_res )
if( flags & ACCEPT_INCOMPLETE )
{
case 0:
list = end_out;
}
wc_res = wildcard_expand( rest, start, flags, list );
free( next );
if( !(flags & ACCEPT_INCOMPLETE) )
{
switch( wc_res )
{
if( !(flags & ACCEPT_INCOMPLETE) )
case 0:
{
if( res == EXPAND_OK )
res = EXPAND_WILDCARD_NO_MATCH;
if( !(flags & ACCEPT_INCOMPLETE) )
{
if( res == EXPAND_OK )
res = EXPAND_WILDCARD_NO_MATCH;
break;
}
}
case 1:
{
int j;
res = EXPAND_WILDCARD_MATCH;
sort_list( out );
for( j=0; j<al_get_count( out ); j++ )
{
wchar_t *next = (wchar_t *)al_get( out, j );
if( !next )
{
debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ );
continue;
}
al_push( end_out, next );
}
al_truncate( out, 0 );
break;
}
}
case 1:
{
int j;
res = EXPAND_WILDCARD_MATCH;
sort_list( out );
for( j=0; j<al_get_count( out ); j++ )
case -1:
{
wchar_t *next = (wchar_t *)al_get( out, j );
if( !next )
{
debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ );
continue;
}
al_push( end_out, next );
al_foreach( out, &free );
al_destroy( in );
al_destroy( out );
return EXPAND_ERROR;
}
al_truncate( out, 0 );
break;
}
case -1:
{
al_foreach( out, &free );
al_destroy( in );
al_destroy( out );
return EXPAND_ERROR;
}
}
}
}
else
{
@ -1808,6 +1801,7 @@ int expand_string( void *context,
al_push( end_out, next );
}
}
}
al_destroy( in );
al_destroy( out );
@ -1821,12 +1815,6 @@ int expand_string( void *context,
}
}
if( flags & ACCEPT_INCOMPLETE)
{
glorf( end_out, end_out_count );
}
return res;

View file

@ -177,7 +177,9 @@ static int wildcard_complete_internal( const wchar_t *orig,
if( *wc == 0 &&
( ( *str != L'.') || (!is_first)) )
{
wchar_t *new;
wchar_t *out_completion = 0;
const wchar_t *out_desc = desc;
if( !out )
{
return 1;
@ -190,14 +192,13 @@ static int wildcard_complete_internal( const wchar_t *orig,
*/
wchar_t *sep;
new = wcsdup( str );
sep = wcschr(new, PROG_COMPLETE_SEP );
*sep = COMPLETE_SEP;
out_completion = wcsdup( str );
sep = wcschr(out_completion, PROG_COMPLETE_SEP );
*sep = 0;
out_desc = sep + 1;
}
else
{
const wchar_t *this_desc = desc;
if( desc_func )
{
/*
@ -207,30 +208,25 @@ static int wildcard_complete_internal( const wchar_t *orig,
*/
const wchar_t *func_desc = desc_func( orig );
if( func_desc )
this_desc = func_desc;
out_desc = func_desc;
}
/*
Append description to item, if a description exists
*/
if( this_desc && wcslen(this_desc) )
{
/*
Check if the description already contains a separator character, if not, prepend it
*/
if( wcschr( this_desc, COMPLETE_SEP ) )
new = wcsdupcat2( str, this_desc, (void *)0 );
else
new = wcsdupcat2( str, COMPLETE_SEP_STR, this_desc, (void *)0 );
}
else
new = wcsdup( str );
out_completion = wcsdup( str );
}
if( new )
if( out_completion )
{
al_push( out, new );
completion_allocate( out,
out_completion,
out_desc,
0 );
}
free ( out_completion );
return 1;
}
@ -336,11 +332,6 @@ static void get_desc( wchar_t *fn, string_buffer_t *sb, int is_cmd )
desc = complete_get_desc( fn );
if( wcschr( desc, COMPLETE_SEP )==0 )
{
sb_append( sb, COMPLETE_SEP_STR );
}
if( sz >= 0 && S_ISDIR(buf.st_mode) )
{
sb_append( sb, desc );
@ -527,8 +518,11 @@ int wildcard_expand( const wchar_t *wc,
get_desc( long_name,
&sb_desc,
flags & EXECUTABLES_ONLY );
al_push( out,
wcsdupcat(name, (wchar_t *)sb_desc.buff) );
completion_allocate( out,
name,
(wchar_t *)sb_desc.buff,
0 );
}
free( long_name );