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