Annotation of src/usr.bin/gprof/printgprof.c, Revision 1.12
1.12 ! deraadt 1: /* $OpenBSD: printgprof.c,v 1.11 2006/03/25 19:06:36 espie Exp $ */
1.1 deraadt 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.
1.8 millert 16: * 3. Neither the name of the University nor the names of its contributors
1.1 deraadt 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: */
1.9 david 32:
33: #include <string.h>
1.1 deraadt 34:
35: #include "gprof.h"
36: #include "pathnames.h"
37:
1.11 espie 38: int namecmp(nltype **, nltype **);
39:
1.3 mickey 40: void
1.1 deraadt 41: printprof()
42: {
1.5 mpech 43: nltype *np;
1.1 deraadt 44: nltype **sortednlp;
1.3 mickey 45: int index;
1.1 deraadt 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 *) );
1.3 mickey 54: if ( sortednlp == (nltype **) 0 )
55: warnx("[printprof] ran out of memory for time sorting");
1.1 deraadt 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:
1.3 mickey 68: int
1.11 espie 69: timecmp(nltype **npp1, nltype **npp2)
1.1 deraadt 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: */
1.3 mickey 90: void
1.1 deraadt 91: flatprofheader()
92: {
93:
1.3 mickey 94: if (bflag)
1.1 deraadt 95: printblurb( _PATH_FLAT_BLURB );
1.3 mickey 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 {
1.1 deraadt 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: }
1.3 mickey 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" );
1.1 deraadt 112: }
113:
1.3 mickey 114: void
1.11 espie 115: flatprofline(nltype *np)
1.1 deraadt 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 ) {
1.3 mickey 125: printf( " %8ld %8.2f %8.2f " , np -> ncall ,
1.1 deraadt 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:
1.3 mickey 135: void
1.1 deraadt 136: gprofheader()
137: {
138:
139: if ( bflag ) {
140: printblurb( _PATH_CALLG_BLURB );
141: }
1.3 mickey 142: printf( "\ngranularity: each sample hit covers %ld byte(s)" ,
1.1 deraadt 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:
1.3 mickey 164: void
1.11 espie 165: gprofline(nltype *np)
1.1 deraadt 166: {
167: char kirkbuffer[ BUFSIZ ];
168:
1.7 deraadt 169: snprintf(kirkbuffer, sizeof kirkbuffer, "[%d]" , np -> index );
1.3 mickey 170: printf( "%-6.6s %5.1f %7.2f %11.2f" , kirkbuffer ,
1.1 deraadt 171: 100 * ( np -> propself + np -> propchild ) / printtime ,
1.3 mickey 172: np -> propself / hz , np -> propchild / hz );
1.1 deraadt 173: if ( ( np -> ncall + np -> selfcalls ) != 0 ) {
1.3 mickey 174: printf( " %7ld" , np -> npropcall );
1.1 deraadt 175: if ( np -> selfcalls != 0 ) {
1.3 mickey 176: printf( "+%-7ld " , np -> selfcalls );
1.1 deraadt 177: } else {
178: printf( " %7.7s " , "" );
179: }
180: } else {
181: printf( " %7.7s %7.7s " , "" , "" );
182: }
183: printname( np );
184: printf( "\n" );
185: }
186:
1.3 mickey 187: void
1.11 espie 188: printgprof(nltype **timesortnlp)
1.1 deraadt 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
1.11 espie 236: totalcmp(nltype **npp1, nltype **npp2)
1.1 deraadt 237: {
1.5 mpech 238: nltype *np1 = *npp1;
239: nltype *np2 = *npp2;
1.1 deraadt 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:
1.3 mickey 267: void
1.11 espie 268: printparents(nltype *childp)
1.1 deraadt 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: */
1.3 mickey 292: printf( "%6.6s %5.5s %7.7s %11.11s %7ld %7.7s " ,
1.1 deraadt 293: "" , "" , "" , "" ,
294: arcp -> arc_count , "" );
295: printname( parentp );
296: printf( "\n" );
297: } else {
298: /*
299: * regular parent of child
300: */
1.3 mickey 301: printf( "%6.6s %5.5s %7.2f %11.2f %7ld/%-7ld " ,
1.1 deraadt 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:
1.3 mickey 311: void
1.11 espie 312: printchildren(nltype *parentp)
1.1 deraadt 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: */
1.3 mickey 326: printf( "%6.6s %5.5s %7.7s %11.11s %7ld %7.7s " ,
1.1 deraadt 327: "" , "" , "" , "" , arcp -> arc_count , "" );
328: printname( childp );
329: printf( "\n" );
330: } else {
331: /*
332: * regular child of parent
333: */
1.3 mickey 334: printf( "%6.6s %5.5s %7.2f %11.2f %7ld/%-7ld " ,
1.1 deraadt 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:
1.3 mickey 344: void
1.11 espie 345: printname(nltype *selfp)
1.1 deraadt 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: }
1.6 danh 357: # endif /* DEBUG */
1.1 deraadt 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:
1.3 mickey 371: void
1.11 espie 372: sortchildren(nltype *parentp)
1.1 deraadt 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;
1.4 fgsch 388: for ((arcp = parentp -> children) && (detachedp = arcp -> arc_childlist);
1.1 deraadt 389: arcp ;
1.4 fgsch 390: (arcp = detachedp) && (detachedp = detachedp -> arc_childlist)) {
1.1 deraadt 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:
1.3 mickey 411: void
1.11 espie 412: sortparents(nltype *childp)
1.1 deraadt 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;
1.4 fgsch 428: for ((arcp = childp->parents) && (detachedp = arcp->arc_parentlist);
429: arcp; (arcp = detachedp) && (detachedp = detachedp->arc_parentlist)) {
1.1 deraadt 430: /*
431: * consider *arcp as disconnected
432: * insert it into sorted
433: */
1.3 mickey 434: for (prevp = &sorted; prevp->arc_parentlist;
435: prevp = prevp->arc_parentlist)
436: if (arccmp(arcp , prevp->arc_parentlist) != GREATERTHAN)
1.1 deraadt 437: break;
1.3 mickey 438: arcp->arc_parentlist = prevp->arc_parentlist;
439: prevp->arc_parentlist = arcp;
1.1 deraadt 440: }
441: /*
442: * reattach sorted arcs to child
443: */
444: childp -> parents = sorted.arc_parentlist;
445: }
446:
447: /*
448: * print a cycle header
449: */
1.3 mickey 450: void
1.11 espie 451: printcycle(nltype *cyclep)
1.1 deraadt 452: {
453: char kirkbuffer[ BUFSIZ ];
454:
1.7 deraadt 455: snprintf(kirkbuffer, sizeof kirkbuffer, "[%d]" , cyclep->index);
1.3 mickey 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 );
1.1 deraadt 465: }
466:
467: /*
468: * print the members of a cycle
469: */
1.3 mickey 470: void
1.11 espie 471: printmembers(nltype *cyclep)
1.1 deraadt 472: {
473: nltype *memberp;
474:
475: sortmembers( cyclep );
476: for ( memberp = cyclep -> cnext ; memberp ; memberp = memberp -> cnext ) {
1.3 mickey 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");
1.1 deraadt 486: }
487: }
488:
489: /*
490: * sort members of a cycle
491: */
1.3 mickey 492: void
1.11 espie 493: sortmembers(nltype *cyclep)
1.1 deraadt 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;
1.4 fgsch 505: for ((doing = todo) && (todo = doing -> cnext);
506: doing; (doing = todo) && (todo = doing -> cnext)) {
1.3 mickey 507: for (prev = cyclep; prev -> cnext; prev = prev -> cnext)
508: if (membercmp(doing, prev->cnext ) == GREATERTHAN)
1.1 deraadt 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
1.11 espie 520: membercmp(nltype *this , nltype *that)
1.1 deraadt 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
1.11 espie 551: arccmp(arctype *thisp, arctype *thatp)
1.1 deraadt 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 );
1.10 art 566: printf( " %f + %f %ld/%ld\n" ,
1.1 deraadt 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 );
1.10 art 573: printf( " %f + %f %ld/%ld\n" ,
1.1 deraadt 574: thatp -> arc_time , thatp -> arc_childtime ,
575: thatp -> arc_count , thatchildp -> ncall );
576: printf( "\n" );
577: }
1.6 danh 578: # endif /* DEBUG */
1.1 deraadt 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:
1.3 mickey 627: void
1.11 espie 628: printblurb(const char *blurbname)
1.1 deraadt 629: {
630: FILE *blurbfile;
631: int input;
632:
633: blurbfile = fopen( blurbname , "r" );
634: if ( blurbfile == NULL ) {
1.3 mickey 635: warn("fopen: %s", blurbname );
1.1 deraadt 636: return;
637: }
1.3 mickey 638: while ( ( input = getc( blurbfile ) ) != EOF )
1.1 deraadt 639: putchar( input );
1.3 mickey 640:
1.1 deraadt 641: fclose( blurbfile );
642: }
643:
644: int
1.11 espie 645: namecmp(nltype **npp1, nltype **npp2)
1.1 deraadt 646: {
647: return( strcmp( (*npp1) -> name , (*npp2) -> name ) );
648: }
649:
1.3 mickey 650: void
1.1 deraadt 651: printindex()
652: {
653: nltype **namesortnlp;
1.5 mpech 654: nltype *nlp;
1.1 deraadt 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 *) );
1.3 mickey 663: if ( namesortnlp == (nltype **) 0 )
664: warnx("ran out of memory for sorting");
1.1 deraadt 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 ) {
1.7 deraadt 680: snprintf(peterbuffer, sizeof peterbuffer, "[%d]" , nlp -> index );
1.1 deraadt 681: } else {
1.7 deraadt 682: snprintf(peterbuffer, sizeof peterbuffer, "(%d)" , nlp -> index );
1.1 deraadt 683: }
684: if ( j < nnames ) {
685: printf( "%6.6s %-19.19s" , peterbuffer , nlp -> name );
686: } else {
687: printf( "%6.6s " , peterbuffer );
1.7 deraadt 688: snprintf(peterbuffer, sizeof peterbuffer, "<cycle %d>"
689: , nlp -> cycleno );
1.1 deraadt 690: printf( "%-19.19s" , peterbuffer );
691: }
692: }
693: printf( "\n" );
694: }
695: free( namesortnlp );
696: }