#--------------------------------------------------------------------------- # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # Author: Anne Pacalet (mailto:anne.pacalet@tele2.fr) #--------------------------------------------------------------------------- # gprof.awk : génération d'un fichiers html à partir d'un fichier gprof. # Usage : ne pas utiliser directement, mais plutôt à travers gprof_html # (pour test : gawk -f gprof.awk fic.gprof > fic.gprof.html) #--------------------------------------------------------------------------- # #--------------------------------------------------------------------------- #=== Debug function Debug(txt) { #print txt > "/dev/stderr"; #print txt; } #=== PrintSep function PrintSep() { print "
"; InfoFct[IndiceCG] = InfoFct[IndiceCG] Memo; Memo = ""; } #=== LiensNumeros # remplace [] par un lien vers #id dans toute la ligne courante. function LiensNumeros() { $0 = gensub(/\[([0-9]*)\]/, "[\\1]", "g"); } #=== NomFct : indice de début du nom, indice de fin # construit un nom en concaténant les champs situés entre les 2 indices. function NomFct(i0,i1) { nom = ""; for (ch = i0; ch <= i1; ch++) nom = nom " " $(ch); return nom; } #------------------------------------------------------------------------------ #=== Début du fitre : BEGIN { IndiceCG = 0; IndiceFP = 0; # NumPartie = 0 => Flat Profile (FP) # NumPartie = 1 => Call Graph (CG) NumPartie = 0; # nom de la fonction courante pendant l'analyse du graphe d'appel. NomFctCourante = ""; } $1 == "" { NumPartie++; if (NumPartie == 2) exit; next; } $1 == " " { spontaneous = 1; } { # introduction des balises HTML pour < et > gsub(/, "\\<"); gsub(/>/, "\\>"); } NumPartie == 0 && /^[ ]*[0-9]/ { IndiceFP++; # si le champ 4 contient des lettres, c'est là que commence le nom. debut_nom = ($4 ~ /[A-Za-z_]/) ? 4 : 7; nom_fct_flat = NomFct(debut_nom, NF); TableIndiceFlatFromNom[nom_fct_flat] = IndiceFP; LigneFlat[IndiceFP] = $0; next; } NumPartie == 0 && IndiceFP == 0 { PreFlat = PreFlat $0 "\n"; next; } NumPartie == 0 && IndiceFP > 0 { PostFlat = PostFlat $0 "\n"; next; } NumPartie == 0 || NumPartie == 2 { next; } /^--------------/ { # Séparateur entre les fonctions dans le CG => réinitialisation : spontaneous = 0; NomFctCourante = ""; on_passe = 0; IndiceCG ++; next; } on_passe == 1 { next; } /^\[/ { # on récupère le numéro de la fonction courante avant d'ajouter les liens num_fct = gensub(/\[(.*)\]/, "\\1", "1", $1); # ATTENTION : certains numéros n'existent pas... => num_fct != IndiceCG NomFctCourante = NomFct(6 - spontaneous, NF-1); TraiteFctCG(num_fct, NomFctCourante); if (NomFctCourante ~ /std::/) { on_passe = 1; InfoFct[IndiceCG] = InfoFct[IndiceCG] \ "on ne détaille pas les fonctions de la STL"; } else { LiensNumeros(); InfoFct[IndiceCG] = InfoFct[IndiceCG] $0 "\n"; } next; } /\[[0-9]*\]/ { LiensNumeros(); } # on est avant la fonction elle-même : c'est les appelants NumPartie == 1 && NomFctCourante == "" { Memo = Memo $0 "
"; if (IndiceCG == 0 && $1 ~ /index/) { InfoFct[0] = Memo; Memo = ""; IndiceCG = 1; } next; } NumPartie == 1 && NomFctCourante != "" { InfoFct[IndiceCG] = InfoFct[IndiceCG] $0 "\n"; } END { print "Gprof Results "; print ""; PrintSep(); print "Call Graph
" print ""; for (i = 0; i < IndiceCG; i++) { print InfoFct[i]; PrintSep(); } print ""; print "Call Graph Help
"; print "" Memo ""; PrintSep(); print "Flat Profile
" print ""; print PreFlat; for (i = 0; i < IndiceFP; i++) { if (i % 10 == 0) PrintSep(); i_call = TableIndiceCall[i]; print ""; print "[" i_call "]" LigneFlat[i]; } PrintSep(); print ""; print "Flat Profile Help
"; print "" PostFlat ""; print "" }