xref: /csrg-svn/usr.bin/gprof/printgprof.c (revision 4854)
14515Speter #ifndef lint
2*4854Speter     static	char *sccsid = "@(#)printgprof.c	1.5 (Berkeley) 11/10/81";
34515Speter #endif lint
44515Speter 
54562Speter #include "gprof.h"
64515Speter 
74753Speter printprof()
84753Speter {
94753Speter     register nltype	*np;
104753Speter     nltype		**sortednlp;
114753Speter     int			index;
124753Speter 
13*4854Speter     printf( "\ngranularity: each sample hit covers %d byte(s)" , (long) scale );
14*4854Speter     printf( " for %.2f%% of %.2f seconds\n\n" , 100.0/totime , totime / HZ );
154753Speter     actime = 0.0;
164753Speter     flatprofheader();
174753Speter 	/*
184753Speter 	 *	Sort the symbol table in by time
194753Speter 	 */
204753Speter     sortednlp = (nltype **) calloc( nname , sizeof(nltype *) );
214753Speter     if ( sortednlp == (nltype **) 0 ) {
224753Speter 	fprintf( stderr , "[printprof] ran out of memory for time sorting\n" );
234753Speter     }
244753Speter     for ( index = 0 ; index < nname ; index += 1 ) {
254753Speter 	sortednlp[ index ] = &nl[ index ];
264753Speter     }
274753Speter     qsort( sortednlp , nname , sizeof(nltype *) , timecmp );
284753Speter     for ( index = 0 ; index < nname ; index += 1 ) {
294753Speter 	np = sortednlp[ index ];
304753Speter 	flatprofline( np );
314753Speter     }
324753Speter     actime = 0.0;
334753Speter }
344753Speter 
354753Speter timecmp( npp1 , npp2 )
364753Speter     nltype **npp1, **npp2;
374753Speter {
384753Speter     double d;
394753Speter 
404753Speter     d = (*npp2) -> time - (*npp1) -> time;
414753Speter     if ( d > 0.0 )
424753Speter 	return 1 ;
434753Speter     if ( d < 0.0 )
444753Speter 	return -1;
454753Speter     return( strcmp( (*npp1) -> name , (*npp2) -> name ) );
464753Speter }
474753Speter 
484753Speter     /*
494753Speter      *	header for flatprofline
504753Speter      */
514753Speter flatprofheader()
524753Speter {
534753Speter 
54*4854Speter     if ( bflag ) {
55*4854Speter 	printblurb( "flat.blurb" );
56*4854Speter     }
574753Speter     printf( "%5.5s %7.7s %7.7s %7.7s %-8.8s\n" ,
584753Speter 	    "%time" , "cumsecs" , "seconds" , "calls" , "name" );
594753Speter }
604753Speter 
614753Speter flatprofline( np )
624753Speter     register nltype	*np;
634753Speter {
644753Speter 
65*4854Speter     if ( zflag == 0 && np -> ncall == 0 && np -> time == 0 ) {
664753Speter 	return;
674753Speter     }
684753Speter     actime += np -> time;
694753Speter     printf( "%5.1f %7.2f %7.2f" ,
704753Speter 	100 * np -> time / totime , actime / HZ , np -> time / HZ );
714753Speter     if ( np -> ncall != 0 ) {
724753Speter 	printf( " %7d" , np -> ncall );
734753Speter     } else {
744753Speter 	printf( " %7.7s" , "" );
754753Speter     }
764753Speter     printf( " %s\n" , np -> name );
774753Speter }
784753Speter 
794753Speter gprofheader()
804753Speter {
81*4854Speter 
82*4854Speter     if ( bflag ) {
83*4854Speter 	printblurb( "callg.blurb" );
84*4854Speter     }
854753Speter     printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s     %-8.8s\n" ,
864753Speter 	"" , "" , "" , "" , "called" , "total" , "parents" , "" );
874753Speter     printf( "%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n" ,
884753Speter 	"index" , "%time" , "self" , "descendents" ,
894753Speter 	"called" , "self" , "name" , "index" );
904753Speter     printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s     %-8.8s\n" ,
914753Speter 	"" , "" , "" , "" , "called" , "total" , "children" , "" );
924753Speter     printf( "\n" );
934753Speter }
944753Speter 
954753Speter gprofline( np )
964753Speter     register nltype	*np;
974753Speter {
984753Speter     char	kirkbuffer[ BUFSIZ ];
994753Speter 
1004753Speter     sprintf( kirkbuffer , "[%d]" , np -> index );
1014753Speter     printf( "%-6.6s %5.1f %7.2f %11.2f" ,
1024753Speter 	    kirkbuffer ,
1034753Speter 	    100 * ( np -> time + np -> childtime ) / totime ,
1044753Speter 	    np -> time / HZ ,
1054753Speter 	    np -> childtime / HZ );
1064753Speter     if ( ( np -> ncall + np -> selfcalls ) != 0 ) {
1074753Speter 	printf( " %7d" , np -> ncall );
1084753Speter 	if ( np -> selfcalls != 0 ) {
1094753Speter 	    printf( "+%-7d " , np -> selfcalls );
1104753Speter 	} else {
1114753Speter 	    printf( " %7.7s " , "" );
1124753Speter 	}
1134753Speter     } else {
1144753Speter 	printf( " %7.7s %7.7s " , "" , "" );
1154753Speter     }
1164753Speter     printname( np );
1174753Speter     printf( "\n" );
1184753Speter }
1194753Speter 
1204562Speter printgprof()
1214515Speter {
1224515Speter     nltype	**timesortnlp;
1234515Speter     int		index;
1244515Speter     nltype	*parentp;
1254515Speter 
1264515Speter 	/*
1274515Speter 	 *	Now, sort by time + childtime.
1284515Speter 	 *	include the cycle headers hiding out past nl[nname].
1294753Speter 	 *	don't include the dummy hiding at nl[nname].
1304515Speter 	 */
1314753Speter     timesortnlp = (nltype **) calloc( nname + cyclemax , sizeof(nltype *) );
1324515Speter     if ( timesortnlp == (nltype **) 0 ) {
1334515Speter 	fprintf( stderr , "[doarcs] ran out of memory for sorting\n" );
1344515Speter     }
1354753Speter     for ( index = 0 ; index < nname ; index++ ) {
1364515Speter 	timesortnlp[index] = &nl[index];
1374515Speter     }
1384753Speter     for ( index = 1 ; index <= cyclemax ; index++ ) {
1394753Speter 	timesortnlp[(nname-1)+index] = &nl[nname+index];
1404753Speter     }
1414753Speter     qsort( timesortnlp , nname + cyclemax , sizeof(nltype *) , totalcmp );
1424753Speter     for ( index = 0 ; index < nname + cyclemax ; index++ ) {
1434515Speter 	timesortnlp[ index ] -> index = index + 1;
1444515Speter     }
1454515Speter 	/*
1464515Speter 	 *	Now, print out the structured profiling list
1474515Speter 	 */
1484753Speter     printf( "\f\n" );
1494753Speter     gprofheader();
1504753Speter     for ( index = 0 ; index < nname + cyclemax ; index ++ ) {
1514515Speter 	parentp = timesortnlp[ index ];
152*4854Speter 	if ( zflag == 0 &&
1534515Speter 	     parentp -> ncall == 0 &&
1544515Speter 	     parentp -> selfcalls == 0 &&
1554515Speter 	     parentp -> time == 0 &&
1564515Speter 	     parentp -> childtime == 0 ) {
1574515Speter 	    continue;
1584515Speter 	}
1594515Speter 	if ( parentp -> name == 0 && parentp -> cycleno != 0 ) {
1604515Speter 		/*
1614515Speter 		 *	cycle header
1624515Speter 		 */
1634753Speter 	    printcycle( parentp );
1644753Speter 	    printmembers( parentp );
1654515Speter 	} else {
1664515Speter 	    printparents( parentp );
1674753Speter 	    gprofline( parentp );
1684515Speter 	    printchildren( parentp );
1694515Speter 	}
1704515Speter 	printf( "\n" );
1714753Speter 	printf( "-----------------------------------------------\n" );
1724753Speter 	printf( "\n" );
1734515Speter     }
1744515Speter }
1754515Speter 
1764515Speter printparents( childp )
1774515Speter     nltype	*childp;
1784515Speter {
1794515Speter     nltype	*parentp;
1804515Speter     arctype	*arcp;
1814515Speter     nltype	*cycleheadp;
1824515Speter 
1834515Speter     if ( childp -> cyclehead != 0 ) {
1844515Speter 	cycleheadp = childp -> cyclehead;
1854515Speter     } else {
1864515Speter 	cycleheadp = childp;
1874515Speter     }
1884515Speter     if ( childp -> parents == 0 ) {
1894753Speter 	printf( "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s     <spontaneous>\n" ,
1904515Speter 		"" , "" , "" , "" , "" , "" );
1914515Speter 	return;
1924515Speter     }
1934515Speter     sortparents( childp );
1944515Speter     for ( arcp = childp -> parents ; arcp ; arcp = arcp -> arc_parentlist ) {
1954515Speter 	parentp = arcp -> arc_parentp;
1964515Speter 	if ( childp == parentp ||
1974515Speter 	     ( childp->cycleno != 0 && parentp->cycleno == childp->cycleno ) ) {
1984515Speter 		/*
1994753Speter 		 *	selfcall or call among siblings
2004515Speter 		 */
2014753Speter 	    printf( "%6.6s %5.5s %7.7s %11.11s %7d %7.7s     " ,
2024515Speter 		    "" , "" , "" , "" ,
2034515Speter 		    arcp -> arc_count , "" );
2044515Speter 	    printname( parentp );
2054515Speter 	    printf( "\n" );
2064515Speter 	} else {
2074515Speter 		/*
2084515Speter 		 *	regular parent of child
2094515Speter 		 */
2104753Speter 	    printf( "%6.6s %5.5s %7.2f %11.2f %7d/%-7d     " ,
2114753Speter 		    "" , "" ,
2124515Speter 		    arcp -> arc_time / HZ , arcp -> arc_childtime / HZ ,
2134515Speter 		    arcp -> arc_count , cycleheadp -> ncall );
2144515Speter 	    printname( parentp );
2154515Speter 	    printf( "\n" );
2164515Speter 	}
2174515Speter     }
2184515Speter }
2194515Speter 
2204515Speter printchildren( parentp )
2214515Speter     nltype	*parentp;
2224515Speter {
2234515Speter     nltype	*childp;
2244515Speter     arctype	*arcp;
2254515Speter 
2264515Speter     sortchildren( parentp );
2274515Speter     arcp = parentp -> children;
2284515Speter     for ( arcp = parentp -> children ; arcp ; arcp = arcp -> arc_childlist ) {
2294515Speter 	childp = arcp -> arc_childp;
2304515Speter 	if ( childp == parentp ||
2314515Speter 	    ( childp->cycleno != 0 && childp->cycleno == parentp->cycleno ) ) {
2324515Speter 		/*
2334515Speter 		 *	self call or call to sibling
2344515Speter 		 */
2354753Speter 	    printf( "%6.6s %5.5s %7.7s %11.11s %7d %7.7s     " ,
2364753Speter 		    "" , "" , "" , "" , arcp -> arc_count , "" );
2374515Speter 	    printname( childp );
2384515Speter 	    printf( "\n" );
2394515Speter 	} else {
2404515Speter 		/*
2414515Speter 		 *	regular child of parent
2424515Speter 		 */
2434753Speter 	    printf( "%6.6s %5.5s %7.2f %11.2f %7d/%-7d     " ,
2444753Speter 		    "" , "" ,
2454515Speter 		    arcp -> arc_time / HZ , arcp -> arc_childtime / HZ ,
2464515Speter 		    arcp -> arc_count , childp -> cyclehead -> ncall );
2474515Speter 	    printname( childp );
2484515Speter 	    printf( "\n" );
2494515Speter 	}
2504515Speter     }
2514515Speter }
2524515Speter 
2534515Speter printname( selfp )
2544515Speter     nltype	*selfp;
2554515Speter {
2564515Speter 
2574515Speter     if ( selfp -> name != 0 ) {
2584753Speter 	printf( "%s" , selfp -> name );
2594515Speter #	ifdef DEBUG
2604515Speter 	    if ( debug & DFNDEBUG ) {
2614515Speter 		printf( "{%d} " , selfp -> toporder );
2624515Speter 	    }
2634515Speter #	endif DEBUG
2644515Speter     }
2654842Speter     if ( selfp -> cycleno != 0 ) {
2664842Speter 	printf( "\t<cycle %d>" , selfp -> cycleno );
2674842Speter     }
2684753Speter     if ( selfp -> index != 0 ) {
2694842Speter 	printf( " [%d]" , selfp -> index );
2704753Speter     }
2714515Speter }
2724515Speter 
2734515Speter sortchildren( parentp )
2744515Speter     nltype	*parentp;
2754515Speter {
2764515Speter     arctype	*arcp;
2774515Speter     arctype	*detachedp;
2784515Speter     arctype	sorted;
2794515Speter     arctype	*prevp;
2804515Speter 
2814515Speter 	/*
2824515Speter 	 *	unlink children from parent,
2834515Speter 	 *	then insertion sort back on to sorted's children.
2844515Speter 	 *	    *arcp	the arc you have detached and are inserting.
2854515Speter 	 *	    *detachedp	the rest of the arcs to be sorted.
2864515Speter 	 *	    sorted	arc list onto which you insertion sort.
2874515Speter 	 *	    *prevp	arc before the arc you are comparing.
2884515Speter 	 */
2894515Speter     sorted.arc_childlist = 0;
2904515Speter     for (   arcp = parentp -> children , detachedp = arcp -> arc_childlist ;
2914515Speter 	    arcp ;
2924515Speter 	    arcp = detachedp , detachedp = detachedp -> arc_childlist ) {
2934515Speter 	    /*
2944515Speter 	     *	consider *arcp as disconnected
2954515Speter 	     *	insert it into sorted
2964515Speter 	     */
2974515Speter 	for (   prevp = &sorted ;
2984515Speter 		prevp -> arc_childlist ;
2994515Speter 		prevp = prevp -> arc_childlist ) {
3004515Speter 	    if ( arccmp( arcp , prevp -> arc_childlist ) != LESSTHAN ) {
3014515Speter 		break;
3024515Speter 	    }
3034515Speter 	}
3044515Speter 	arcp -> arc_childlist = prevp -> arc_childlist;
3054515Speter 	prevp -> arc_childlist = arcp;
3064515Speter     }
3074515Speter 	/*
3084515Speter 	 *	reattach sorted children to parent
3094515Speter 	 */
3104515Speter     parentp -> children = sorted.arc_childlist;
3114515Speter }
3124515Speter 
3134515Speter sortparents( childp )
3144515Speter     nltype	*childp;
3154515Speter {
3164515Speter     arctype	*arcp;
3174515Speter     arctype	*detachedp;
3184515Speter     arctype	sorted;
3194515Speter     arctype	*prevp;
3204515Speter 
3214515Speter 	/*
3224515Speter 	 *	unlink parents from child,
3234515Speter 	 *	then insertion sort back on to sorted's parents.
3244515Speter 	 *	    *arcp	the arc you have detached and are inserting.
3254515Speter 	 *	    *detachedp	the rest of the arcs to be sorted.
3264515Speter 	 *	    sorted	arc list onto which you insertion sort.
3274515Speter 	 *	    *prevp	arc before the arc you are comparing.
3284515Speter 	 */
3294515Speter     sorted.arc_parentlist = 0;
3304515Speter     for (   arcp = childp -> parents , detachedp = arcp -> arc_parentlist ;
3314515Speter 	    arcp ;
3324515Speter 	    arcp = detachedp , detachedp = detachedp -> arc_parentlist ) {
3334515Speter 	    /*
3344515Speter 	     *	consider *arcp as disconnected
3354515Speter 	     *	insert it into sorted
3364515Speter 	     */
3374515Speter 	for (   prevp = &sorted ;
3384515Speter 		prevp -> arc_parentlist ;
3394515Speter 		prevp = prevp -> arc_parentlist ) {
3404515Speter 	    if ( arccmp( arcp , prevp -> arc_parentlist ) != GREATERTHAN ) {
3414515Speter 		break;
3424515Speter 	    }
3434515Speter 	}
3444515Speter 	arcp -> arc_parentlist = prevp -> arc_parentlist;
3454515Speter 	prevp -> arc_parentlist = arcp;
3464515Speter     }
3474515Speter 	/*
3484515Speter 	 *	reattach sorted arcs to child
3494515Speter 	 */
3504515Speter     childp -> parents = sorted.arc_parentlist;
3514515Speter }
3524515Speter 
3534515Speter     /*
3544753Speter      *	print a cycle header
3554753Speter      */
3564753Speter printcycle( cyclep )
3574753Speter     nltype	*cyclep;
3584753Speter {
3594753Speter     char	kirkbuffer[ BUFSIZ ];
3604753Speter 
3614753Speter     sprintf( kirkbuffer , "[%d]" , cyclep -> index );
3624753Speter     printf( "%-6.6s %5.1f %7.2f %11.2f %7d" ,
3634753Speter 	    kirkbuffer ,
3644753Speter 	    100 * ( cyclep -> time + cyclep -> childtime ) / totime ,
3654753Speter 	    cyclep -> time / HZ ,
3664753Speter 	    cyclep -> childtime / HZ ,
3674753Speter 	    cyclep -> ncall );
3684753Speter     if ( cyclep -> selfcalls != 0 ) {
3694753Speter 	printf( "+%-7d" , cyclep -> selfcalls );
3704753Speter     } else {
3714753Speter 	printf( " %7.7s" , "" );
3724753Speter     }
3734753Speter     printf( " <cycle %d as a whole>\t[%d]\n" ,
3744753Speter 	    cyclep -> cycleno , cyclep -> index );
3754753Speter }
3764753Speter 
3774753Speter     /*
3784753Speter      *	print the members of a cycle
3794753Speter      */
3804753Speter printmembers( cyclep )
3814753Speter     nltype	*cyclep;
3824753Speter {
3834753Speter     nltype	*memberp;
3844753Speter 
3854753Speter     sortmembers( cyclep );
3864753Speter     for ( memberp = cyclep -> cnext ; memberp ; memberp = memberp -> cnext ) {
3874753Speter 	printf( "%6.6s %5.5s %7.2f %11.2f %7d" ,
3884753Speter 		"" , "" , memberp -> time / HZ , memberp -> childtime / HZ ,
3894753Speter 		memberp -> ncall );
3904753Speter 	if ( memberp -> selfcalls != 0 ) {
3914753Speter 	    printf( "+%-7d" , memberp -> selfcalls );
3924753Speter 	} else {
3934753Speter 	    printf( " %7.7s" , "" );
3944753Speter 	}
3954753Speter 	printf( "     " );
3964753Speter 	printname( memberp );
3974753Speter 	printf( "\n" );
3984753Speter     }
3994753Speter }
4004753Speter 
4014753Speter     /*
4024753Speter      *	sort members of a cycle
4034753Speter      */
4044753Speter sortmembers( cyclep )
4054753Speter     nltype	*cyclep;
4064753Speter {
4074753Speter     nltype	*todo;
4084753Speter     nltype	*doing;
4094753Speter     nltype	*prev;
4104753Speter 
4114753Speter 	/*
4124753Speter 	 *	detach cycle members from cyclehead,
4134753Speter 	 *	and insertion sort them back on.
4144753Speter 	 */
4154753Speter     todo = cyclep -> cnext;
4164753Speter     cyclep -> cnext = 0;
4174753Speter     for (   doing = todo , todo = doing -> cnext ;
4184753Speter 	    doing ;
4194753Speter 	    doing = todo , todo = doing -> cnext ) {
4204753Speter 	for ( prev = cyclep ; prev -> cnext ; prev = prev -> cnext ) {
4214753Speter 	    if ( membercmp( doing , prev -> cnext ) == GREATERTHAN ) {
4224753Speter 		break;
4234753Speter 	    }
4244753Speter 	}
4254753Speter 	doing -> cnext = prev -> cnext;
4264753Speter 	prev -> cnext = doing;
4274753Speter     }
4284753Speter }
4294753Speter 
4304753Speter     /*
4314753Speter      *	major sort is on time + childtime,
4324753Speter      *	next is sort on ncalls + selfcalls.
4334753Speter      */
4344842Speter int
4354753Speter membercmp( this , that )
4364753Speter     nltype	*this;
4374753Speter     nltype	*that;
4384753Speter {
4394753Speter     double	thistime = this -> time + this -> childtime;
4404753Speter     double	thattime = that -> time + that -> childtime;
4414753Speter     long	thiscalls = this -> ncall + this -> selfcalls;
4424753Speter     long	thatcalls = that -> ncall + that -> selfcalls;
4434753Speter 
4444753Speter     if ( thistime > thattime ) {
4454753Speter 	return GREATERTHAN;
4464753Speter     }
4474753Speter     if ( thistime < thattime ) {
4484753Speter 	return LESSTHAN;
4494753Speter     }
4504753Speter     if ( thiscalls > thatcalls ) {
4514753Speter 	return GREATERTHAN;
4524753Speter     }
4534753Speter     if ( thiscalls < thatcalls ) {
4544753Speter 	return LESSTHAN;
4554753Speter     }
4564753Speter     return EQUALTO;
4574753Speter }
4584753Speter     /*
4594515Speter      *	compare two arcs to/from the same child/parent.
4604515Speter      *	- if one arc is a self arc, it's least.
4614515Speter      *	- if one arc is within a cycle, it's less than.
4624515Speter      *	- if both arcs are within a cycle, compare arc counts.
4634515Speter      *	- if neither arc is within a cycle, compare with
4644515Speter      *		time + childtime as major key
4654515Speter      *		arc count as minor key
4664515Speter      */
4674515Speter int
4684515Speter arccmp( thisp , thatp )
4694515Speter     arctype	*thisp;
4704515Speter     arctype	*thatp;
4714515Speter {
4724515Speter     nltype	*thisparentp = thisp -> arc_parentp;
4734515Speter     nltype	*thischildp = thisp -> arc_childp;
4744515Speter     nltype	*thatparentp = thatp -> arc_parentp;
4754515Speter     nltype	*thatchildp = thatp -> arc_childp;
4764515Speter     double	thistime;
4774515Speter     double	thattime;
4784515Speter 
4794515Speter #   ifdef DEBUG
4804515Speter 	if ( debug & TIMEDEBUG ) {
4814515Speter 	    printf( "[arccmp] " );
4824515Speter 	    printname( thisparentp );
4834515Speter 	    printf( " calls " );
4844515Speter 	    printname ( thischildp );
4854515Speter 	    printf( " %f + %f %d/%d\n" ,
4864515Speter 		    thisp -> arc_time , thisp -> arc_childtime ,
4874515Speter 		    thisp -> arc_count , thischildp -> ncall );
4884515Speter 	    printf( "[arccmp] " );
4894515Speter 	    printname( thatparentp );
4904515Speter 	    printf( " calls " );
4914515Speter 	    printname( thatchildp );
4924515Speter 	    printf( " %f + %f %d/%d\n" ,
4934515Speter 		    thatp -> arc_time , thatp -> arc_childtime ,
4944515Speter 		    thatp -> arc_count , thatchildp -> ncall );
4954515Speter 	    printf( "\n" );
4964515Speter 	}
4974515Speter #   endif DEBUG
4984515Speter     if ( thisparentp == thischildp ) {
4994515Speter 	    /* this is a self call */
5004515Speter 	return LESSTHAN;
5014515Speter     }
5024515Speter     if ( thatparentp == thatchildp ) {
5034515Speter 	    /* that is a self call */
5044515Speter 	return GREATERTHAN;
5054515Speter     }
5064515Speter     if ( thisparentp -> cycleno != 0 && thischildp -> cycleno != 0 &&
5074515Speter 	thisparentp -> cycleno == thischildp -> cycleno ) {
5084515Speter 	    /* this is a call within a cycle */
5094515Speter 	if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 &&
5104515Speter 	    thatparentp -> cycleno == thatchildp -> cycleno ) {
5114515Speter 		/* that is a call within the cycle, too */
5124515Speter 	    if ( thisp -> arc_count < thatp -> arc_count ) {
5134515Speter 		return LESSTHAN;
5144515Speter 	    }
5154515Speter 	    if ( thisp -> arc_count > thatp -> arc_count ) {
5164515Speter 		return GREATERTHAN;
5174515Speter 	    }
5184515Speter 	    return EQUALTO;
5194515Speter 	} else {
5204515Speter 		/* that isn't a call within the cycle */
5214515Speter 	    return LESSTHAN;
5224515Speter 	}
5234515Speter     } else {
5244515Speter 	    /* this isn't a call within a cycle */
5254515Speter 	if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 &&
5264515Speter 	    thatparentp -> cycleno == thatchildp -> cycleno ) {
5274515Speter 		/* that is a call within a cycle */
5284515Speter 	    return GREATERTHAN;
5294515Speter 	} else {
5304515Speter 		/* neither is a call within a cycle */
5314515Speter 	    thistime = thisp -> arc_time + thisp -> arc_childtime;
5324515Speter 	    thattime = thatp -> arc_time + thatp -> arc_childtime;
5334515Speter 	    if ( thistime < thattime )
5344515Speter 		return LESSTHAN;
5354515Speter 	    if ( thistime > thattime )
5364515Speter 		return GREATERTHAN;
5374515Speter 	    if ( thisp -> arc_count < thatp -> arc_count )
5384515Speter 		return LESSTHAN;
5394515Speter 	    if ( thisp -> arc_count > thatp -> arc_count )
5404515Speter 		return GREATERTHAN;
5414515Speter 	    return EQUALTO;
5424515Speter 	}
5434515Speter     }
5444515Speter }
545*4854Speter 
546*4854Speter printblurb( blurbname )
547*4854Speter     char	*blurbname;
548*4854Speter {
549*4854Speter     char	pathname[ BUFSIZ ];
550*4854Speter     FILE	*blurbfile;
551*4854Speter     int		input;
552*4854Speter 
553*4854Speter #   ifndef BLURBLIB
554*4854Speter #	define BLURBLIB	"./"
555*4854Speter #   endif not BLURBLIB
556*4854Speter     sprintf( pathname , "%s%s" , BLURBLIB , blurbname );
557*4854Speter     blurbfile = fopen( pathname , "r" );
558*4854Speter     if ( blurbfile == NULL ) {
559*4854Speter 	perror( pathname );
560*4854Speter 	return;
561*4854Speter     }
562*4854Speter     while ( ( input = getc( blurbfile ) ) != EOF ) {
563*4854Speter 	putchar( input );
564*4854Speter     }
565*4854Speter     fclose( blurbfile );
566*4854Speter }
567