Question

Je travaille sur une petite recherche universitaire sur les fonctions extrêmement longues et compliquées dans le noyau Linux . J'essaie de savoir s'il y a une bonne raison d'écrire 600 ou 800 fonctions lignes longues.

À cette fin, je voudrais trouver un outil qui peut extraire une fonction à partir d'un fichier .c, donc je peux exécuter des tests automatisés sur la fonction.

Par exemple, si je la fonction cifs_parse_mount_options() dans le fichier connect.c, je suis à la recherche d'une solution qui fonctionnerait à peu près comme:

extract /fs/cifs/connect.c cifs_parse_mount_options

et retourner les 523 lignes de code (!) De la fonction, de l'ouverture des accolades pour les entretoises de fermeture.

Bien sûr, une façon de manipuler les paquets logiciels existants comme gcc pour le faire, serait le plus utile aussi.

Merci,

Udi

EDIT: Les réponses à Regex de tirer des déclarations de prototypes de fonction C? m'a convaincu que la déclaration de fonction correspondant par expression rationnelle est loin d'être anodin.

Était-ce utile?

La solution

Pourquoi écrivez-vous pas un petit PERL / PHP / script Python ou même un petit C ++, programme Java ou C # qui fait cela?

Je ne connais pas d'outils déjà fait pour le faire, mais l'écriture du code pour analyser le fichier texte et l'extrait d'un corps de la fonction d'un fichier de code C ++ ne devrait pas prendre plus de 20 lignes de code .. La seule difficile partie sera le début de la localisation de la fonction et qui devrait être une tâche relativement simple utilisant l'expression rationnelle. Après cela, tout ce que vous avez besoin est d'itérer le reste du fichier garder la trace de l'ouverture et la fermeture des accolades et lorsque vous atteignez l'accolade fermante corps de la fonction que vous avez terminé.

Autres conseils

tiret Code -kr -o code.out

awk -f split.awk code.out

vous devez adapter un peu split.awk Wich est un peu spécifique à mes besoins de code et refactoring (par exemple y ont struct donc qui ne sont pas typedefs

Et je suis sûr que vous pouvez faire un script plus agréable: -)

--
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;
               }

dans le cas où vous trouvez difficile d'extraire les noms de fonction:

1> utiliser ctags (programme) pour extraire des noms de fonctions.   ctags -x-types = --c fp chemin_du_fichier. 2> une fois u a obtenu les noms de fonction, écrire un script Perl simple pour extraire le contenu de la fonction en passant le nom du script de la fonction comme dit ci-dessus.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top