1 /* $OpenBSD: printgprof.c,v 1.4 2001/03/31 23:27:02 fgsch Exp $ */ 2 /* $NetBSD: printgprof.c,v 1.5 1995/04/19 07:16:21 cgd Exp $ */ 3 4 /* 5 * Copyright (c) 1983, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37 #ifndef lint 38 #if 0 39 static char sccsid[] = "@(#)printgprof.c 8.1 (Berkeley) 6/6/93"; 40 #else 41 static char rcsid[] = "$OpenBSD: printgprof.c,v 1.4 2001/03/31 23:27:02 fgsch Exp $"; 42 #endif 43 #endif /* not lint */ 44 45 #include "gprof.h" 46 #include "pathnames.h" 47 48 void 49 printprof() 50 { 51 register nltype *np; 52 nltype **sortednlp; 53 int index; 54 55 actime = 0.0; 56 printf( "\f\n" ); 57 flatprofheader(); 58 /* 59 * Sort the symbol table in by time 60 */ 61 sortednlp = (nltype **) calloc( nname , sizeof(nltype *) ); 62 if ( sortednlp == (nltype **) 0 ) 63 warnx("[printprof] ran out of memory for time sorting"); 64 for ( index = 0 ; index < nname ; index += 1 ) { 65 sortednlp[ index ] = &nl[ index ]; 66 } 67 qsort( sortednlp , nname , sizeof(nltype *) , timecmp ); 68 for ( index = 0 ; index < nname ; index += 1 ) { 69 np = sortednlp[ index ]; 70 flatprofline( np ); 71 } 72 actime = 0.0; 73 free( sortednlp ); 74 } 75 76 int 77 timecmp( npp1 , npp2 ) 78 nltype **npp1, **npp2; 79 { 80 double timediff; 81 long calldiff; 82 83 timediff = (*npp2) -> time - (*npp1) -> time; 84 if ( timediff > 0.0 ) 85 return 1 ; 86 if ( timediff < 0.0 ) 87 return -1; 88 calldiff = (*npp2) -> ncall - (*npp1) -> ncall; 89 if ( calldiff > 0 ) 90 return 1; 91 if ( calldiff < 0 ) 92 return -1; 93 return( strcmp( (*npp1) -> name , (*npp2) -> name ) ); 94 } 95 96 /* 97 * header for flatprofline 98 */ 99 void 100 flatprofheader() 101 { 102 103 if (bflag) 104 printblurb( _PATH_FLAT_BLURB ); 105 printf("\ngranularity: each sample hit covers %ld byte(s)", 106 (long) scale * sizeof(UNIT)); 107 if (totime > 0.0) 108 printf(" for %.2f%% of %.2f seconds\n\n" , 100.0/totime, totime / hz); 109 else { 110 printf( " no time accumulated\n\n" ); 111 /* 112 * this doesn't hurt sinc eall the numerators will be zero. 113 */ 114 totime = 1.0; 115 } 116 printf("%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n" , 117 "% " , "cumulative" , "self " , "" , "self " , "total " , "" ); 118 printf("%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n" , 119 "time" , "seconds " , "seconds" , "calls" , 120 "ms/call" , "ms/call" , "name" ); 121 } 122 123 void 124 flatprofline( np ) 125 register nltype *np; 126 { 127 128 if ( zflag == 0 && np -> ncall == 0 && np -> time == 0 ) { 129 return; 130 } 131 actime += np -> time; 132 printf( "%5.1f %10.2f %8.2f" , 133 100 * np -> time / totime , actime / hz , np -> time / hz ); 134 if ( np -> ncall != 0 ) { 135 printf( " %8ld %8.2f %8.2f " , np -> ncall , 136 1000 * np -> time / hz / np -> ncall , 137 1000 * ( np -> time + np -> childtime ) / hz / np -> ncall ); 138 } else { 139 printf( " %8.8s %8.8s %8.8s " , "" , "" , "" ); 140 } 141 printname( np ); 142 printf( "\n" ); 143 } 144 145 void 146 gprofheader() 147 { 148 149 if ( bflag ) { 150 printblurb( _PATH_CALLG_BLURB ); 151 } 152 printf( "\ngranularity: each sample hit covers %ld byte(s)" , 153 (long) scale * sizeof(UNIT) ); 154 if ( printtime > 0.0 ) { 155 printf( " for %.2f%% of %.2f seconds\n\n" , 156 100.0/printtime , printtime / hz ); 157 } else { 158 printf( " no time propagated\n\n" ); 159 /* 160 * this doesn't hurt, since all the numerators will be 0.0 161 */ 162 printtime = 1.0; 163 } 164 printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n" , 165 "" , "" , "" , "" , "called" , "total" , "parents"); 166 printf( "%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n" , 167 "index" , "%time" , "self" , "descendents" , 168 "called" , "self" , "name" , "index" ); 169 printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n" , 170 "" , "" , "" , "" , "called" , "total" , "children"); 171 printf( "\n" ); 172 } 173 174 void 175 gprofline( np ) 176 register nltype *np; 177 { 178 char kirkbuffer[ BUFSIZ ]; 179 180 sprintf( kirkbuffer , "[%d]" , np -> index ); 181 printf( "%-6.6s %5.1f %7.2f %11.2f" , kirkbuffer , 182 100 * ( np -> propself + np -> propchild ) / printtime , 183 np -> propself / hz , np -> propchild / hz ); 184 if ( ( np -> ncall + np -> selfcalls ) != 0 ) { 185 printf( " %7ld" , np -> npropcall ); 186 if ( np -> selfcalls != 0 ) { 187 printf( "+%-7ld " , np -> selfcalls ); 188 } else { 189 printf( " %7.7s " , "" ); 190 } 191 } else { 192 printf( " %7.7s %7.7s " , "" , "" ); 193 } 194 printname( np ); 195 printf( "\n" ); 196 } 197 198 void 199 printgprof(timesortnlp) 200 nltype **timesortnlp; 201 { 202 int index; 203 nltype *parentp; 204 205 /* 206 * Print out the structured profiling list 207 */ 208 gprofheader(); 209 for ( index = 0 ; index < nname + ncycle ; index ++ ) { 210 parentp = timesortnlp[ index ]; 211 if ( zflag == 0 && 212 parentp -> ncall == 0 && 213 parentp -> selfcalls == 0 && 214 parentp -> propself == 0 && 215 parentp -> propchild == 0 ) { 216 continue; 217 } 218 if ( ! parentp -> printflag ) { 219 continue; 220 } 221 if ( parentp -> name == 0 && parentp -> cycleno != 0 ) { 222 /* 223 * cycle header 224 */ 225 printcycle( parentp ); 226 printmembers( parentp ); 227 } else { 228 printparents( parentp ); 229 gprofline( parentp ); 230 printchildren( parentp ); 231 } 232 printf( "\n" ); 233 printf( "-----------------------------------------------\n" ); 234 printf( "\n" ); 235 } 236 free( timesortnlp ); 237 } 238 239 /* 240 * sort by decreasing propagated time 241 * if times are equal, but one is a cycle header, 242 * say that's first (e.g. less, i.e. -1). 243 * if one's name doesn't have an underscore and the other does, 244 * say the one is first. 245 * all else being equal, sort by names. 246 */ 247 int 248 totalcmp( npp1 , npp2 ) 249 nltype **npp1; 250 nltype **npp2; 251 { 252 register nltype *np1 = *npp1; 253 register nltype *np2 = *npp2; 254 double diff; 255 256 diff = ( np1 -> propself + np1 -> propchild ) 257 - ( np2 -> propself + np2 -> propchild ); 258 if ( diff < 0.0 ) 259 return 1; 260 if ( diff > 0.0 ) 261 return -1; 262 if ( np1 -> name == 0 && np1 -> cycleno != 0 ) 263 return -1; 264 if ( np2 -> name == 0 && np2 -> cycleno != 0 ) 265 return 1; 266 if ( np1 -> name == 0 ) 267 return -1; 268 if ( np2 -> name == 0 ) 269 return 1; 270 if ( *(np1 -> name) != '_' && *(np2 -> name) == '_' ) 271 return -1; 272 if ( *(np1 -> name) == '_' && *(np2 -> name) != '_' ) 273 return 1; 274 if ( np1 -> ncall > np2 -> ncall ) 275 return -1; 276 if ( np1 -> ncall < np2 -> ncall ) 277 return 1; 278 return strcmp( np1 -> name , np2 -> name ); 279 } 280 281 void 282 printparents( childp ) 283 nltype *childp; 284 { 285 nltype *parentp; 286 arctype *arcp; 287 nltype *cycleheadp; 288 289 if ( childp -> cyclehead != 0 ) { 290 cycleheadp = childp -> cyclehead; 291 } else { 292 cycleheadp = childp; 293 } 294 if ( childp -> parents == 0 ) { 295 printf( "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontaneous>\n" , 296 "" , "" , "" , "" , "" , "" ); 297 return; 298 } 299 sortparents( childp ); 300 for ( arcp = childp -> parents ; arcp ; arcp = arcp -> arc_parentlist ) { 301 parentp = arcp -> arc_parentp; 302 if ( childp == parentp || ( arcp -> arc_flags & DEADARC ) || 303 ( childp->cycleno != 0 && parentp->cycleno == childp->cycleno ) ) { 304 /* 305 * selfcall or call among siblings 306 */ 307 printf( "%6.6s %5.5s %7.7s %11.11s %7ld %7.7s " , 308 "" , "" , "" , "" , 309 arcp -> arc_count , "" ); 310 printname( parentp ); 311 printf( "\n" ); 312 } else { 313 /* 314 * regular parent of child 315 */ 316 printf( "%6.6s %5.5s %7.2f %11.2f %7ld/%-7ld " , 317 "" , "" , 318 arcp -> arc_time / hz , arcp -> arc_childtime / hz , 319 arcp -> arc_count , cycleheadp -> npropcall ); 320 printname( parentp ); 321 printf( "\n" ); 322 } 323 } 324 } 325 326 void 327 printchildren( parentp ) 328 nltype *parentp; 329 { 330 nltype *childp; 331 arctype *arcp; 332 333 sortchildren( parentp ); 334 arcp = parentp -> children; 335 for ( arcp = parentp -> children ; arcp ; arcp = arcp -> arc_childlist ) { 336 childp = arcp -> arc_childp; 337 if ( childp == parentp || ( arcp -> arc_flags & DEADARC ) || 338 ( childp->cycleno != 0 && childp->cycleno == parentp->cycleno ) ) { 339 /* 340 * self call or call to sibling 341 */ 342 printf( "%6.6s %5.5s %7.7s %11.11s %7ld %7.7s " , 343 "" , "" , "" , "" , arcp -> arc_count , "" ); 344 printname( childp ); 345 printf( "\n" ); 346 } else { 347 /* 348 * regular child of parent 349 */ 350 printf( "%6.6s %5.5s %7.2f %11.2f %7ld/%-7ld " , 351 "" , "" , 352 arcp -> arc_time / hz , arcp -> arc_childtime / hz , 353 arcp -> arc_count , childp -> cyclehead -> npropcall ); 354 printname( childp ); 355 printf( "\n" ); 356 } 357 } 358 } 359 360 void 361 printname( selfp ) 362 nltype *selfp; 363 { 364 365 if ( selfp -> name != 0 ) { 366 printf( "%s" , selfp -> name ); 367 # ifdef DEBUG 368 if ( debug & DFNDEBUG ) { 369 printf( "{%d} " , selfp -> toporder ); 370 } 371 if ( debug & PROPDEBUG ) { 372 printf( "%5.2f%% " , selfp -> propfraction ); 373 } 374 # endif DEBUG 375 } 376 if ( selfp -> cycleno != 0 ) { 377 printf( " <cycle %d>" , selfp -> cycleno ); 378 } 379 if ( selfp -> index != 0 ) { 380 if ( selfp -> printflag ) { 381 printf( " [%d]" , selfp -> index ); 382 } else { 383 printf( " (%d)" , selfp -> index ); 384 } 385 } 386 } 387 388 void 389 sortchildren( parentp ) 390 nltype *parentp; 391 { 392 arctype *arcp; 393 arctype *detachedp; 394 arctype sorted; 395 arctype *prevp; 396 397 /* 398 * unlink children from parent, 399 * then insertion sort back on to sorted's children. 400 * *arcp the arc you have detached and are inserting. 401 * *detachedp the rest of the arcs to be sorted. 402 * sorted arc list onto which you insertion sort. 403 * *prevp arc before the arc you are comparing. 404 */ 405 sorted.arc_childlist = 0; 406 for ((arcp = parentp -> children) && (detachedp = arcp -> arc_childlist); 407 arcp ; 408 (arcp = detachedp) && (detachedp = detachedp -> arc_childlist)) { 409 /* 410 * consider *arcp as disconnected 411 * insert it into sorted 412 */ 413 for ( prevp = &sorted ; 414 prevp -> arc_childlist ; 415 prevp = prevp -> arc_childlist ) { 416 if ( arccmp( arcp , prevp -> arc_childlist ) != LESSTHAN ) { 417 break; 418 } 419 } 420 arcp -> arc_childlist = prevp -> arc_childlist; 421 prevp -> arc_childlist = arcp; 422 } 423 /* 424 * reattach sorted children to parent 425 */ 426 parentp -> children = sorted.arc_childlist; 427 } 428 429 void 430 sortparents( childp ) 431 nltype *childp; 432 { 433 arctype *arcp; 434 arctype *detachedp; 435 arctype sorted; 436 arctype *prevp; 437 438 /* 439 * unlink parents from child, 440 * then insertion sort back on to sorted's parents. 441 * *arcp the arc you have detached and are inserting. 442 * *detachedp the rest of the arcs to be sorted. 443 * sorted arc list onto which you insertion sort. 444 * *prevp arc before the arc you are comparing. 445 */ 446 sorted.arc_parentlist = 0; 447 for ((arcp = childp->parents) && (detachedp = arcp->arc_parentlist); 448 arcp; (arcp = detachedp) && (detachedp = detachedp->arc_parentlist)) { 449 /* 450 * consider *arcp as disconnected 451 * insert it into sorted 452 */ 453 for (prevp = &sorted; prevp->arc_parentlist; 454 prevp = prevp->arc_parentlist) 455 if (arccmp(arcp , prevp->arc_parentlist) != GREATERTHAN) 456 break; 457 arcp->arc_parentlist = prevp->arc_parentlist; 458 prevp->arc_parentlist = arcp; 459 } 460 /* 461 * reattach sorted arcs to child 462 */ 463 childp -> parents = sorted.arc_parentlist; 464 } 465 466 /* 467 * print a cycle header 468 */ 469 void 470 printcycle( cyclep ) 471 nltype *cyclep; 472 { 473 char kirkbuffer[ BUFSIZ ]; 474 475 sprintf(kirkbuffer , "[%d]" , cyclep->index); 476 printf("%-6.6s %5.1f %7.2f %11.2f %7ld", kirkbuffer, 477 100 * (cyclep->propself + cyclep->propchild) / printtime, 478 cyclep->propself / hz, cyclep->propchild / hz, cyclep->npropcall); 479 if (cyclep -> selfcalls != 0) 480 printf("+%-7ld" , cyclep->selfcalls); 481 else 482 printf(" %7.7s" , ""); 483 printf(" <cycle %d as a whole>\t[%d]\n" , 484 cyclep->cycleno , cyclep->index ); 485 } 486 487 /* 488 * print the members of a cycle 489 */ 490 void 491 printmembers( cyclep ) 492 nltype *cyclep; 493 { 494 nltype *memberp; 495 496 sortmembers( cyclep ); 497 for ( memberp = cyclep -> cnext ; memberp ; memberp = memberp -> cnext ) { 498 printf( "%6.6s %5.5s %7.2f %11.2f %7ld" , "", "", 499 memberp->propself / hz, memberp->propchild / hz, memberp->npropcall ); 500 if (memberp -> selfcalls != 0) 501 printf("+%-7ld" , memberp -> selfcalls); 502 else 503 printf(" %7.7s", ""); 504 printf(" "); 505 printname(memberp); 506 printf("\n"); 507 } 508 } 509 510 /* 511 * sort members of a cycle 512 */ 513 void 514 sortmembers( cyclep ) 515 nltype *cyclep; 516 { 517 nltype *todo; 518 nltype *doing; 519 nltype *prev; 520 521 /* 522 * detach cycle members from cyclehead, 523 * and insertion sort them back on. 524 */ 525 todo = cyclep -> cnext; 526 cyclep -> cnext = 0; 527 for ((doing = todo) && (todo = doing -> cnext); 528 doing; (doing = todo) && (todo = doing -> cnext)) { 529 for (prev = cyclep; prev -> cnext; prev = prev -> cnext) 530 if (membercmp(doing, prev->cnext ) == GREATERTHAN) 531 break; 532 doing -> cnext = prev -> cnext; 533 prev -> cnext = doing; 534 } 535 } 536 537 /* 538 * major sort is on propself + propchild, 539 * next is sort on ncalls + selfcalls. 540 */ 541 int 542 membercmp( this , that ) 543 nltype *this; 544 nltype *that; 545 { 546 double thistime = this -> propself + this -> propchild; 547 double thattime = that -> propself + that -> propchild; 548 long thiscalls = this -> ncall + this -> selfcalls; 549 long thatcalls = that -> ncall + that -> selfcalls; 550 551 if ( thistime > thattime ) { 552 return GREATERTHAN; 553 } 554 if ( thistime < thattime ) { 555 return LESSTHAN; 556 } 557 if ( thiscalls > thatcalls ) { 558 return GREATERTHAN; 559 } 560 if ( thiscalls < thatcalls ) { 561 return LESSTHAN; 562 } 563 return EQUALTO; 564 } 565 /* 566 * compare two arcs to/from the same child/parent. 567 * - if one arc is a self arc, it's least. 568 * - if one arc is within a cycle, it's less than. 569 * - if both arcs are within a cycle, compare arc counts. 570 * - if neither arc is within a cycle, compare with 571 * arc_time + arc_childtime as major key 572 * arc count as minor key 573 */ 574 int 575 arccmp( thisp , thatp ) 576 arctype *thisp; 577 arctype *thatp; 578 { 579 nltype *thisparentp = thisp -> arc_parentp; 580 nltype *thischildp = thisp -> arc_childp; 581 nltype *thatparentp = thatp -> arc_parentp; 582 nltype *thatchildp = thatp -> arc_childp; 583 double thistime; 584 double thattime; 585 586 # ifdef DEBUG 587 if ( debug & TIMEDEBUG ) { 588 printf( "[arccmp] " ); 589 printname( thisparentp ); 590 printf( " calls " ); 591 printname ( thischildp ); 592 printf( " %f + %f %d/%d\n" , 593 thisp -> arc_time , thisp -> arc_childtime , 594 thisp -> arc_count , thischildp -> ncall ); 595 printf( "[arccmp] " ); 596 printname( thatparentp ); 597 printf( " calls " ); 598 printname( thatchildp ); 599 printf( " %f + %f %d/%d\n" , 600 thatp -> arc_time , thatp -> arc_childtime , 601 thatp -> arc_count , thatchildp -> ncall ); 602 printf( "\n" ); 603 } 604 # endif DEBUG 605 if ( thisparentp == thischildp ) { 606 /* this is a self call */ 607 return LESSTHAN; 608 } 609 if ( thatparentp == thatchildp ) { 610 /* that is a self call */ 611 return GREATERTHAN; 612 } 613 if ( thisparentp -> cycleno != 0 && thischildp -> cycleno != 0 && 614 thisparentp -> cycleno == thischildp -> cycleno ) { 615 /* this is a call within a cycle */ 616 if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 && 617 thatparentp -> cycleno == thatchildp -> cycleno ) { 618 /* that is a call within the cycle, too */ 619 if ( thisp -> arc_count < thatp -> arc_count ) { 620 return LESSTHAN; 621 } 622 if ( thisp -> arc_count > thatp -> arc_count ) { 623 return GREATERTHAN; 624 } 625 return EQUALTO; 626 } else { 627 /* that isn't a call within the cycle */ 628 return LESSTHAN; 629 } 630 } else { 631 /* this isn't a call within a cycle */ 632 if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 && 633 thatparentp -> cycleno == thatchildp -> cycleno ) { 634 /* that is a call within a cycle */ 635 return GREATERTHAN; 636 } else { 637 /* neither is a call within a cycle */ 638 thistime = thisp -> arc_time + thisp -> arc_childtime; 639 thattime = thatp -> arc_time + thatp -> arc_childtime; 640 if ( thistime < thattime ) 641 return LESSTHAN; 642 if ( thistime > thattime ) 643 return GREATERTHAN; 644 if ( thisp -> arc_count < thatp -> arc_count ) 645 return LESSTHAN; 646 if ( thisp -> arc_count > thatp -> arc_count ) 647 return GREATERTHAN; 648 return EQUALTO; 649 } 650 } 651 } 652 653 void 654 printblurb( blurbname ) 655 char *blurbname; 656 { 657 FILE *blurbfile; 658 int input; 659 660 blurbfile = fopen( blurbname , "r" ); 661 if ( blurbfile == NULL ) { 662 warn("fopen: %s", blurbname ); 663 return; 664 } 665 while ( ( input = getc( blurbfile ) ) != EOF ) 666 putchar( input ); 667 668 fclose( blurbfile ); 669 } 670 671 int 672 namecmp( npp1 , npp2 ) 673 nltype **npp1, **npp2; 674 { 675 return( strcmp( (*npp1) -> name , (*npp2) -> name ) ); 676 } 677 678 void 679 printindex() 680 { 681 nltype **namesortnlp; 682 register nltype *nlp; 683 int index, nnames, todo, i, j; 684 char peterbuffer[ BUFSIZ ]; 685 686 /* 687 * Now, sort regular function name alphbetically 688 * to create an index. 689 */ 690 namesortnlp = (nltype **) calloc( nname + ncycle , sizeof(nltype *) ); 691 if ( namesortnlp == (nltype **) 0 ) 692 warnx("ran out of memory for sorting"); 693 for ( index = 0 , nnames = 0 ; index < nname ; index++ ) { 694 if ( zflag == 0 && nl[index].ncall == 0 && nl[index].time == 0 ) 695 continue; 696 namesortnlp[nnames++] = &nl[index]; 697 } 698 qsort( namesortnlp , nnames , sizeof(nltype *) , namecmp ); 699 for ( index = 1 , todo = nnames ; index <= ncycle ; index++ ) { 700 namesortnlp[todo++] = &cyclenl[index]; 701 } 702 printf( "\f\nIndex by function name\n\n" ); 703 index = ( todo + 2 ) / 3; 704 for ( i = 0; i < index ; i++ ) { 705 for ( j = i; j < todo ; j += index ) { 706 nlp = namesortnlp[ j ]; 707 if ( nlp -> printflag ) { 708 sprintf( peterbuffer , "[%d]" , nlp -> index ); 709 } else { 710 sprintf( peterbuffer , "(%d)" , nlp -> index ); 711 } 712 if ( j < nnames ) { 713 printf( "%6.6s %-19.19s" , peterbuffer , nlp -> name ); 714 } else { 715 printf( "%6.6s " , peterbuffer ); 716 sprintf( peterbuffer , "<cycle %d>" , nlp -> cycleno ); 717 printf( "%-19.19s" , peterbuffer ); 718 } 719 } 720 printf( "\n" ); 721 } 722 free( namesortnlp ); 723 } 724