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