xref: /csrg-svn/usr.bin/gprof/printgprof.c (revision 7172)
14515Speter #ifndef lint
2*7172Speter     static	char *sccsid = "@(#)printgprof.c	1.9 (Berkeley) 06/14/82";
34515Speter #endif lint
44515Speter 
54562Speter #include "gprof.h"
64515Speter 
74753Speter printprof()
84753Speter {
94753Speter     register nltype	*np;
104753Speter     nltype		**sortednlp;
114753Speter     int			index;
124753Speter 
13*7172Speter     printf( "\ngranularity: each sample hit covers %d byte(s)" ,
14*7172Speter 	    (long) scale * sizeof(UNIT) );
154854Speter     printf( " for %.2f%% of %.2f seconds\n\n" , 100.0/totime , totime / HZ );
164753Speter     actime = 0.0;
174753Speter     flatprofheader();
184753Speter 	/*
194753Speter 	 *	Sort the symbol table in by time
204753Speter 	 */
214753Speter     sortednlp = (nltype **) calloc( nname , sizeof(nltype *) );
224753Speter     if ( sortednlp == (nltype **) 0 ) {
234753Speter 	fprintf( stderr , "[printprof] ran out of memory for time sorting\n" );
244753Speter     }
254753Speter     for ( index = 0 ; index < nname ; index += 1 ) {
264753Speter 	sortednlp[ index ] = &nl[ index ];
274753Speter     }
284753Speter     qsort( sortednlp , nname , sizeof(nltype *) , timecmp );
294753Speter     for ( index = 0 ; index < nname ; index += 1 ) {
304753Speter 	np = sortednlp[ index ];
314753Speter 	flatprofline( np );
324753Speter     }
334753Speter     actime = 0.0;
344753Speter }
354753Speter 
364753Speter timecmp( npp1 , npp2 )
374753Speter     nltype **npp1, **npp2;
384753Speter {
394856Speter     double	timediff;
404856Speter     long	calldiff;
414753Speter 
424856Speter     timediff = (*npp2) -> time - (*npp1) -> time;
434856Speter     if ( timediff > 0.0 )
444753Speter 	return 1 ;
454856Speter     if ( timediff < 0.0 )
464753Speter 	return -1;
474856Speter     calldiff = (*npp2) -> ncall - (*npp1) -> ncall;
484856Speter     if ( calldiff > 0 )
494856Speter 	return 1;
504856Speter     if ( calldiff < 0 )
514856Speter 	return -1;
524753Speter     return( strcmp( (*npp1) -> name , (*npp2) -> name ) );
534753Speter }
544753Speter 
554753Speter     /*
564753Speter      *	header for flatprofline
574753Speter      */
584753Speter flatprofheader()
594753Speter {
604753Speter 
614854Speter     if ( bflag ) {
624854Speter 	printblurb( "flat.blurb" );
634854Speter     }
644753Speter     printf( "%5.5s %7.7s %7.7s %7.7s %-8.8s\n" ,
654753Speter 	    "%time" , "cumsecs" , "seconds" , "calls" , "name" );
664753Speter }
674753Speter 
684753Speter flatprofline( np )
694753Speter     register nltype	*np;
704753Speter {
714753Speter 
724854Speter     if ( zflag == 0 && np -> ncall == 0 && np -> time == 0 ) {
734753Speter 	return;
744753Speter     }
754753Speter     actime += np -> time;
764753Speter     printf( "%5.1f %7.2f %7.2f" ,
774753Speter 	100 * np -> time / totime , actime / HZ , np -> time / HZ );
784753Speter     if ( np -> ncall != 0 ) {
794753Speter 	printf( " %7d" , np -> ncall );
804753Speter     } else {
814753Speter 	printf( " %7.7s" , "" );
824753Speter     }
834753Speter     printf( " %s\n" , np -> name );
844753Speter }
854753Speter 
864753Speter gprofheader()
874753Speter {
884854Speter 
894854Speter     if ( bflag ) {
904854Speter 	printblurb( "callg.blurb" );
914854Speter     }
92*7172Speter     printf( "\ngranularity: each sample hit covers %d byte(s)" ,
93*7172Speter 	    (long) scale * sizeof(UNIT) );
94*7172Speter     printf( " for %.2f%% of %.2f seconds\n\n" ,
95*7172Speter 	    100.0/printtime , printtime / HZ );
964753Speter     printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s     %-8.8s\n" ,
974753Speter 	"" , "" , "" , "" , "called" , "total" , "parents" , "" );
984753Speter     printf( "%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n" ,
994753Speter 	"index" , "%time" , "self" , "descendents" ,
1004753Speter 	"called" , "self" , "name" , "index" );
1014753Speter     printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s     %-8.8s\n" ,
1024753Speter 	"" , "" , "" , "" , "called" , "total" , "children" , "" );
1034753Speter     printf( "\n" );
1044753Speter }
1054753Speter 
1064753Speter gprofline( np )
1074753Speter     register nltype	*np;
1084753Speter {
1094753Speter     char	kirkbuffer[ BUFSIZ ];
1104753Speter 
1114753Speter     sprintf( kirkbuffer , "[%d]" , np -> index );
1124753Speter     printf( "%-6.6s %5.1f %7.2f %11.2f" ,
1134753Speter 	    kirkbuffer ,
114*7172Speter 	    100 * ( np -> time + np -> childtime ) / printtime ,
1154753Speter 	    np -> time / HZ ,
1164753Speter 	    np -> childtime / HZ );
1174753Speter     if ( ( np -> ncall + np -> selfcalls ) != 0 ) {
1184753Speter 	printf( " %7d" , np -> ncall );
1194753Speter 	if ( np -> selfcalls != 0 ) {
1204753Speter 	    printf( "+%-7d " , np -> selfcalls );
1214753Speter 	} else {
1224753Speter 	    printf( " %7.7s " , "" );
1234753Speter 	}
1244753Speter     } else {
1254753Speter 	printf( " %7.7s %7.7s " , "" , "" );
1264753Speter     }
1274753Speter     printname( np );
1284753Speter     printf( "\n" );
1294753Speter }
1304753Speter 
1314562Speter printgprof()
1324515Speter {
1334515Speter     nltype	**timesortnlp;
1344515Speter     int		index;
1354515Speter     nltype	*parentp;
1364515Speter 
1374515Speter 	/*
1384515Speter 	 *	Now, sort by time + childtime.
1397129Speter 	 *	sorting both the regular function names
1407129Speter 	 *	and cycle headers.
1414515Speter 	 */
1427129Speter     timesortnlp = (nltype **) calloc( nname + ncycle , sizeof(nltype *) );
1434515Speter     if ( timesortnlp == (nltype **) 0 ) {
1447129Speter 	fprintf( stderr , "%s: ran out of memory for sorting\n" , whoami );
1454515Speter     }
1464753Speter     for ( index = 0 ; index < nname ; index++ ) {
1474515Speter 	timesortnlp[index] = &nl[index];
1484515Speter     }
1497129Speter     for ( index = 1 ; index <= ncycle ; index++ ) {
1507129Speter 	timesortnlp[nname+index-1] = &cyclenl[index];
1514753Speter     }
1527129Speter     qsort( timesortnlp , nname + ncycle , sizeof(nltype *) , totalcmp );
1537129Speter     for ( index = 0 ; index < nname + ncycle ; index++ ) {
1544515Speter 	timesortnlp[ index ] -> index = index + 1;
1554515Speter     }
1564515Speter 	/*
1574515Speter 	 *	Now, print out the structured profiling list
1584515Speter 	 */
1594753Speter     printf( "\f\n" );
1604753Speter     gprofheader();
1617129Speter     for ( index = 0 ; index < nname + ncycle ; index ++ ) {
1624515Speter 	parentp = timesortnlp[ index ];
1634854Speter 	if ( zflag == 0 &&
1644515Speter 	     parentp -> ncall == 0 &&
1654515Speter 	     parentp -> selfcalls == 0 &&
1664515Speter 	     parentp -> time == 0 &&
1674515Speter 	     parentp -> childtime == 0 ) {
1684515Speter 	    continue;
1694515Speter 	}
170*7172Speter 	if ( ! parentp -> printflag ) {
171*7172Speter 	    continue;
172*7172Speter 	}
1734515Speter 	if ( parentp -> name == 0 && parentp -> cycleno != 0 ) {
1744515Speter 		/*
1754515Speter 		 *	cycle header
1764515Speter 		 */
1774753Speter 	    printcycle( parentp );
1784753Speter 	    printmembers( parentp );
1794515Speter 	} else {
1804515Speter 	    printparents( parentp );
1814753Speter 	    gprofline( parentp );
1824515Speter 	    printchildren( parentp );
1834515Speter 	}
1844515Speter 	printf( "\n" );
1854753Speter 	printf( "-----------------------------------------------\n" );
1864753Speter 	printf( "\n" );
1874515Speter     }
1884515Speter }
1894515Speter 
1904856Speter     /*
1914856Speter      *	sort by decreasing total time (time+childtime)
1924856Speter      *	if times are equal, but one is a cycle header,
1934856Speter      *		say that's first (e.g. less, i.e. -1).
1944856Speter      *	if one's name doesn't have an underscore and the other does,
1954856Speter      *		say the one is first.
1964856Speter      *	all else being equal, sort by names.
1974856Speter      */
1984856Speter int
1994856Speter totalcmp( npp1 , npp2 )
2004856Speter     nltype	**npp1;
2014856Speter     nltype	**npp2;
2024856Speter {
2034856Speter     register nltype	*np1 = *npp1;
2044856Speter     register nltype	*np2 = *npp2;
2054856Speter     double		diff;
2064856Speter 
2074856Speter     diff =    ( np1 -> time + np1 -> childtime )
2084856Speter 	    - ( np2 -> time + np2 -> childtime );
2094856Speter     if ( diff < 0.0 )
2104856Speter 	    return 1;
2114856Speter     if ( diff > 0.0 )
2124856Speter 	    return -1;
2134856Speter     if ( np1 -> name == 0 && np1 -> cycleno != 0 )
2144856Speter 	return -1;
2154856Speter     if ( np2 -> name == 0 && np2 -> cycleno != 0 )
2164856Speter 	return 1;
2174856Speter     if ( np1 -> name == 0 )
2184856Speter 	return -1;
2194856Speter     if ( np2 -> name == 0 )
2204856Speter 	return 1;
2214856Speter     if ( *(np1 -> name) != '_' && *(np2 -> name) == '_' )
2224856Speter 	return -1;
2234856Speter     if ( *(np1 -> name) == '_' && *(np2 -> name) != '_' )
2244856Speter 	return 1;
2254856Speter     return strcmp( np1 -> name , np2 -> name );
2264856Speter }
2274856Speter 
2284515Speter printparents( childp )
2294515Speter     nltype	*childp;
2304515Speter {
2314515Speter     nltype	*parentp;
2324515Speter     arctype	*arcp;
2334515Speter     nltype	*cycleheadp;
2344515Speter 
2354515Speter     if ( childp -> cyclehead != 0 ) {
2364515Speter 	cycleheadp = childp -> cyclehead;
2374515Speter     } else {
2384515Speter 	cycleheadp = childp;
2394515Speter     }
2404515Speter     if ( childp -> parents == 0 ) {
2414753Speter 	printf( "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s     <spontaneous>\n" ,
2424515Speter 		"" , "" , "" , "" , "" , "" );
2434515Speter 	return;
2444515Speter     }
2454515Speter     sortparents( childp );
2464515Speter     for ( arcp = childp -> parents ; arcp ; arcp = arcp -> arc_parentlist ) {
2474515Speter 	parentp = arcp -> arc_parentp;
2484515Speter 	if ( childp == parentp ||
2494515Speter 	     ( childp->cycleno != 0 && parentp->cycleno == childp->cycleno ) ) {
2504515Speter 		/*
2514753Speter 		 *	selfcall or call among siblings
2524515Speter 		 */
2534753Speter 	    printf( "%6.6s %5.5s %7.7s %11.11s %7d %7.7s     " ,
2544515Speter 		    "" , "" , "" , "" ,
2554515Speter 		    arcp -> arc_count , "" );
2564515Speter 	    printname( parentp );
2574515Speter 	    printf( "\n" );
2584515Speter 	} else {
2594515Speter 		/*
2604515Speter 		 *	regular parent of child
2614515Speter 		 */
2624753Speter 	    printf( "%6.6s %5.5s %7.2f %11.2f %7d/%-7d     " ,
2634753Speter 		    "" , "" ,
2644515Speter 		    arcp -> arc_time / HZ , arcp -> arc_childtime / HZ ,
2654515Speter 		    arcp -> arc_count , cycleheadp -> ncall );
2664515Speter 	    printname( parentp );
2674515Speter 	    printf( "\n" );
2684515Speter 	}
2694515Speter     }
2704515Speter }
2714515Speter 
2724515Speter printchildren( parentp )
2734515Speter     nltype	*parentp;
2744515Speter {
2754515Speter     nltype	*childp;
2764515Speter     arctype	*arcp;
2774515Speter 
2784515Speter     sortchildren( parentp );
2794515Speter     arcp = parentp -> children;
2804515Speter     for ( arcp = parentp -> children ; arcp ; arcp = arcp -> arc_childlist ) {
2814515Speter 	childp = arcp -> arc_childp;
2824515Speter 	if ( childp == parentp ||
2834515Speter 	    ( childp->cycleno != 0 && childp->cycleno == parentp->cycleno ) ) {
2844515Speter 		/*
2854515Speter 		 *	self call or call to sibling
2864515Speter 		 */
2874753Speter 	    printf( "%6.6s %5.5s %7.7s %11.11s %7d %7.7s     " ,
2884753Speter 		    "" , "" , "" , "" , arcp -> arc_count , "" );
2894515Speter 	    printname( childp );
2904515Speter 	    printf( "\n" );
2914515Speter 	} else {
2924515Speter 		/*
2934515Speter 		 *	regular child of parent
2944515Speter 		 */
2954753Speter 	    printf( "%6.6s %5.5s %7.2f %11.2f %7d/%-7d     " ,
2964753Speter 		    "" , "" ,
2974515Speter 		    arcp -> arc_time / HZ , arcp -> arc_childtime / HZ ,
2984515Speter 		    arcp -> arc_count , childp -> cyclehead -> ncall );
2994515Speter 	    printname( childp );
3004515Speter 	    printf( "\n" );
3014515Speter 	}
3024515Speter     }
3034515Speter }
3044515Speter 
3054515Speter printname( selfp )
3064515Speter     nltype	*selfp;
3074515Speter {
3084515Speter 
3094515Speter     if ( selfp -> name != 0 ) {
3104753Speter 	printf( "%s" , selfp -> name );
3114515Speter #	ifdef DEBUG
3124515Speter 	    if ( debug & DFNDEBUG ) {
3134515Speter 		printf( "{%d} " , selfp -> toporder );
3144515Speter 	    }
3154515Speter #	endif DEBUG
3164515Speter     }
3174842Speter     if ( selfp -> cycleno != 0 ) {
3184842Speter 	printf( "\t<cycle %d>" , selfp -> cycleno );
3194842Speter     }
3204753Speter     if ( selfp -> index != 0 ) {
321*7172Speter 	if ( selfp -> printflag ) {
322*7172Speter 	    printf( " [%d]" , selfp -> index );
323*7172Speter 	} else {
324*7172Speter 	    printf( " (%d)" , selfp -> index );
325*7172Speter 	}
3264753Speter     }
3274515Speter }
3284515Speter 
3294515Speter sortchildren( parentp )
3304515Speter     nltype	*parentp;
3314515Speter {
3324515Speter     arctype	*arcp;
3334515Speter     arctype	*detachedp;
3344515Speter     arctype	sorted;
3354515Speter     arctype	*prevp;
3364515Speter 
3374515Speter 	/*
3384515Speter 	 *	unlink children from parent,
3394515Speter 	 *	then insertion sort back on to sorted's children.
3404515Speter 	 *	    *arcp	the arc you have detached and are inserting.
3414515Speter 	 *	    *detachedp	the rest of the arcs to be sorted.
3424515Speter 	 *	    sorted	arc list onto which you insertion sort.
3434515Speter 	 *	    *prevp	arc before the arc you are comparing.
3444515Speter 	 */
3454515Speter     sorted.arc_childlist = 0;
3464515Speter     for (   arcp = parentp -> children , detachedp = arcp -> arc_childlist ;
3474515Speter 	    arcp ;
3484515Speter 	    arcp = detachedp , detachedp = detachedp -> arc_childlist ) {
3494515Speter 	    /*
3504515Speter 	     *	consider *arcp as disconnected
3514515Speter 	     *	insert it into sorted
3524515Speter 	     */
3534515Speter 	for (   prevp = &sorted ;
3544515Speter 		prevp -> arc_childlist ;
3554515Speter 		prevp = prevp -> arc_childlist ) {
3564515Speter 	    if ( arccmp( arcp , prevp -> arc_childlist ) != LESSTHAN ) {
3574515Speter 		break;
3584515Speter 	    }
3594515Speter 	}
3604515Speter 	arcp -> arc_childlist = prevp -> arc_childlist;
3614515Speter 	prevp -> arc_childlist = arcp;
3624515Speter     }
3634515Speter 	/*
3644515Speter 	 *	reattach sorted children to parent
3654515Speter 	 */
3664515Speter     parentp -> children = sorted.arc_childlist;
3674515Speter }
3684515Speter 
3694515Speter sortparents( childp )
3704515Speter     nltype	*childp;
3714515Speter {
3724515Speter     arctype	*arcp;
3734515Speter     arctype	*detachedp;
3744515Speter     arctype	sorted;
3754515Speter     arctype	*prevp;
3764515Speter 
3774515Speter 	/*
3784515Speter 	 *	unlink parents from child,
3794515Speter 	 *	then insertion sort back on to sorted's parents.
3804515Speter 	 *	    *arcp	the arc you have detached and are inserting.
3814515Speter 	 *	    *detachedp	the rest of the arcs to be sorted.
3824515Speter 	 *	    sorted	arc list onto which you insertion sort.
3834515Speter 	 *	    *prevp	arc before the arc you are comparing.
3844515Speter 	 */
3854515Speter     sorted.arc_parentlist = 0;
3864515Speter     for (   arcp = childp -> parents , detachedp = arcp -> arc_parentlist ;
3874515Speter 	    arcp ;
3884515Speter 	    arcp = detachedp , detachedp = detachedp -> arc_parentlist ) {
3894515Speter 	    /*
3904515Speter 	     *	consider *arcp as disconnected
3914515Speter 	     *	insert it into sorted
3924515Speter 	     */
3934515Speter 	for (   prevp = &sorted ;
3944515Speter 		prevp -> arc_parentlist ;
3954515Speter 		prevp = prevp -> arc_parentlist ) {
3964515Speter 	    if ( arccmp( arcp , prevp -> arc_parentlist ) != GREATERTHAN ) {
3974515Speter 		break;
3984515Speter 	    }
3994515Speter 	}
4004515Speter 	arcp -> arc_parentlist = prevp -> arc_parentlist;
4014515Speter 	prevp -> arc_parentlist = arcp;
4024515Speter     }
4034515Speter 	/*
4044515Speter 	 *	reattach sorted arcs to child
4054515Speter 	 */
4064515Speter     childp -> parents = sorted.arc_parentlist;
4074515Speter }
4084515Speter 
4094515Speter     /*
4104753Speter      *	print a cycle header
4114753Speter      */
4124753Speter printcycle( cyclep )
4134753Speter     nltype	*cyclep;
4144753Speter {
4154753Speter     char	kirkbuffer[ BUFSIZ ];
4164753Speter 
4174753Speter     sprintf( kirkbuffer , "[%d]" , cyclep -> index );
4184753Speter     printf( "%-6.6s %5.1f %7.2f %11.2f %7d" ,
4194753Speter 	    kirkbuffer ,
420*7172Speter 	    100 * ( cyclep -> time + cyclep -> childtime ) / printtime ,
4214753Speter 	    cyclep -> time / HZ ,
4224753Speter 	    cyclep -> childtime / HZ ,
4234753Speter 	    cyclep -> ncall );
4244753Speter     if ( cyclep -> selfcalls != 0 ) {
4254753Speter 	printf( "+%-7d" , cyclep -> selfcalls );
4264753Speter     } else {
4274753Speter 	printf( " %7.7s" , "" );
4284753Speter     }
4294753Speter     printf( " <cycle %d as a whole>\t[%d]\n" ,
4304753Speter 	    cyclep -> cycleno , cyclep -> index );
4314753Speter }
4324753Speter 
4334753Speter     /*
4344753Speter      *	print the members of a cycle
4354753Speter      */
4364753Speter printmembers( cyclep )
4374753Speter     nltype	*cyclep;
4384753Speter {
4394753Speter     nltype	*memberp;
4404753Speter 
4414753Speter     sortmembers( cyclep );
4424753Speter     for ( memberp = cyclep -> cnext ; memberp ; memberp = memberp -> cnext ) {
4434753Speter 	printf( "%6.6s %5.5s %7.2f %11.2f %7d" ,
4444753Speter 		"" , "" , memberp -> time / HZ , memberp -> childtime / HZ ,
4454753Speter 		memberp -> ncall );
4464753Speter 	if ( memberp -> selfcalls != 0 ) {
4474753Speter 	    printf( "+%-7d" , memberp -> selfcalls );
4484753Speter 	} else {
4494753Speter 	    printf( " %7.7s" , "" );
4504753Speter 	}
4514753Speter 	printf( "     " );
4524753Speter 	printname( memberp );
4534753Speter 	printf( "\n" );
4544753Speter     }
4554753Speter }
4564753Speter 
4574753Speter     /*
4584753Speter      *	sort members of a cycle
4594753Speter      */
4604753Speter sortmembers( cyclep )
4614753Speter     nltype	*cyclep;
4624753Speter {
4634753Speter     nltype	*todo;
4644753Speter     nltype	*doing;
4654753Speter     nltype	*prev;
4664753Speter 
4674753Speter 	/*
4684753Speter 	 *	detach cycle members from cyclehead,
4694753Speter 	 *	and insertion sort them back on.
4704753Speter 	 */
4714753Speter     todo = cyclep -> cnext;
4724753Speter     cyclep -> cnext = 0;
4734753Speter     for (   doing = todo , todo = doing -> cnext ;
4744753Speter 	    doing ;
4754753Speter 	    doing = todo , todo = doing -> cnext ) {
4764753Speter 	for ( prev = cyclep ; prev -> cnext ; prev = prev -> cnext ) {
4774753Speter 	    if ( membercmp( doing , prev -> cnext ) == GREATERTHAN ) {
4784753Speter 		break;
4794753Speter 	    }
4804753Speter 	}
4814753Speter 	doing -> cnext = prev -> cnext;
4824753Speter 	prev -> cnext = doing;
4834753Speter     }
4844753Speter }
4854753Speter 
4864753Speter     /*
4874753Speter      *	major sort is on time + childtime,
4884753Speter      *	next is sort on ncalls + selfcalls.
4894753Speter      */
4904842Speter int
4914753Speter membercmp( this , that )
4924753Speter     nltype	*this;
4934753Speter     nltype	*that;
4944753Speter {
4954753Speter     double	thistime = this -> time + this -> childtime;
4964753Speter     double	thattime = that -> time + that -> childtime;
4974753Speter     long	thiscalls = this -> ncall + this -> selfcalls;
4984753Speter     long	thatcalls = that -> ncall + that -> selfcalls;
4994753Speter 
5004753Speter     if ( thistime > thattime ) {
5014753Speter 	return GREATERTHAN;
5024753Speter     }
5034753Speter     if ( thistime < thattime ) {
5044753Speter 	return LESSTHAN;
5054753Speter     }
5064753Speter     if ( thiscalls > thatcalls ) {
5074753Speter 	return GREATERTHAN;
5084753Speter     }
5094753Speter     if ( thiscalls < thatcalls ) {
5104753Speter 	return LESSTHAN;
5114753Speter     }
5124753Speter     return EQUALTO;
5134753Speter }
5144753Speter     /*
5154515Speter      *	compare two arcs to/from the same child/parent.
5164515Speter      *	- if one arc is a self arc, it's least.
5174515Speter      *	- if one arc is within a cycle, it's less than.
5184515Speter      *	- if both arcs are within a cycle, compare arc counts.
5194515Speter      *	- if neither arc is within a cycle, compare with
5204515Speter      *		time + childtime as major key
5214515Speter      *		arc count as minor key
5224515Speter      */
5234515Speter int
5244515Speter arccmp( thisp , thatp )
5254515Speter     arctype	*thisp;
5264515Speter     arctype	*thatp;
5274515Speter {
5284515Speter     nltype	*thisparentp = thisp -> arc_parentp;
5294515Speter     nltype	*thischildp = thisp -> arc_childp;
5304515Speter     nltype	*thatparentp = thatp -> arc_parentp;
5314515Speter     nltype	*thatchildp = thatp -> arc_childp;
5324515Speter     double	thistime;
5334515Speter     double	thattime;
5344515Speter 
5354515Speter #   ifdef DEBUG
5364515Speter 	if ( debug & TIMEDEBUG ) {
5374515Speter 	    printf( "[arccmp] " );
5384515Speter 	    printname( thisparentp );
5394515Speter 	    printf( " calls " );
5404515Speter 	    printname ( thischildp );
5414515Speter 	    printf( " %f + %f %d/%d\n" ,
5424515Speter 		    thisp -> arc_time , thisp -> arc_childtime ,
5434515Speter 		    thisp -> arc_count , thischildp -> ncall );
5444515Speter 	    printf( "[arccmp] " );
5454515Speter 	    printname( thatparentp );
5464515Speter 	    printf( " calls " );
5474515Speter 	    printname( thatchildp );
5484515Speter 	    printf( " %f + %f %d/%d\n" ,
5494515Speter 		    thatp -> arc_time , thatp -> arc_childtime ,
5504515Speter 		    thatp -> arc_count , thatchildp -> ncall );
5514515Speter 	    printf( "\n" );
5524515Speter 	}
5534515Speter #   endif DEBUG
5544515Speter     if ( thisparentp == thischildp ) {
5554515Speter 	    /* this is a self call */
5564515Speter 	return LESSTHAN;
5574515Speter     }
5584515Speter     if ( thatparentp == thatchildp ) {
5594515Speter 	    /* that is a self call */
5604515Speter 	return GREATERTHAN;
5614515Speter     }
5624515Speter     if ( thisparentp -> cycleno != 0 && thischildp -> cycleno != 0 &&
5634515Speter 	thisparentp -> cycleno == thischildp -> cycleno ) {
5644515Speter 	    /* this is a call within a cycle */
5654515Speter 	if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 &&
5664515Speter 	    thatparentp -> cycleno == thatchildp -> cycleno ) {
5674515Speter 		/* that is a call within the cycle, too */
5684515Speter 	    if ( thisp -> arc_count < thatp -> arc_count ) {
5694515Speter 		return LESSTHAN;
5704515Speter 	    }
5714515Speter 	    if ( thisp -> arc_count > thatp -> arc_count ) {
5724515Speter 		return GREATERTHAN;
5734515Speter 	    }
5744515Speter 	    return EQUALTO;
5754515Speter 	} else {
5764515Speter 		/* that isn't a call within the cycle */
5774515Speter 	    return LESSTHAN;
5784515Speter 	}
5794515Speter     } else {
5804515Speter 	    /* this isn't a call within a cycle */
5814515Speter 	if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 &&
5824515Speter 	    thatparentp -> cycleno == thatchildp -> cycleno ) {
5834515Speter 		/* that is a call within a cycle */
5844515Speter 	    return GREATERTHAN;
5854515Speter 	} else {
5864515Speter 		/* neither is a call within a cycle */
5874515Speter 	    thistime = thisp -> arc_time + thisp -> arc_childtime;
5884515Speter 	    thattime = thatp -> arc_time + thatp -> arc_childtime;
5894515Speter 	    if ( thistime < thattime )
5904515Speter 		return LESSTHAN;
5914515Speter 	    if ( thistime > thattime )
5924515Speter 		return GREATERTHAN;
5934515Speter 	    if ( thisp -> arc_count < thatp -> arc_count )
5944515Speter 		return LESSTHAN;
5954515Speter 	    if ( thisp -> arc_count > thatp -> arc_count )
5964515Speter 		return GREATERTHAN;
5974515Speter 	    return EQUALTO;
5984515Speter 	}
5994515Speter     }
6004515Speter }
6014854Speter 
6024854Speter printblurb( blurbname )
6034854Speter     char	*blurbname;
6044854Speter {
6054854Speter     char	pathname[ BUFSIZ ];
6064854Speter     FILE	*blurbfile;
6074854Speter     int		input;
6084854Speter 
6094854Speter     sprintf( pathname , "%s%s" , BLURBLIB , blurbname );
6104854Speter     blurbfile = fopen( pathname , "r" );
6114854Speter     if ( blurbfile == NULL ) {
6124854Speter 	perror( pathname );
6134854Speter 	return;
6144854Speter     }
6154854Speter     while ( ( input = getc( blurbfile ) ) != EOF ) {
6164854Speter 	putchar( input );
6174854Speter     }
6184854Speter     fclose( blurbfile );
6194854Speter }
620