Exemplo n.º 1
0
/**
   Free all memory used by one line_t struct.
*/
static void free_line( void *l )
{
	line_t *line = (line_t *)l;
	al_destroy( &line->text );
	al_destroy( &line->color );
	free( line );
}
Exemplo n.º 2
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);
}
Exemplo n.º 3
0
/**
   Find at most one file relative to the XDG data directories.
*/
static char *get_filename( char *f )
{
    array_list_t list;
    char *first = NULL;

    al_init( &list );
    append_filenames( &list, f, 0 );
    first = al_pop( &list );
    al_destroy( &list );
    return first;
}
Exemplo n.º 4
0
/**
   Clean up one entry from the hash table of launch files
*/
static void clear_entry( void *key, void *val )
{
    /*
      The key is a mime value, either from the libraries internal hash
      table of mime types or from the command line. Either way, it
      should not be freed.

      The value is an array_list_t of filenames. The filenames com from
      the argument list and should not be freed. The arraylist,
      however, should be destroyed and freed.
    */
    array_list_t *l = (array_list_t *)val;
    al_destroy( l );
    free( l );
}
Exemplo n.º 5
0
/**
   Test stack functionality
*/
static int stack_test( int elements )
{
	long i;

	int res=1;
	
	array_list_t s;

	al_init( &s );	

	for( i=0; i<elements; i++ )
	{
		long foo;

		al_push_long( &s, i);
		al_push_long( &s, i);
		
		if( (foo=al_pop_long( &s )) != i )
		{
			err( L"Unexpected data" );
			res = 0;			
			break;
		}
	}

	for( i=0; i<elements; i++ )
	{
		long foo;
		
		if( (foo=al_pop_long( &s )) != (elements-i-1) )
		{
			err( L"Unexpected data" );
			res = 0;
			break;
		}		
	}


	al_destroy( &s );
	
	return res;
}
Exemplo n.º 6
0
/**
   Evaluate the argument list (as supplied by complete -a) and insert
   any return matching completions. Matching is done using \c
   copy_strings_with_prefix, meaning the completion may contain
   wildcards. Logically, this is not always the right thing to do, but
   I have yet to come up with a case where this matters.

   \param str The string to complete.
   \param args The list of option arguments to be evaluated.
   \param desc Description of the completion
   \param comp_out The list into which the results will be inserted
*/
static void complete_from_args( const wchar_t *str,
								const wchar_t *args,
								const wchar_t *desc,
								array_list_t *comp_out,
								int flags )
{

	array_list_t possible_comp;

	al_init( &possible_comp );

	proc_push_interactive(0);
	eval_args( args, &possible_comp );
	proc_pop_interactive();

	complete_strings( comp_out, str, desc, 0, &possible_comp, flags );

	al_foreach( &possible_comp, &free );
	al_destroy( &possible_comp );
}
Exemplo n.º 7
0
void input_destroy()
{
	if( !is_init )
		return;
	

	is_init=0;
	
	al_foreach( &mappings, &free );		
	al_destroy( &mappings );

	input_common_destroy();
	
	if( del_curterm( cur_term ) == ERR )
	{
		debug( 0, _(L"Error while closing terminfo") );
	}

	input_terminfo_destroy();
	
}
Exemplo n.º 8
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;
}
Exemplo n.º 9
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;
}
Exemplo n.º 10
0
static anna_node_t *anna_node_calculate_type_internal_call(
    anna_node_call_t *n)
{
    anna_node_t *res = 0;
    int is_constructor = 0;
    anna_stack_template_t *stack = n->stack;
	    
    n->object = anna_node_calculate_type(n->object);
    anna_type_t *type = n->object->return_type;

    array_list_t memb_list = AL_STATIC;
    anna_member_t *member = 0;
 
    if(type == ANNA_NODE_TYPE_IN_TRANSIT)
    {
	res = (anna_node_t *)n;
	goto CLEANUP;
    }
    if(n->node_type == ANNA_NODE_STATIC_MEMBER_CALL)
    {
	type = anna_node_resolve_to_type(n->object, stack);
	n->access_type = ANNA_NODE_ACCESS_STATIC_MEMBER;

	if(!type)
	{
	    anna_error(n->object, L"Unknown type");
	    res = (anna_node_t *)n;
	    goto CLEANUP;
	}
    }

    anna_type_setup_interface(type);    
    anna_type_prepare_member(type, n->mid);

    anna_method_search(type, anna_mid_get_reverse(n->mid), &memb_list, 0);
    
    member = anna_node_calc_type_call_helper(type, &n, &memb_list);
    
    if(member)
    {
	if(member->type == type_type && anna_member_is_static(member))
	{
	    anna_type_t *ctype = anna_type_unwrap(
		anna_as_obj(
		    type->static_member[member->offset]));
	    
	    if(ctype)
	    {
		if(!anna_node_calculate_type_direct_children(n, stack))
		{
		    res = (anna_node_t *)n;
		    goto CLEANUP;
		}

		ctype = anna_type_implicit_specialize(ctype, n);

		n->node_type = ANNA_NODE_CONSTRUCT;
		n->function = (anna_node_t *)anna_node_create_type(
		    &n->object->location,
		    ctype);
		n->function->stack = n->stack;
		n->return_type = ctype;
		n->flags |= ANNA_NODE_TYPE_FULL;
		
		anna_type_prepare_member(ctype, anna_mid_get(L"__init__"));
		member = anna_member_get(ctype, anna_mid_get(L"__init__"));

		if(!member)
		{
		    anna_error(
			(anna_node_t *)n, L"No constructor for type %ls could be found\n", ctype->name);
		    res = (anna_node_t *)n;
		    goto CLEANUP;
		}
		
		is_constructor = 1;
	    }
	}
	if(member->type == ANNA_NODE_TYPE_IN_TRANSIT)
	{
	    anna_error(
		(anna_node_t *)n,
		L"Member %ls is not a function\n",
		anna_mid_get_reverse(n->mid),
		type->name);
	    res = (anna_node_t *)n;	
	    goto CLEANUP;
	}
	
	anna_function_type_t *fun_type =
 	    (n->access_type == ANNA_NODE_ACCESS_STATIC_MEMBER) ? 
	    anna_function_type_unwrap(member->type) :
	    anna_member_bound_function_type(member);

	if(!fun_type)
	{
	    anna_error(
		(anna_node_t *)n,
		L"Member %ls is not a function\n",
		anna_mid_get_reverse(n->mid),
		type->name);
	    res = (anna_node_t *)n;
	    goto CLEANUP;
	}

	anna_node_t *memb_get = (anna_node_t *)
	    anna_node_create_member_get(
		0,
		(n->node_type == ANNA_NODE_STATIC_MEMBER_CALL) ? ANNA_NODE_STATIC_MEMBER_GET: ANNA_NODE_MEMBER_GET,
		n->object, n->mid);
	memb_get->stack = n->stack;
	anna_entry_t fun_entry = anna_node_static_invoke_try(memb_get, n->stack);
	if(!anna_entry_null_ptr(fun_entry))
	{
	    
	    anna_function_t *fun = anna_function_unwrap(anna_as_obj(fun_entry));
		
	    if(fun)
	    {
		
		anna_function_t *fun_spec = anna_function_implicit_specialize(fun, n);
		if(fun_spec != fun)
		{
		    anna_node_call_t *call = anna_node_create_call(
			&n->location,
			(anna_node_t *)anna_node_create_closure(
			    &n->location, 
			    fun_spec),
			0, 0);
		    int i;
		    for(i=0; i<n->child_count; i++)
		    {
			anna_node_call_push(
			    call,
			    n->child[i]);
		    }
		    call->function->stack = call->stack = n->stack;
		    call->function->return_type = anna_function_wrap(fun_spec)->type;
		    res = anna_node_calculate_type((anna_node_t *)call);
		    goto CLEANUP;
		}
	    }
	}
	
	if(!anna_node_validate_call_parameters(
	       n, fun_type,
	       1))
	{
	    member = 0;
	}
	else
	{
	    anna_node_call_map(n, fun_type);
	}
    }
    else
    {
	anna_error(
	    (anna_node_t *)n, 
	    L"No member named %ls in type %ls\n", 
	    anna_mid_get_reverse(n->mid),
	    type->name);
	res = (anna_node_t *)n;
	goto CLEANUP;
    }

    if(!is_constructor && member)
    {
	anna_function_type_t *funt = anna_function_type_unwrap(member->type);
	n->return_type = funt->return_type;
    }
    res = (anna_node_t *)n;
  CLEANUP:
    al_destroy(&memb_list);
    return res;
}
Exemplo n.º 11
0
/**
   Main function. Parses options and calls helper function for any heavy lifting.
*/
int main (int argc, char *argv[])
{
    int input_type=FILEDATA;
    int output_type=MIMETYPE;

    const char *mimetype;
    char *output=0;

    int i;

    hash_table_t launch_hash;

    locale_init();

    /*
      Parse options
    */
    while( 1 )
    {
        static struct option
            long_options[] =
        {
            {
                "input-file-data", no_argument, 0, 't'
            }
            ,
            {
                "input-filename", no_argument, 0, 'f'
            }
            ,
            {
                "input-mime", no_argument, 0, 'i'
            }
            ,
            {
                "output-mime", no_argument, 0, 'm'
            }
            ,
            {
                "output-description", no_argument, 0, 'd'
            }
            ,
            {
                "output-action", no_argument, 0, 'a'
            }
            ,
            {
                "help", no_argument, 0, 'h'
            }
            ,
            {
                "version", no_argument, 0, 'v'
            }
            ,
            {
                "launch", no_argument, 0, 'l'
            }
            ,
            {
                0, 0, 0, 0
            }
        }
        ;

        int opt_index = 0;

        int opt = getopt_long( argc,
                               argv,
                               GETOPT_STRING,
                               long_options,
                               &opt_index );

        if( opt == -1 )
            break;

        switch( opt )
        {
        case 0:
            break;

        case 't':
            input_type=FILEDATA;
            break;

        case 'f':
            input_type=FILENAME;
            break;

        case 'i':
            input_type=MIMETYPE;
            break;

        case 'm':
            output_type=MIMETYPE;
            break;

        case 'd':
            output_type=DESCRIPTION;
            break;

        case 'a':
            output_type=ACTION;
            break;

        case 'l':
            output_type=LAUNCH;
            break;

        case 'h':
            print_help( argv[0], 1 );
            exit(0);

        case 'v':
            printf( _("%s, version %s\n"), MIMEDB, PACKAGE_VERSION );
            exit( 0 );

        case '?':
            return 1;

        }
    }

    if( ( output_type == LAUNCH )&&(input_type==MIMETYPE))
    {
        fprintf( stderr, _("%s: Can not launch a mimetype\n"), MIMEDB );
        print_help( argv[0], 2 );
        exit(1);
    }

    if( output_type == LAUNCH )
        hash_init( &launch_hash, &hash_str_func, &hash_str_cmp );


    /*
       Loop over all non option arguments and do the specified lookup
    */

    //fprintf( stderr, "Input %d, output %d\n", input_type, output_type );

    for (i = optind; (i < argc)&&(!error); i++)
    {
        /* Convert from filename to mimetype, if needed */
        if( input_type == FILENAME )
        {
            mimetype = xdg_mime_get_mime_type_from_file_name(argv[i]);
        }
        else if( input_type == FILEDATA )
        {
            mimetype = xdg_mime_get_mime_type_for_file(argv[i]);
        }
        else
            mimetype = xdg_mime_is_valid_mime_type(argv[i])?argv[i]:0;

        mimetype = xdg_mime_unalias_mime_type (mimetype);
        if( !mimetype )
        {
            fprintf( stderr, _( "%s: Could not parse mimetype from argument '%s'\n"), MIMEDB, argv[i] );
            error=1;
            return 1;
        }

        /*
          Convert from mimetype to whatever, if needed
        */
        switch( output_type )
        {
        case MIMETYPE:
        {
            output = (char *)mimetype;
            break;

        }
        case DESCRIPTION:
        {
            output = get_description( mimetype );
            if( !output )
                output = strdup( _("Unknown") );

            break;
        }
        case ACTION:
        {
            output = get_action( mimetype );
            break;
        }
        case LAUNCH:
        {
            /*
              There may be more files using the same launcher, we
              add them all up in little array_list_ts and launched
              them together after all the arguments have been
              parsed.
            */
            array_list_t *l= (array_list_t *)hash_get( &launch_hash, mimetype );
            output = 0;

            if( !l )
            {
                l = my_malloc( sizeof( array_list_t ) );
                if( l == 0 )
                {
                    break;
                }
                al_init( l );
                hash_put( &launch_hash, mimetype, l );
            }
            al_push( l, argv[i] );
        }
        }

        /*
          Print the glorious result
        */
        if( output )
        {
            printf( "%s\n", output );
            if( output != mimetype )
                free( output );
        }
        output = 0;
    }

    /*
      Perform the actual launching
    */
    if( output_type == LAUNCH && !error )
    {
        int i;
        array_list_t mimes;
        al_init( &mimes );
        hash_get_keys( &launch_hash, &mimes );
        for( i=0; i<al_get_count( &mimes ); i++ )
        {
            char *mimetype = (char *)al_get( &mimes, i );
            array_list_t *files = (array_list_t *)hash_get( &launch_hash, mimetype );
            if( !files )
            {
                fprintf( stderr, _( "%s: Unknown error\n"), MIMEDB );
                error=1;
                break;
            }

            char *launcher = get_action( mimetype );

            if( launcher )
            {
                launch( launcher, files, 0 );
                free( launcher );
            }
        }
        hash_foreach( &launch_hash, &clear_entry );
        hash_destroy( &launch_hash );
        al_destroy( &mimes );
    }

    if( launch_buff )
        free( launch_buff );

    if( start_re )
    {
        regfree( start_re );
        regfree( stop_re );
        free( start_re );
        free( stop_re );
    }

    xdg_mime_shutdown();

    return error;
}
Exemplo n.º 12
0
void al_delete(smb_al *list)
{
  al_destroy(list);
  smb_free(list);
}
Exemplo n.º 13
0
/**
   Go through the mmaped region and insert pointers to suitable loacations into the item list
*/
static void history_populate_from_mmap( history_mode_t *m )
{
    char *begin = m->mmap_start;
    char *end = begin + m->mmap_length;
    char *pos;

    array_list_t old_item;
    array_list_t session_item_list;
    int ignore_newline = 0;
    int do_push = 1;

    al_init( &old_item );
    al_init( &session_item_list );
    al_push_all( &old_item, &m->item );
    al_truncate( &m->item, 0 );

    for( pos = begin; pos <end; pos++ )
    {

        if( do_push )
        {
            item_t *i;
            item_t *i_orig;

            ignore_newline = *pos == '#';

            i = item_get( m, pos );

            if( (i_orig=hash_get( &current_mode->session_item, i ) ) )
            {
                /*
                  This item comes from this session. Insert the
                  original item at the end of the item list.
                */
                al_push( &session_item_list, i_orig );
            }
            else
            {
                /*
                  Old item. Insert pointer directly to the item list
                */
                al_push( &m->item, pos );
            }

            do_push = 0;
        }

        switch( *pos )
        {
        case '\\':
        {
            pos++;
            break;
        }

        case '\n':
        {
            if( ignore_newline )
            {
                ignore_newline = 0;
            }
            else
            {
                do_push = 1;
            }
            break;
        }
        }
    }

    al_push_all(  &m->item, &session_item_list );
    m->pos += al_get_count( &m->item );
    al_push_all(  &m->item, &old_item );


    al_destroy( &session_item_list );
    al_destroy( &old_item );
}
Exemplo n.º 14
0
/**
   If command to complete is short enough, substitute
   the description with the whatis information for the executable.
*/
static void complete_cmd_desc( const wchar_t *cmd, array_list_t *comp )
{
	int i;
	const wchar_t *cmd_start;
	int cmd_len;
	wchar_t *lookup_cmd=0;
	array_list_t list;
	hash_table_t lookup;
	wchar_t *esc;
	int skip;

	if( !cmd )
		return;

	cmd_start=wcsrchr(cmd, L'/');

	if( cmd_start )
		cmd_start++;
	else
		cmd_start = cmd;

	cmd_len = wcslen(cmd_start);

	/*
	  Using apropos with a single-character search term produces far
	  to many results - require at least two characters if we don't
	  know the location of the whatis-database.
	*/
	if(cmd_len < 2 )
		return;

	if( wildcard_has( cmd_start, 0 ) )
	{
		return;
	}

	skip = 1;

	for( i=0; i<al_get_count( comp ); i++ )
	{
		completion_t *c = (completion_t *)al_get( comp, i );

		if( !wcslen( c->completion) || (c->completion[wcslen(c->completion)-1] != L'/' ))
		{
			skip = 0;
			break;
		}

	}

	if( skip )
	{
		return;
	}


	esc = escape( cmd_start, 1 );

	lookup_cmd = wcsdupcat( L"__fish_describe_command ", esc );
	free(esc);

	al_init( &list );
	hash_init( &lookup, &hash_wcs_func, &hash_wcs_cmp );


	/*
	  First locate a list of possible descriptions using a single
	  call to apropos or a direct search if we know the location
	  of the whatis database. This can take some time on slower
	  systems with a large set of manuals, but it should be ok
	  since apropos is only called once.
	*/
	if( exec_subshell( lookup_cmd, &list ) != -1 )
	{

		/*
		  Then discard anything that is not a possible completion and put
		  the result into a hashtable with the completion as key and the
		  description as value.

		  Should be reasonably fast, since no memory allocations are needed.
		*/
		for( i=0; i<al_get_count( &list); i++ )
		{
			wchar_t *el = (wchar_t *)al_get( &list, i );
			wchar_t *key, *key_end, *val_begin;

			if( !el )
				continue;

			key = el+wcslen(cmd_start);
			key_end = wcschr( key, L'\t' );

			if( !key_end )
				continue;

			*key_end = 0;
			val_begin = key_end+1;

			/*
			  And once again I make sure the first character is uppercased
			  because I like it that way, and I get to decide these
			  things.
			*/
			val_begin[0]=towupper(val_begin[0]);

			hash_put( &lookup, key, val_begin );
		}

		/*
		  Then do a lookup on every completion and if a match is found,
		  change to the new description.

		  This needs to do a reallocation for every description added, but
		  there shouldn't be that many completions, so it should be ok.
		*/
		for( i=0; i<al_get_count(comp); i++ )
		{
			completion_t *c = (completion_t *)al_get( comp, i );
			const wchar_t *el = c->completion;

			wchar_t *new_desc;

			new_desc = (wchar_t *)hash_get( &lookup,
											el );

			if( new_desc )
			{
				c->description = halloc_wcsdup( comp, new_desc );
			}
		}
	}

	hash_destroy( &lookup );
	al_foreach( &list,
				&free );
	al_destroy( &list );
	free( lookup_cmd );
}
Exemplo n.º 15
0
/**
   Test speed of completion calculations
*/
void perf_complete()
{
	wchar_t c;
	array_list_t out;
	long long t1, t2;
	int matches=0;
	double t;
	wchar_t str[3]=
	{
		0, 0, 0 
	}
	;
	int i;
	
	
	say( L"Testing completion performance" );
	al_init( &out );
	
	reader_push(L"");
	say( L"Here we go" );
	 	
	t1 = get_time();
	
	
	for( c=L'a'; c<=L'z'; c++ )
	{
		str[0]=c;
		reader_set_buffer( str, 0 );
		
		complete( str, &out );
	
		matches += al_get_count( &out );
		
		al_foreach( &out, &free );
		al_truncate( &out, 0 );
	}
	t2=get_time();
	
	t = (double)(t2-t1)/(1000000*26);
	
	say( L"One letter command completion took %f seconds per completion, %f microseconds/match", t, (double)(t2-t1)/matches );
	
	matches=0;
	t1 = get_time();
	for( i=0; i<LAPS; i++ )
	{
		str[0]='a'+(rand()%26);
		str[1]='a'+(rand()%26);
		
		reader_set_buffer( str, 0 );
		
		complete( str, &out );
	
		matches += al_get_count( &out );
		
		al_foreach( &out, &free );
		al_truncate( &out, 0 );
	}
	t2=get_time();
	
	t = (double)(t2-t1)/(1000000*LAPS);
	
	say( L"Two letter command completion took %f seconds per completion, %f microseconds/match", t, (double)(t2-t1)/matches );
	
	al_destroy( &out );

	reader_pop();
	
}
Exemplo n.º 16
0
/**
   Complete the specified command name. Search for executables in the
   path, executables defined using an absolute path, functions,
   builtins and directories for implicit cd commands.

   \param cmd the command string to find completions for

   \param comp the list to add all completions to
*/
static void complete_cmd( const wchar_t *cmd,
						  array_list_t *comp,
						  int use_function,
						  int use_builtin,
						  int use_command )
{
	wchar_t *path;
	wchar_t *path_cpy;
	wchar_t *nxt_path;
	wchar_t *state;
	array_list_t possible_comp;
	wchar_t *nxt_completion;

	wchar_t *cdpath = env_get(L"CDPATH");
	wchar_t *cdpath_cpy = wcsdup( cdpath?cdpath:L"." );

	if( (wcschr( cmd, L'/') != 0) || (cmd[0] == L'~' ) )
	{

		if( use_command )
		{

			if( expand_string( 0,
							   wcsdup(cmd),
							   comp,
							   ACCEPT_INCOMPLETE | EXECUTABLES_ONLY ) != EXPAND_ERROR )
			{
				complete_cmd_desc( cmd, comp );
			}
		}
	}
	else
	{
		if( use_command )
		{

			path = env_get(L"PATH");
			if( path )
			{

				path_cpy = wcsdup( path );

				for( nxt_path = wcstok( path_cpy, ARRAY_SEP_STR, &state );
				     nxt_path != 0;
				     nxt_path = wcstok( 0, ARRAY_SEP_STR, &state) )
				{
					int prev_count;
					int i;
					int path_len = wcslen(nxt_path);
					int add_slash;

					if( !path_len )
					{
						continue;
					}

					add_slash = nxt_path[path_len-1]!=L'/';
					nxt_completion = wcsdupcat( nxt_path,
												add_slash?L"/":L"",
												cmd );
					if( ! nxt_completion )
						continue;

					prev_count = al_get_count( comp );

					if( expand_string( 0,
									   nxt_completion,
									   comp,
									   ACCEPT_INCOMPLETE |
									   EXECUTABLES_ONLY ) != EXPAND_ERROR )
					{
						for( i=prev_count; i<al_get_count( comp ); i++ )
						{
							completion_t *c = (completion_t *)al_get( comp, i );
							if(c->flags & COMPLETE_NO_CASE )
							{
								c->completion = halloc_wcsdup( comp, c->completion + path_len + add_slash );
							}
						}
					}
				}
				free( path_cpy );
				complete_cmd_desc( cmd, comp );
			}
		}

		/*
		  These return the original strings - don't free them
		*/

		al_init( &possible_comp );

		if( use_function )
		{
			function_get_names( &possible_comp, cmd[0] == L'_' );
			complete_strings( comp, cmd, 0, &complete_function_desc, &possible_comp, 0 );
		}

		al_truncate( &possible_comp, 0 );

		if( use_builtin )
		{
			builtin_get_names( &possible_comp );
			complete_strings( comp, cmd, 0, &builtin_get_desc, &possible_comp, 0 );
		}
		al_destroy( &possible_comp );

	}

	if( use_builtin || (use_function && function_exists( L"cd") ) )
	{
		/*
		  Tab complete implicit cd for directories in CDPATH
		*/
		if( cmd[0] != L'/' && ( wcsncmp( cmd, L"./", 2 )!=0) )
		{
			for( nxt_path = wcstok( cdpath_cpy, ARRAY_SEP_STR, &state );
				 nxt_path != 0;
				 nxt_path = wcstok( 0, ARRAY_SEP_STR, &state) )
			{
				wchar_t *nxt_completion=
					wcsdupcat( nxt_path,
							   (nxt_path[wcslen(nxt_path)-1]==L'/'?L"":L"/"),
							   cmd );
				if( ! nxt_completion )
				{
					continue;
				}

				if( expand_string( 0,
								   nxt_completion,
								   comp,
								   ACCEPT_INCOMPLETE | DIRECTORIES_ONLY ) != EXPAND_ERROR )
				{
				}
			}
		}
	}

	free( cdpath_cpy );
}
Exemplo n.º 17
0
void anna_mid_destroy(void)
{
    al_destroy(&anna_mid_identifier_reverse);
    hash_foreach(&anna_mid_identifier, anna_mid_free);
    hash_destroy(&anna_mid_identifier);
}