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