Как найти функции в cpp файле, которые содержат определенное слово

Я добился этого в два этапа:

1) Добавить пользовательское правило сборки для .metal файлов, которое индивидуально компилирует их в .metallib с:

enter image description here

2) Добавьте пользовательский шаг сборки для копирования этих .metallib в цель:

enter image description here [1111 ]

5
задан andreas buykx 7 May 2009 в 10:00
поделиться

8 ответов

As far as I know, this can't be done. Here's why:

First, you have to search across lines. No problem, in vim adding a _ to a character class tells it to include new lines. so {_.*} would match everything between those brackets across multiple lines.

So now you need to match whatever the pattern is for a function header(brittle even if you get it to work), then , and here's the problem, whatever lines are between it and your search string, and finally match your search string. So you might have a regex like

/^\(void \+\a\+ *(.*)\)\_.*JOHN_DOE

But what happens is the first time vim finds a function header, it starts matching. It then matches every character until it finds JOHN_DOE. Which includes all the function headers in the file.

So the problem is that, as far as I know, there's no way to tell vim to match every character except for this regex pattern. And even if there was, a regex is not the tool for this job. It's like opening a beer with a hammer. What we should do is write a simple script that gives you this info, and I have.

fun! FindMyFunction(searchPattern, funcPattern)
  call search(a:searchPattern)
  let lineNumber = line(".")
  let lineNumber = lineNumber - 1
  "call setpos(".", [0,  lineNumber, 0, 0])

  let lineString = getline(lineNumber)
  while lineString !~ a:funcPattern
    let lineNumber = lineNumber - 1
    if lineNumber < 0
      echo "Function not found :/"
    endif
    let lineString = getline(lineNumber)
  endwhile

  echo lineString

endfunction

That should give you the result you want and it's way easier to share, debug, and repurpose than a regular expression spit from the mouth of Cthulhu himself.

2
ответ дан 14 December 2019 в 01:16
поделиться

Вероятно, за это меня проголосуют!

Я заядлый (G) пользователь VIM, но когда я хочу просмотреть или понять какой-то код, я использую Source Insight . Я почти никогда не использую его как настоящий редактор.

В этом случае он делает именно то, что вам нужно, например, показывает все функции / методы, которые используют какой-то выделенный тип данных / define / constant / etc ... в окне отношений ...

gif of the relations window from the source insight website
(источник: sourceinsight.com )

Ой! Вот мой представитель.

3
ответ дан 14 December 2019 в 01:16
поделиться

Tough call, although as a starting point I would suggest this wonderful VIM Regex Tutorial.

1
ответ дан 14 December 2019 в 01:16
поделиться

You cannot do that reliably with a regular expression, because code is not a regular language. You need a real parser for the language in question.

1
ответ дан 14 December 2019 в 01:16
поделиться

Для такого рода вещей, хотя это снова касается примитивного поиска, я бы порекомендовал плагин compview . Откроется окно поиска, так что вы сможете увидеть всю строку, где произошел поиск, и автоматически перейти к ней. Дает хороший обзор.

alt text
(источник: axisym3.net )

1
ответ дан 14 December 2019 в 01:16
поделиться

Как сказал Роберт, Регекс поможет. В командном режиме запустите поиск по регулярному выражению, введя символ "/", а затем свое регулярное выражение.

Ctags 1 также могут быть вам полезны. Он может генерировать файл тегов для проекта. Этот файл тегов позволяет пользователю переходить непосредственно от вызова функции к его определению, даже если он находится в другом файле с помощью «CTRL +]».

0
ответ дан 14 December 2019 в 01:16
поделиться

вы можете использовать grep -r -n -H JOHN_DOE * он будет искать «JOHN_DOE» в файлах, рекурсивно начиная с текущего каталога

, который вы можете использовать следующий код, чтобы практически найти функцию, которая содержит текстовое выражение:

    public void findFunction(File file, String expression) {
    Reader r = null;
    try {
        r = new FileReader(file);
    } catch (FileNotFoundException ex) {
        ex.printStackTrace();
    }
    BufferedReader br = new BufferedReader(r);

    String match = "";
    String lineWithNameOfFunction = "";

    Boolean matchFound = false;

    try {
        while(br.read() > 0) {
            match = br.readLine();
            if((match.endsWith(") {")) ||
                    (match.endsWith("){")) ||
                    (match.endsWith("()")) ||
                    (match.endsWith(")")) ||
                    (match.endsWith("( )"))) {
                // this here is because i guessed that method will start
                // at the 0
                if((match.charAt(0)!=' ') && !(match.startsWith("\t"))) {
                    lineWithNameOfFunction = match;                        
                }
            }

            if(match.contains(expression)) {
                matchFound = true;
                break;
            }
        }
        if(matchFound)
            System.out.println(lineWithNameOfFunction);
        else 
            System.out.println("No matching function found");
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

я написал это в JAVA, протестировал его и работает как шарм. Есть несколько недостатков, но для начала это хорошо. не добавлена ​​поддержка нескольких функций, содержащих одно и то же выражение и, возможно, некоторые другие вещи. попробуй.

0
ответ дан 14 December 2019 в 01:16
поделиться

Ага! Я признаю, что это немного перебор:

Маленькая программа для фильтрации стандартного ввода, удаления комментариев и помещения тел функций в одну строку. Помимо прочего, его обманут пространства имен и определения функций внутри объявлений классов. Но это может быть хорошим началом:

#include <stdio.h>
#include <assert.h>

int main() {
    enum {
        NORMAL,
        LINE_COMMENT,
        MULTI_COMMENT,
        IN_STRING,
    } state = NORMAL;
    unsigned depth = 0;
    for(char c=getchar(),prev=0; !feof(stdin); prev=c,c=getchar()) {
        switch(state) {
        case NORMAL:
            if('/'==c && '/'==prev)
                state = LINE_COMMENT;
            else if('*'==c && '/'==prev)
                state = MULTI_COMMENT;
            else if('#'==c)
                state = LINE_COMMENT;
            else if('\"'==c) {
                state = IN_STRING;
                putchar(c);
            } else {
                if(('}'==c && !--depth) || (';'==c && !depth)) {
                    putchar(c);
                    putchar('\n');
                } else {
                    if('{'==c)
                        depth++;
                    else if('/'==prev && NORMAL==state)
                        putchar(prev);
                    else if('\t'==c)
                        c = ' ';
                    if(' '==c && ' '!=prev)
                        putchar(c);
                    else if(' '<c && '/'!=c)
                        putchar(c);
                }
            }
            break;
        case LINE_COMMENT:
            if(' '>c)
                state = NORMAL;
            break;
        case MULTI_COMMENT:
            if('/'==c && '*'==prev) {
                c = '\0';
                state = NORMAL;
            }
            break;
        case IN_STRING:
            if('\"'==c && '\\'!=prev)
                state = NORMAL;
            putchar(c);
            break;
        default:
            assert(!"bug");
        }
    }
    putchar('\n');
    return 0;
}

Его c ++, поэтому просто его в файле, скомпилируйте его в файл с именем 'stripper', а затем:

cat my_source.cpp | ./stripper | grep JOHN_DOE

Итак, рассмотрим ввод:

int foo ( int arg1 ) 
{
    /// code 
}
void bar ( std::string arg2  )
{
    /// code
    aFunctionCall( JOHN_DOE );
    /// more code
}

Вывод " cat example.cpp | ./stripper ":

int foo ( int arg1 ) { }
void bar ( std::string arg2 ){  aFunctionCall( JOHN_DOE ); }

Результатом" cat example.cpp | ./stripper | grep JOHN_DOE "является:

void bar ( std::string arg2 ){  aFunctionCall( JOHN_DOE ); }

Задача поиска имя функции (предположить, что это последний идентификатор, предшествующий " (") - оставлено читателю в качестве упражнения.

1
ответ дан 14 December 2019 в 01:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: