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