示例#1
0
文件: search.c 项目: howard5888/wineT
/*******************************************************************
 *         symbol_search
 *
 * Call Patrik Stridvall's 'function_grep.pl' script to retrieve a
 * function prototype from include file(s)
 */
int symbol_search (parsed_symbol *sym)
{
    static const size_t MAX_RESULT_LEN = 1024;
    FILE *grep;
    int attempt = 0;

    assert (globals.do_code);
    assert (globals.directory);
    assert (sym && sym->symbol);

    if (!symbol_is_valid_c (sym))
        return - 1;

    if (!grep_buff)
        grep_buff = (char *) malloc (MAX_RESULT_LEN);

    if (!fgrep_buff)
        fgrep_buff = (char *) malloc (MAX_RESULT_LEN);

    if (!grep_buff || !fgrep_buff)
        fatal ("Out of Memory");

    /* Use 'grep' to tell us which possible files the function is in,
     * then use 'function_grep.pl' to get the prototype. If this fails the
     * first time then give grep a more general query (that doesn't
     * require an opening argument brace on the line with the function name).
     */
    while (attempt < 2)
    {
        FILE *f_grep;
        char *cmd = str_create (4, "grep -d recurse -l \"", sym->symbol,
                                !attempt ? "[:blank:]*(\" " : "\" ", globals.directory);

        if (VERBOSE)
            puts (cmd);

        fflush (NULL); /* See 'man popen' */

        if (!(grep = popen (cmd, "r")))
            fatal ("Cannot execute grep -l");
        free (cmd);

        while (fgets (grep_buff, MAX_RESULT_LEN, grep))
        {
            int i;
            const char *extension = grep_buff;
            for (i = 0; grep_buff[i] && grep_buff[i] != '\n' ; i++) {
                if (grep_buff[i] == '.')
                    extension = &grep_buff[i];
            }
            grep_buff[i] = '\0';

            /* Definitely not in these: */
            if (strcmp(extension,".dll") == 0 ||
                    strcmp(extension,".lib") == 0 ||
                    strcmp(extension,".so")  == 0 ||
                    strcmp(extension,".o")   == 0)
                continue;

            if (VERBOSE)
                puts (grep_buff);

            cmd = str_create (5, "function_grep.pl ", sym->symbol,
                              " \"", grep_buff, "\"");

            if (VERBOSE)
                puts (cmd);

            fflush (NULL); /* See 'man popen' */

            if (!(f_grep = popen (cmd, "r")))
                fatal ("Cannot execute function_grep.pl");
            free (cmd);

            while (fgets (grep_buff, MAX_RESULT_LEN, f_grep))
            {
                char *iter = grep_buff;

                /* Keep only the first line */
                symbol_clean_string(grep_buff);

                for (i = 0; grep_buff[i] && grep_buff[i] != '\n' ; i++)
                    ;
                grep_buff[i] = '\0';

                if (VERBOSE)
                    puts (grep_buff);

                while ((iter = strstr (iter, sym->symbol)))
                {
                    if (iter > grep_buff && (iter[-1] == ' ' || iter[-1] == '*') &&
                            (iter[strlen (sym->symbol)] == ' ' ||
                             iter[strlen (sym->symbol)] == '('))
                    {
                        if (VERBOSE)
                            printf ("Prototype '%s' looks OK, processing\n", grep_buff);

                        if (!symbol_from_prototype (sym, grep_buff))
                        {
                            pclose (f_grep);
                            pclose (grep);
                            return 0;  /* OK */
                        }
                        if (VERBOSE)
                            puts ("Failed, trying next");
                    }
                    else
                        iter += strlen (sym->symbol);
                }
            }
            pclose (f_grep);
        }
        pclose (grep);
        attempt++;
    }

    return -1; /* Not found */
}
示例#2
0
文件: main.c 项目: DeltaYang/wine
int   main (int argc, char *argv[])
#endif
{
    parsed_symbol symbol;
    int count = 0;

    globals.mode = NONE;
    globals.forward_dll = NULL;
    globals.input_name = NULL;
    globals.dumpsect = NULL;

    parse_options (argv);

    memset (&symbol, 0, sizeof (parsed_symbol));

    switch (globals.mode)
    {
    case DMGL:
        VERBOSE = TRUE;

        if (globals.input_name == NULL)
            fatal("No symbol name has been given\n");
        printf("%s\n", get_symbol_str(globals.input_name));
	break;

    case SPEC:
        if (globals.input_name == NULL)
            fatal("No file name has been given\n");
        set_module_name(TRUE);
	if (!dll_open (globals.input_name))
            break;

	output_spec_preamble ();
	output_header_preamble ();
	output_c_preamble ();

        while (dll_next_symbol (&symbol))
	{
	    count++;

	    if (NORMAL)
		printf ("Export %3d - '%s' ...%c", count, symbol.symbol,
			VERBOSE ? '\n' : ' ');

	    if (globals.do_code && symbol_searched(count, symbol.symbol))
	    {
		/* Attempt to get information about the symbol */
                BOOL result = symbol_demangle (&symbol) || symbol_search(&symbol);

                if (result && symbol.function_name)
		    /* Clean up the prototype */
		    symbol_clean_string (symbol.function_name);

		if (NORMAL)
                    puts (result ? "[OK]" : "[Not Found]");
	    }
	    else if (NORMAL)
		puts ("[Ignoring]");

	    output_spec_symbol (&symbol);
	    output_header_symbol (&symbol);
	    output_c_symbol (&symbol);

	    symbol_clear (&symbol);
	}

	output_makefile ();

	if (VERBOSE)
	    puts ("Finished, Cleaning up...");
        if (symbol_finish())
            return 1;
	break;
    case NONE:
	do_usage(0);
	break;
    case DUMP:
        if (globals.input_name == NULL)
            fatal("No file name has been given\n");
        set_module_name(FALSE);
	dump_file(globals.input_name);
	break;
    }

    return 0;
}
示例#3
0
文件: search.c 项目: howard5888/wineT
/*******************************************************************
 *         get_type
 *
 * Read a type from a prototype
 */
static const char *get_type (parsed_symbol *sym, const char *proto, int arg)
{
    int is_const, is_volatile, is_struct, is_signed, is_unsigned, ptrs = 0;
    const char *iter, *type_str, *base_type, *catch_unsigned;
    char dest_type;

    assert (sym && sym->symbol);
    assert (proto && *proto);
    assert (arg < 0 || (unsigned)arg == sym->argc);

    type_str = proto;

    proto = str_match (proto, "const", &is_const);
    proto = str_match (proto, "volatile", &is_volatile);
    proto = str_match (proto, "struct", &is_struct);
    if (!is_struct)
        proto = str_match (proto, "union", &is_struct);

    catch_unsigned = proto;

    proto = str_match (proto, "unsigned", &is_unsigned);
    proto = str_match (proto, "signed", &is_signed);

    /* Can have 'unsigned const' or 'const unsigned' etc */
    if (!is_const)
        proto = str_match (proto, "const", &is_const);
    if (!is_volatile)
        proto = str_match (proto, "volatile", &is_volatile);

    base_type = proto;
    iter = str_find_set (proto, " ,*)");
    if (!iter)
        return NULL;

    if (arg < 0 && (is_signed || is_unsigned))
    {
        /* Prevent calling convention from being swallowed by 'un/signed' alone */
        if (strncmp (base_type, "int", 3) && strncmp (base_type, "long", 4) &&
                strncmp (base_type, "short", 5) && strncmp (base_type, "char", 4))
        {
            iter = proto;
            base_type = catch_unsigned;
        } else
            catch_unsigned = NULL;
    }
    else
        catch_unsigned = NULL;

    /* FIXME: skip const/volatile here too */
    for (proto = iter; *proto; proto++)
        if (*proto == '*')
            ptrs++;
        else if (*proto != ' ')
            break;

    if (!*proto)
        return NULL;

    type_str = str_substring (type_str, proto);
    if (iter == base_type || catch_unsigned)
    {
        /* 'unsigned' with no type */
        char *tmp = str_create (2, type_str, " int");
        free ((char*)type_str);
        type_str = tmp;
    }
    symbol_clean_string (type_str);

    dest_type = symbol_get_type (type_str);

    if (arg < 0)
    {
        sym->return_text = (char*)type_str;
        sym->return_type = dest_type;
    }
    else
    {
        sym->arg_type [arg] = dest_type;
        sym->arg_flag [arg] = is_const ? CT_CONST : is_volatile ? CT_VOLATILE : 0;

        if (*proto == ',' || *proto == ')')
            sym->arg_name [arg] = str_create_num (1, arg, "arg");
        else
        {
            iter = str_find_set (proto, " ,)");
            if (!iter)
            {
                free ((char*)type_str);
                return NULL;
            }
            sym->arg_name [arg] = str_substring (proto, iter);
            proto = iter;
        }
        sym->arg_text [arg] = (char*)type_str;

    }
    return proto;
}