Пример #1
0
void halloc_free( void *context )
{
	halloc_t *me;
	int i;
	
	if( !context )
		return;

	
	me = halloc_from_data( context );

#ifdef HALLOC_DEBUG
	alloc_spill += me->scratch_free;
#endif
	for( i=0; i<al_get_count(&me->children); i+=2 )
	{
		void (*func)(void *) = (void (*)(void *))al_get( &me->children, i );
		void * data = (void *)al_get( &me->children, i+1 );
		if( func != &late_free )
			func( data );
	}
	for( i=0; i<al_get_count(&me->children); i+=2 )
	{
		void (*func)(void *) = (void (*)(void *))al_get_func( &me->children, i );
		void * data = (void *)al_get( &me->children, i+1 );
		if( func == &late_free )
			free( data );
	}
	al_destroy( &me->children );
	free(me);
}
Пример #2
0
/**
   Arraylist test
*/
static void al_test( int sz)
{
	long i;	
	array_list_t l;

	

	al_init( &l );
	
	al_set_long( &l, 1, 7L );
	al_set_long( &l, sz, 7L );
	
	if( al_get_count( &l ) != maxi( sz+1, 2 ) )
		err( L"Wrong number of elements in array list" );
	
	for( i=0; i<al_get_count( &l ); i++ )
	{
		long val = al_get_long( &l, i );
		if( (i == 1) || (i==sz))
		{
			if( val != 7 )
				err( L"Canary changed to %d at index %d", val, i );
		}
		else
		{
			if( val != 0 )
				err( L"False canary %d found at index %d", val, i );
		}
	}
}
Пример #3
0
/**
   Silly function
*/
static void	builtin_complete_remove( array_list_t *cmd, 
									 array_list_t *path,
									 const wchar_t *short_opt,
									 array_list_t *gnu_opt,
									 array_list_t *old_opt )
{
	
	int i;
	
	for( i=0; i<al_get_count( cmd ); i++ )
	{
		builtin_complete_remove2( (wchar_t *)al_get( cmd, i ),
								  COMMAND,
								  short_opt, 
								  gnu_opt,
								  old_opt );
	}
	
	for( i=0; i<al_get_count( path ); i++ )
	{
		builtin_complete_remove2( (wchar_t *)al_get( path, i ),
								  PATH,
								  short_opt, 
								  gnu_opt,
								  old_opt );
	}
	
}
Пример #4
0
const wchar_t *history_next_match( const wchar_t *needle)
{
    if( current_mode )
    {
        /*
          The index of previous search matches are saved in the 'used'
          list. We just need to pop the top item and set the new
          position. Easy!
        */
        if( al_get_count( &current_mode->used ) )
        {
            al_pop( &current_mode->used );
            if( al_get_count( &current_mode->used ) )
            {
                current_mode->pos = (int) al_peek_long( &current_mode->used );
                item_t *i = item_get( current_mode, al_get( &current_mode->item, current_mode->pos ) );
                return i->data;
            }
        }

        /*
          The used-list is empty. Set position to 'past end of list'
          and return the search string.
        */
        current_mode->pos = al_get_count( &current_mode->item );

    }
    return needle;
}
Пример #5
0
/**
   Silly function
*/
static void	builtin_complete_add( array_list_t *cmd, 
								  array_list_t *path,
								  const wchar_t *short_opt,
								  array_list_t *gnu_opt,
								  array_list_t *old_opt, 
								  int result_mode, 
								  int authoritative,
								  const wchar_t *condition,
								  const wchar_t *comp,
								  const wchar_t *desc,
								  int flags )
{
	int i;
	
	for( i=0; i<al_get_count( cmd ); i++ )
	{
		builtin_complete_add2( al_get( cmd, i ),
							   COMMAND,
							   short_opt, 
							   gnu_opt,
							   old_opt, 
							   result_mode, 
							   condition, 
							   comp, 
							   desc,
							   flags );

		if( authoritative != -1 )
		{
			complete_set_authoritative( al_get( cmd, i ),
									  COMMAND,
									  authoritative );
		}
		
	}
	
	for( i=0; i<al_get_count( path ); i++ )
	{
		builtin_complete_add2( al_get( path, i ),
							   PATH,
							   short_opt, 
							   gnu_opt,
							   old_opt, 
							   result_mode, 
							   condition, 
							   comp, 
							   desc,
							   flags );

		if( authoritative != -1 )
		{
			complete_set_authoritative( al_get( path, i ),
									  PATH,
									  authoritative );
		}
		
	}	
}
Пример #6
0
void history_add( const wchar_t *str )
{
    item_t *i;

    if( !current_mode )
        return;

    i = halloc( current_mode->item_context, sizeof(item_t));
    i->data = (wchar_t *)halloc_wcsdup( current_mode->item_context, str );
    i->timestamp = time(0);

    al_push( &current_mode->item, i );
    hash_put( &current_mode->session_item, i, i );

    al_truncate( &current_mode->used, 0 );
    current_mode->pos = al_get_count( &current_mode->item );

    current_mode->new_count++;

    if( (time(0) > current_mode->save_timestamp+SAVE_INTERVAL) || (current_mode->new_count >= SAVE_COUNT) )
    {
        history_save_mode( 0, current_mode );
    }

}
Пример #7
0
void input_mapping_add( const wchar_t *sequence,
			const wchar_t *command )
{
	int i;

	CHECK( sequence, );
	CHECK( command, );
	
	//	debug( 0, L"Add mapping from %ls to %ls", escape(sequence, 1), escape(command, 1 ) );
	

	for( i=0; i<al_get_count( &mappings); i++ )
	{
		input_mapping_t *m = (input_mapping_t *)al_get( &mappings, i );
		if( wcscmp( m->seq, sequence ) == 0 )
		{
			m->command = intern(command);
			return;
		}
	}
	
	input_mapping_t *m = malloc( sizeof( input_mapping_t ) );
	m->seq = intern( sequence );
	m->command = intern(command);
	al_push( &mappings, m );	
	
}
Пример #8
0
void sort_list( array_list_t *comp )
{
	qsort( comp->arr,
		   al_get_count( comp ),
		   sizeof( void*),
		   &str_cmp );
}
Пример #9
0
static void complete_strings( array_list_t *comp_out,
							  const wchar_t *wc_escaped,
							  const wchar_t *desc,
							  const wchar_t *(*desc_func)(const wchar_t *),
							  array_list_t *possible_comp,
							  int flags )
{
	int i;
	wchar_t *wc, *tmp;

	tmp = expand_one( 0,
					  wcsdup(wc_escaped), EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_WILDCARDS);
	if(!tmp)
		return;

	wc = parse_util_unescape_wildcards( tmp );
	free(tmp);

	for( i=0; i<al_get_count( possible_comp ); i++ )
	{
		wchar_t *next_str = (wchar_t *)al_get( possible_comp, i );

		if( next_str )
		{
			wildcard_complete( next_str, wc, desc, desc_func, comp_out, flags );
		}
	}

	free( wc );
}
Пример #10
0
const wchar_t *input_terminfo_get_name( const wchar_t *seq )
{
	int i;	
	static string_buffer_t *buff = 0;

	CHECK( seq, 0 );
	input_init();
		
	if( !buff )
	{
		buff = sb_halloc( global_context );
	}
	
	for( i=0; i<al_get_count( terminfo_mappings ); i++ )
	{
		terminfo_mapping_t *m = (terminfo_mapping_t *)al_get( terminfo_mappings, i );
		
		if( !m->seq )
		{
			continue;
		}
		
		sb_clear( buff );
		sb_printf( buff, L"%s", m->seq );
		
		if( !wcscmp( seq, (wchar_t *)buff->buff ) )
		{
			return m->name;
		}
	}
	
	return 0;
	
}
Пример #11
0
int input_init()
{
	if( is_init )
		return 1;
	
	is_init = 1;

	input_common_init( &interrupt_handler );

	if( setupterm( 0, STDOUT_FILENO, 0) == ERR )
	{
		debug( 0, _( L"Could not set up terminal" ) );
		exit(1);
	}
	output_set_term( env_get( L"TERM" ) );
	
	input_terminfo_init();

	/*
	  If we have no keybindings, add a few simple defaults
	*/
	if( !al_get_count( &mappings ) )
	{
		input_mapping_add( L"", L"self-insert" );
		input_mapping_add( L"\n", L"execute" );
		input_mapping_add( L"\t", L"complete" );
		input_mapping_add( L"\x3", L"commandline \"\"" );
		input_mapping_add( L"\x4", L"exit" );
		input_mapping_add( L"\x5", L"bind" );
	}

	return 1;
}
Пример #12
0
int input_mapping_erase( const wchar_t *sequence )
{
	int ok = 0;
	int i;
	size_t sz = al_get_count( &mappings );
	
	for( i=0; i<sz; i++ )
	{
		input_mapping_t *m = (input_mapping_t *)al_get( &mappings, i );
		if( !wcscmp( sequence, m->seq ) )
		{
			if( i != (sz-1 ) )
			{
				al_set( &mappings, i, al_get( &mappings, sz -1 ) );
			}
			al_truncate( &mappings, sz-1 );
			ok = 1;
			
			free( m );
			
			break;
			
		}
		
	}

	return ok;
	
}
Пример #13
0
/**
   Silly function
*/
static void	builtin_complete_remove2( wchar_t *cmd,
									  int cmd_type,
									  const wchar_t *short_opt,
									  array_list_t *gnu_opt,
									  array_list_t *old_opt )
{
	const wchar_t *s = (wchar_t *)short_opt;
	if( *s )
	{
		for( ; *s; s++ )
		{
			if( al_get_count( old_opt) + al_get_count( gnu_opt ) == 0 )
			{
				complete_remove(cmd,
								cmd_type,
								*s,
								0 );
				
			}
			else
			{
				builtin_complete_remove3( cmd,
										  cmd_type,
										  *s,
										  gnu_opt );
				builtin_complete_remove3( cmd,
										  cmd_type,
										  *s,
										  old_opt );
			}
		}
	}
	else
	{
		builtin_complete_remove3( cmd,
								  cmd_type,
								  0,
								  gnu_opt );
		builtin_complete_remove3( cmd,
								  cmd_type,
								  0,
								  old_opt );
										  
	}				

	
}
Пример #14
0
wint_t input_readch()
{
	
	int i;

	CHECK_BLOCK( R_NULL );
	
	/*
	  Clear the interrupted flag
	*/
	reader_interrupted();
	
	/*
	  Search for sequence in mapping tables
	*/

	while( 1 )
	{
		input_mapping_t *generic = 0;
		for( i=0; i<al_get_count( &mappings); i++ )
		{
			input_mapping_t *m = (input_mapping_t *)al_get( &mappings, i );
			wint_t res = input_try_mapping( m );		
			if( res )
				return res;
			
			if( wcslen( m->seq) == 0 )
			{
				generic = m;
			}
			
		}
		
		/*
		  No matching exact mapping, try to find generic mapping.
		*/

		if( generic )
		{	
			wchar_t arr[2]=
				{
					0, 
					0
				}
			;
			arr[0] = input_common_readch(0);
			
			return input_exec_binding( generic, arr );				
		}
				
		/*
		  No action to take on specified character, ignore it
		  and move to next one.
		*/
		input_common_readch( 0 );	}	
}
Пример #15
0
int al_push_all( array_list_t *a, array_list_t *b )
{
    int k;
    for( k=0; k<al_get_count( b ); k++ )
    {
        if( !al_push( a, al_get( b, k ) ) )
            return 0;
    }
    return 1;
}
Пример #16
0
static void anna_hash_add_all_extra_methods(anna_type_t *hash)
{
    int i;
    for(i=0; i<al_get_count(&anna_hash_additional_methods); i++)
    {
	anna_function_t *fun =
	    (anna_function_t *)al_get(&anna_hash_additional_methods, i);
	anna_hash_add_method_internal(hash, fun);
    }
}
Пример #17
0
void history_reset()
{
    if( current_mode )
    {
        current_mode->pos = al_get_count( &current_mode->item );
        /*
          Clear list of search matches
        */
        al_truncate( &current_mode->used, 0 );
    }
}
Пример #18
0
void input_mapping_get_names( array_list_t *list )
{
	int i;
	
	for( i=0; i<al_get_count( &mappings ); i++ )
	{
		input_mapping_t *m = (input_mapping_t *)al_get( &mappings, i );
		al_push( list, m->seq );
	}
	
}
Пример #19
0
wchar_t *history_get( int idx )
{
    int len;

    if( !current_mode )
        return 0;

    len = al_get_count( &current_mode->item );

    if( (idx >= len ) && !current_mode->has_loaded )
    {
        history_load( current_mode );
        len = al_get_count( &current_mode->item );
    }

    if( idx < 0 )
        return 0;

    if( idx >= len )
        return 0;

    return item_get( current_mode, al_get( &current_mode->item, len - 1 - idx ) )->data;
}
Пример #20
0
void exec_close( int fd )
{
	int i;

	if( fd < 0 )
	{
		debug( 0, L"Called close on invalid file descriptor " );
		return;
	}
	
	while( close(fd) == -1 )
	{
		if( errno != EINTR )
		{
			debug( 1, FD_ERROR, fd );
			wperror( L"close" );
			break;
		}
	}
	
	if( open_fds )
	{
		for( i=0; i<al_get_count( open_fds ); i++ )
		{
			int n = (int)al_get_long( open_fds, i );
			if( n == fd )
			{
				al_set_long( open_fds,
					     i,
					     al_get_long( open_fds, al_get_count( open_fds ) -1 ) );
				al_truncate( open_fds, 
					     al_get_count( open_fds ) -1 );
				break;
			}
		}
	}
}
Пример #21
0
/**
   Silly function
*/
static void builtin_complete_remove3( wchar_t *cmd,
									  int cmd_type,
									  wchar_t short_opt,
									  array_list_t *long_opt )		
{
	int i;
	
	for( i=0; i<al_get_count( long_opt ); i++ )
	{
		complete_remove( cmd,
						 cmd_type,
						 short_opt,
						 (wchar_t *)al_get( long_opt, i ) );
	}	
}
Пример #22
0
const wchar_t *input_mapping_get( const wchar_t *sequence )
{
	int i;
	size_t sz = al_get_count( &mappings );
	
	for( i=0; i<sz; i++ )
	{
		input_mapping_t *m = (input_mapping_t *)al_get( &mappings, i );
		if( !wcscmp( sequence, m->seq ) )
		{
			return m->command;
		}
	}
	return 0;
}
Пример #23
0
/**
   Close all fds in open_fds, except for those that are mentioned in
   the redirection list io. This should make sure that there are no
   stray opened file descriptors in the child.
   
   \param io the list of io redirections for this job. Pipes mentioned
   here should not be closed.
*/
static void close_unused_internal_pipes( io_data_t *io )
{
	int i=0;
	
	if( open_fds )
	{
		for( ;i<al_get_count( open_fds ); i++ )
		{
			int n = (long)al_get_long( open_fds, i );
			if( !use_fd_in_pipe( n, io) )
			{
				debug( 4, L"Close fd %d, used in other context", n );
				exec_close( n );
				i--;
			}
		}
	}
}
Пример #24
0
void input_terminfo_get_names( array_list_t *lst, int skip_null )
{
	int i;	

	CHECK( lst, );
	input_init();
		
	for( i=0; i<al_get_count( terminfo_mappings ); i++ )
	{
		terminfo_mapping_t *m = (terminfo_mapping_t *)al_get( terminfo_mappings, i );
		
		if( skip_null && !m->seq )
		{
			continue;
		}
		al_push( lst, m->name );
	}
}
Пример #25
0
/**
   Check if the specified string has already been used a s a search match
*/
static int history_is_used( const wchar_t  *str )
{
    int i;
    int res =0;
    item_t *it = 0;

    for( i=0; i<al_get_count( &current_mode->used); i++ )
    {
        long idx = al_get_long( &current_mode->used, i );
        it = item_get( current_mode, al_get( &current_mode->item, (int)idx ) );
        if( wcscmp( it->data, str ) == 0 )
        {
            res = 1;
            break;
        }

    }
    return res;
}
Пример #26
0
static int expand_test( const wchar_t *in, int flags, ... )
{
	array_list_t out;	
	va_list va;
	int i=0;
	int res=1;
	wchar_t *arg;
	
	al_init( &out );
	if( expand_string( 0, wcsdup(in), &out, flags) )
	{
		
	}
	
	
	va_start( va, flags );

	while( (arg=va_arg(va, wchar_t *) )!= 0 ) 
	{
		if( al_get_count( &out ) == i )
		{
			res=0;
			break;
		}
		
		if( wcscmp( al_get( &out, i ),arg) != 0 )
		{
			res=0;
			break;
		}
		
		i++;		
	}
	va_end( va );
	
	al_foreach( &out, &free );
	return res;
		
}
Пример #27
0
const wchar_t *input_terminfo_get_sequence( const wchar_t *name )
{
	const char *res = 0;
	int i;	
	static string_buffer_t *buff = 0;
	int err = ENOENT;
	
	CHECK( name, 0 );
	input_init();
	
	for( i=0; i<al_get_count( terminfo_mappings ); i++ )
	{
		terminfo_mapping_t *m = (terminfo_mapping_t *)al_get( terminfo_mappings, i );
		
		if( !wcscmp( name, m->name ) )
		{
			res = m->seq;
			err = EILSEQ;
			break;
		}
	}
	
	if( !res )
	{
		errno = err;
		return 0;
	}
	
	if( !buff )
	{
		buff = sb_halloc( global_context );
	}
	
	sb_clear( buff );
	sb_printf( buff, L"%s", res );

	return (wchar_t *)buff->buff;
		
}
Пример #28
0
/**
   Silly function
*/
static void	builtin_complete_add2( const wchar_t *cmd,
								   int cmd_type,
								   const wchar_t *short_opt,
								   array_list_t *gnu_opt,
								   array_list_t *old_opt, 
								   int result_mode, 
								   const wchar_t *condition,
								   const wchar_t *comp,
								   const wchar_t *desc,
								   int flags )
{
	int i;
	const wchar_t *s;
	
	for( s=short_opt; *s; s++ )
	{
		complete_add( cmd, 
					  cmd_type,
					  *s,
					  0,
					  0,
					  result_mode,
					  condition,
					  comp,
					  desc,
					  flags );
	}
	
	for( i=0; i<al_get_count( gnu_opt ); i++ )
	{
		complete_add( cmd, 
					  cmd_type,
					  0,
					  (wchar_t *)al_get(gnu_opt, i ),
					  0,
					  result_mode,
					  condition,
					  comp,
					  desc,
					  flags );
	}
	
	for( i=0; i<al_get_count( old_opt ); i++ )
	{
		complete_add( cmd, 
					  cmd_type,
					  0,
					  (wchar_t *)al_get(old_opt, i ),
					  1,
					  result_mode,
					  condition,
					  comp,
					  desc,
					  flags );
	}	

	if( al_get_count( old_opt )+al_get_count( gnu_opt )+wcslen(short_opt) == 0 )
	{
		complete_add( cmd, 
					  cmd_type,
					  0,
					  0,
					  0,
					  result_mode,
					  condition,
					  comp,
					  desc,
					  flags );
	}	
}
Пример #29
0
/**
   The complete builtin. Used for specifying programmable
   tab-completions. Calls the functions in complete.c for any heavy
   lifting. Defined in builtin_complete.c
*/
static int builtin_complete( wchar_t **argv )
{
	int res=0;
	int argc=0;
	int result_mode=SHARED;
	int remove = 0;
	int authoritative = -1;
	int flags = COMPLETE_AUTO_SPACE;
	
	string_buffer_t short_opt;
	array_list_t gnu_opt, old_opt;
	wchar_t *comp=L"", *desc=L"", *condition=L"";

	wchar_t *do_complete = 0;
	
	array_list_t cmd;
	array_list_t path;

	static int recursion_level=0;
	
	if( !is_interactive_session )
	{
		debug( 1, _(L"%ls: Command only available in interactive sessions"), argv[0] );
	}
	
	al_init( &cmd );
	al_init( &path );
	sb_init( &short_opt );
	al_init( &gnu_opt );
	al_init( &old_opt );
	
	argc = builtin_count_args( argv );	
	
	woptind=0;
	
	while( res == 0 )
	{
		const static struct woption
			long_options[] =
			{
				{
					L"exclusive", no_argument, 0, 'x' 
				}
				,
				{
					L"no-files", no_argument, 0, 'f' 
				}
				,
				{
					L"require-parameter", no_argument, 0, 'r' 
				}
				,
				{
					L"path", required_argument, 0, 'p'
				}
				,					
				{
					L"command", required_argument, 0, 'c' 
				}
				,					
				{
					L"short-option", required_argument, 0, 's' 
				}
				,
				{
					L"long-option", required_argument, 0, 'l'
				}
				,
				{
					L"old-option", required_argument, 0, 'o' 
				}
				,
				{
					L"description", required_argument, 0, 'd'
				}
				,
				{
					L"arguments", required_argument, 0, 'a'
				}
				,
				{
					L"erase", no_argument, 0, 'e'
				}
				,
				{
					L"unauthoritative", no_argument, 0, 'u'
				}
				,
				{
					L"authoritative", no_argument, 0, 'A'
				}
				,
				{
					L"condition", required_argument, 0, 'n'
				}
				,
				{
					L"do-complete", optional_argument, 0, 'C'
				}
				,
				{
					L"help", no_argument, 0, 'h'
				}
				,
				{ 
					0, 0, 0, 0 
				}
			}
		;		
		
		int opt_index = 0;
		
		int opt = wgetopt_long( argc,
								argv, 
								L"a:c:p:s:l:o:d:frxeuAn:C::h", 
								long_options, 
								&opt_index );
		if( opt == -1 )
			break;
			
		switch( opt )
		{
			case 0:
				if(long_options[opt_index].flag != 0)
					break;
                sb_printf( sb_err,
                           BUILTIN_ERR_UNKNOWN,
                           argv[0],
                           long_options[opt_index].name );
				builtin_print_help( argv[0], sb_err );

				
				res = 1;
				break;
				
			case 'x':					
				result_mode |= EXCLUSIVE;
				break;
					
			case 'f':					
				result_mode |= NO_FILES;
				break;
				
			case 'r':					
				result_mode |= NO_COMMON;
				break;
					
			case 'p':	
			case 'c':
			{
				wchar_t *a = unescape( woptarg, 1);
				if( a )
				{
					al_push( (opt=='p'?&path:&cmd), a );
				}
				else
				{
					sb_printf( sb_err, L"%ls: Invalid token '%ls'\n", argv[0], woptarg );
					res = 1;					
				}				
				break;
			}
				
			case 'd':
				desc = woptarg;
				break;
				
			case 'u':
				authoritative=0;
				break;
				
			case 'A':
				authoritative=1;
				break;
				
			case 's':
				sb_append( &short_opt, woptarg );
				break;
					
			case 'l':
				al_push( &gnu_opt, woptarg );
				break;
				
			case 'o':
				al_push( &old_opt, woptarg );
				break;

			case 'a':
				comp = woptarg;
				break;
				
			case 'e':
				remove = 1;
				break;

			case 'n':
				condition = woptarg;
				break;
				
			case 'C':
				do_complete = woptarg?woptarg:reader_get_buffer();
				break;
				
			case 'h':
				builtin_print_help( argv[0], sb_out );
				return 0;
				
			case '?':
				builtin_unknown_option( argv[0], argv[woptind-1] );
				res = 1;
				break;
				
		}
		
	}

	if( !res )
	{
		if( condition && wcslen( condition ) )
		{
			if( parser_test( condition, 0, 0, 0 ) )
			{
				sb_printf( sb_err,
						   L"%ls: Condition '%ls' contained a syntax error\n", 
						   argv[0],
						   condition );
				
				parser_test( condition, 0, sb_err, argv[0] );
				
				res = 1;
			}
		}
	}
	
	if( !res )
	{
		if( comp && wcslen( comp ) )
		{
			if( parser_test_args( comp, 0, 0 ) )
			{
				sb_printf( sb_err,
						   L"%ls: Completion '%ls' contained a syntax error\n", 
						   argv[0],
						   comp );
				
				parser_test_args( comp, sb_err, argv[0] );
				
				res = 1;
			}
		}
	}

	if( !res )
	{
		if( do_complete )
		{
			array_list_t *comp;
			int i;

			const wchar_t *prev_temporary_buffer = temporary_buffer;

			wchar_t *token;

			parse_util_token_extent( do_complete, wcslen( do_complete ), &token, 0, 0, 0 );
						
			temporary_buffer = do_complete;		

			if( recursion_level < 1 )
			{
				recursion_level++;
			
				comp = al_halloc( 0 );
			
				complete( do_complete, comp );
			
				for( i=0; i<al_get_count( comp ); i++ )
				{
					completion_t *next = (completion_t *)al_get( comp, i );
					wchar_t *prepend;
					
					if( next->flags & COMPLETE_NO_CASE )
					{
						prepend = L"";
					}
					else
					{
						prepend = token;
					}
						

					if( next->description )
					{
						sb_printf( sb_out, L"%ls%ls\t%ls\n", prepend, next->completion, next->description );
					}
					else
					{
						sb_printf( sb_out, L"%ls%ls\n", prepend, next->completion );
					}
				}
			
				halloc_free( comp );
				recursion_level--;
			}
		
			temporary_buffer = prev_temporary_buffer;		
		
		}
		else if( woptind != argc )
		{
			sb_printf( sb_err, 
					   _( L"%ls: Too many arguments\n" ),
					   argv[0] );
			builtin_print_help( argv[0], sb_err );

			res = 1;
		}
		else if( (al_get_count( &cmd) == 0 ) && (al_get_count( &path) == 0 ) )
		{
			/* No arguments specified, meaning we print the definitions of
			 * all specified completions to stdout.*/
			complete_print( sb_out );		
		}
		else
		{
			if( remove )
			{
				builtin_complete_remove( &cmd,
										 &path,
										 (wchar_t *)short_opt.buff,
										 &gnu_opt,
										 &old_opt );									 
			}
			else
			{
				builtin_complete_add( &cmd, 
									  &path,
									  (wchar_t *)short_opt.buff,
									  &gnu_opt,
									  &old_opt, 
									  result_mode, 
									  authoritative,
									  condition,
									  comp,
									  desc,
									  flags ); 
			}

		}	
	}
	
	al_foreach( &cmd, &free );
	al_foreach( &path, &free );

	al_destroy( &cmd );
	al_destroy( &path );
	sb_destroy( &short_opt );
	al_destroy( &gnu_opt );
	al_destroy( &old_opt );

	return res;
}
Пример #30
0
/**
   Get default action for a specified mimetype.
*/
static char *get_action( const char *mimetype )
{
    char *res=0;
    int i;

    char *launcher;
    char *end;
    array_list_t mime_filenames;

    char *launcher_str = NULL;
    char *launcher_filename, *launcher_command_str, *launcher_command;
    char *launcher_full;

    al_init( &mime_filenames );
    if( !append_filenames( &mime_filenames, DESKTOP_DEFAULT, 1 ) )
    {
        al_destroy( &mime_filenames );
        return 0;
    }

    for ( i = 0; i < al_get_count( &mime_filenames ); i++ )
    {
        launcher_str = search_ini( al_get( &mime_filenames, i ), mimetype );
        if ( launcher_str )
            break;
    }

    al_foreach( &mime_filenames, free );
    al_destroy( &mime_filenames );

    if( !launcher_str )
    {
        /*
          This type does not have a launcher. Try the supertype!
        */
//		fprintf( stderr, "mimedb: %s does not have launcher, try supertype\n", mimetype );
        const char ** parents = xdg_mime_get_mime_parents(mimetype);

        const char **p;
        if( parents )
        {
            for( p=parents; *p; p++ )
            {
                char *a = get_action(*p);
                if( a != 0 )
                    return a;
            }
        }
        /*
          Just in case subclassing doesn't work, (It doesn't on Fedora
          Core 3) we also test some common subclassings.
        */

        if( strncmp( mimetype, "text/plain", 10) != 0 && strncmp( mimetype, "text/", 5 ) == 0 )
            return get_action( "text/plain" );

        return 0;
    }

//	fprintf( stderr, "WOOT %s\n", launcher_str );
    launcher = strchr( launcher_str, '=' );

    if( !launcher )
    {
        fprintf( stderr, _("%s: Could not parse launcher string '%s'\n"), MIMEDB, launcher_str );
        error=1;
        return 0;
    }

    /* Skip the = */
    launcher++;

    /* Only use first launcher */
    end = strchr( launcher, ';' );
    if( end )
        *end = '\0';

    launcher_full = my_malloc( strlen( launcher) + strlen( APPLICATIONS_DIR)+1 );
    if( !launcher_full )
    {
        free( launcher_str );
        return 0;
    }

    strcpy( launcher_full, APPLICATIONS_DIR );
    strcat( launcher_full, launcher );
    free( launcher_str );

    launcher_filename = get_filename( launcher_full );

    free( launcher_full );

    launcher_command_str = search_ini( launcher_filename, "Exec" );

    if( !launcher_command_str )
    {
        fprintf( stderr,
                 _( "%s: Default launcher '%s' does not specify how to start\n"), MIMEDB,
                 launcher_filename );
        free( launcher_filename );
        return 0;
    }

    free( launcher_filename );

    launcher_command = strchr( launcher_command_str, '=' );
    launcher_command++;

    res = my_strdup( launcher_command );

    free( launcher_command_str );

    return res;
}