#--------------------------------------------------------------------------- # 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 "
[home_call]" \ "[help_call]" \ "[home_flat]" \ "[help_flat]" \ ; } #=== TraiteFctCG : numéro, nom # Génère le titre pour la fonction, ajoute les appelants (Memo), # et fait la correspondance entre l'indice dans le CG, et celui dans le FP. function TraiteFctCG(num, nom) { InfoFct[IndiceCG] = "

" num " - " nom ; # ôte du nom car ça n'apparait pas dans la partie Flat Profile. sub(/[ ]*\<cycle .*\>[ ]*/, "", nom); if (nom != "") { i_flat = TableIndiceFlatFromNom[nom]; if (i_flat == 0) { print "WARNING : function " nom " : not in Flat Profile ?" > "/dev/stderr"; } else { TableIndiceCall[i_flat] = IndiceCG; TableIndiceFlat[IndiceCG] = i_flat; if (i_flat != 0) { InfoFct[IndiceCG] = InfoFct[IndiceCG] \ " (" i_flat "/" IndiceFP ")" } } } InfoFct[IndiceCG] = InfoFct[IndiceCG] "

";
  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(//, "\\>"); 
 }

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