Вопрос

Я работаю над небольшим научным исследованием о чрезвычайно длинные и сложные функции в ядре Linux.Я пытаюсь выяснить, есть ли веская причина писать функции длиной 600 или 800 строк.

Для этой цели я хотел бы найти инструмент, который может извлекать функцию из файла .c, чтобы я мог запустить несколько автоматических тестов этой функции.

Например, если у меня есть функция cifs_parse_mount_options() внутри файла connect.c, я ищу решение, которое примерно будет работать так:

extract /fs/cifs/connect.c cifs_parse_mount_options

и верните 523 строки кода (!) функции, от открывающих до закрывающих скобок.

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

Спасибо,

Уди

РЕДАКТИРОВАТЬ : Ответы на Regex для извлечения объявлений прототипов функций C? убедил меня, что сопоставление объявления функции с помощью регулярного выражения далеко не тривиально.

Это было полезно?

Решение

Почему бы вам не написать небольшой скрипт на PERL/PHP/Python или даже небольшую программу на C++, Java или C#, которая сделает это?

Я не знаю каких-либо готовых инструментов для этого, но написание кода для анализа текстового файла и извлечения тела функции из файла кода C++ не должно занимать более 20 строк кода.Единственный трудный часть будет искать начало функции, и это должна быть относительно простая задача с использованием RegEx.После этого все, что вам нужно, это перебрать остальную часть файла, отслеживая открытие и закрытие фигурных скобок, и когда вы дойдете до закрывающей скобки тела функции, все готово.

Другие советы

отступ -kr код -o code.out

awk -f Split.awk code.out

вам нужно немного адаптировать файл Split.awk, который несколько специфичен для моего кода и потребностей рефакторинга (например, у вас есть такая структура, которая не является typedefs

И я уверен, что вы можете сделать сценарий получше :-)

--
BEGIN   { line=0; FS="";
    out=ARGV[ARGC-1]  ".out";
    var=ARGV[ARGC-1]  ".var";
    ext=ARGV[ARGC-1]  ".ext";
    def=ARGV[ARGC-1]  ".def";
    inc=ARGV[ARGC-1]  ".inc";
    typ=ARGV[ARGC-1]  ".typ";
    system ( rm " " -f " " out " " var " " ext " " def " " inc " " typ );
    }
/^[     ]*\/\/.*/   { print "comment :" $0 "\n"; print $0 >> out ; next ;}
/^#define.*/        { print "define :" $0 ; print $0 >>def ; next;}
/^#include.*/       { print "define :" $0 ; print $0 >>inc ; next;}
/^typedef.*{$/      { print "typedef var :" $0 "\n"; decl="typedef";print $0 >> typ;infile="typ";next;}
/^extern.*$/        { print "extern :" $0 "\n"; print $0 >> ext;infile="ext";next;}
/^[^    }].*{$/     { print "init var :" $0 "\n";decl="var";print $0 >> var; infile="vars";
                print $0;
                fout=gensub("^([^    \\*])*[    ]*([a-zA-A0-9_]*)\\[.*","\\2","g") ".vars";
                     print "var decl : " $0 "in file " fout;
                     print $0 >fout;
                next;
                        }
/^[^    }].*)$/     { print "func  :" $0 "\n";decl="func"; infile="func";
                print $0;
                fout=gensub("^.*[    \\*]([a-zA-A0-9_]*)[   ]*\\(.*","\\1","g") ".func";
                     print "function : " $0 "in file " fout;
                     print $0 >fout;
                next;
            }
/^}[    ]*$/        { print "end of " decl ":" $0 "\n"; 
                if(infile=="typ") {
                    print $0 >> typ;
                }else if (infile=="ext"){
                    print $0 >> ext;
                }else if (infile=="var") {
                    print $0 >> var;
                }else if ((infile=="func")||(infile=="vars")) {
                    print $0 >> fout; 
                    fflush (fout);
                    close (fout);
                }else if (infile=="def") {
                    print $0 >> def;
                }else if (infile=="inc"){
                    print $0 >> inc;
                }else print $0 >> out;
                next;
            }
/^[a-zA-Z_]/        { print "extern :" $0 "\n"; print $0 >> var;infile="var";next;}
            { print "other :" $0 "\n" ; 
                if(infile=="typ") {
                    print $0 >> typ;
                }else if (infile=="ext"){
                    print $0 >> ext;
                }else if (infile=="var") {
                    print $0 >> var;
                }else if ((infile=="func")||(infile=="vars")){
                    print $0 >> fout;
                }else if (infile=="def") {
                    print $0 >> def;
                }else if (infile=="inc"){
                    print $0 >> inc;
                }else print $0 >> out;
               next;
               }

если вам сложно извлечь имена функций:

1> используйте ctags (программу) для извлечения имен функций.ctags -x --c-kinds=fp path_to_file.2> как только вы получили имена функций, напишите простой сценарий Perl для извлечения содержимого функции, передав имя функции сценария, как указано выше.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top